Skip to content

Commit b95061d

Browse files
committed
Add doc comments for detal and Fix example code
1 parent fc04e9a commit b95061d

File tree

2 files changed

+113
-90
lines changed

2 files changed

+113
-90
lines changed

rclrs/src/context.rs

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -118,31 +118,6 @@ impl Context {
118118
NodeBuilder::new(node_name, self).build()
119119
}
120120

121-
/// Creates a new node in a namespace.
122-
///
123-
/// Convenience function equivalent to [`Node::new_with_namespace`][1].
124-
/// Please see that function's documentation.
125-
///
126-
/// [1]: crate::Node::new_with_namespace
127-
///
128-
/// # Example
129-
/// ```
130-
/// # use rclrs::{Context, RclReturnCode};
131-
/// let ctx = Context::new([])?;
132-
/// let node = ctx.create_node_with_namespace("/my/nested/namespace", "my_node");
133-
/// assert!(node.is_ok());
134-
/// # Ok::<(), RclReturnCode>(())
135-
/// ```
136-
pub fn create_node_with_namespace(
137-
&self,
138-
node_namespace: &str,
139-
node_name: &str,
140-
) -> Result<Node, RclReturnCode> {
141-
NodeBuilder::new(node_name, self)
142-
.namespace(node_namespace)
143-
.build()
144-
}
145-
146121
/// Creates a [`NodeBuilder`][1].
147122
///
148123
/// Convenience function equivalent to [`NodeBuilder::new`][2].

rclrs/src/node/mod.rs

Lines changed: 113 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ pub struct Node {
4242

4343
/// A builder for node instantiation.
4444
///
45-
/// The default values for each field are
45+
/// default value in each fields are
4646
/// - context: user defined
4747
/// - name: user defined
4848
/// - namespace: "/"
@@ -86,67 +86,6 @@ impl Node {
8686
NodeBuilder::new(node_name, context).build()
8787
}
8888

89-
/// Creates a new node in a namespace.
90-
///
91-
/// A namespace without a leading forward slash is automatically changed to have a leading
92-
/// forward slash.
93-
///
94-
/// # Naming
95-
/// The node namespace will be prefixed to the node name itself to form the *fully qualified
96-
/// node name*. This is the name that is shown e.g. in `ros2 node list`.
97-
/// Similarly, the node namespace will be prefixed to all names of topics and services
98-
/// created from this node.
99-
///
100-
/// By convention, a node name with a leading underscore marks the node as hidden.
101-
///
102-
/// It's a good idea for node names in the same executable to be unique.
103-
///
104-
/// ## Remapping
105-
/// The namespace and name given here can be overriden through the command line.
106-
/// In that sense, the parameters to this functions are only the _default_ namespace and name.
107-
/// See also the [official tutorial][1] on the command line arguments for ROS nodes, and the
108-
/// [`Node::namespace()`] and [`Node::name()`] functions for examples.
109-
///
110-
/// ## Rules for valid names
111-
/// The node namespace needs to fulfill the criteria of
112-
/// [`rmw_validate_namespace()`][2], otherwise an error will be returned.
113-
/// Likewise, the node name needs to fulfill the criteria of [`rmw_validate_node_name()`][3].
114-
///
115-
/// # Example
116-
/// ```
117-
/// # use rclrs::{Context, Node, RclReturnCode, NodeErrorCode};
118-
/// let ctx = Context::new([])?;
119-
/// // This is a valid namespace and name
120-
/// assert!(Node::new_with_namespace("/my/nested/namespace", "my_node", &ctx).is_ok());
121-
/// // This name contains invalid characters, although the empty namespace is valid
122-
/// assert_eq!(
123-
/// Node::new_with_namespace("", "röböt", &ctx),
124-
/// Err(RclReturnCode::NodeError(NodeErrorCode::NodeInvalidName))
125-
/// );
126-
/// // This namespace starts with a number
127-
/// assert_eq!(
128-
/// Node::new_with_namespace("/123/4", "my_node", &ctx),
129-
/// Err(RclReturnCode::NodeError(NodeErrorCode::NodeInvalidNamespace))
130-
/// );
131-
/// # Ok::<(), RclReturnCode>(())
132-
/// ```
133-
///
134-
/// # Panics
135-
/// When the node namespace or node name contain interior null bytes.
136-
///
137-
/// [1]: https://docs.ros.org/en/rolling/How-To-Guides/Node-arguments.html
138-
/// [2]: https://docs.ros2.org/latest/api/rmw/validate__namespace_8h.html
139-
/// [3]: https://docs.ros2.org/latest/api/rmw/validate__node__name_8h.html
140-
pub fn new_with_namespace(
141-
node_ns: &str,
142-
node_name: &str,
143-
context: &Context,
144-
) -> Result<Node, RclReturnCode> {
145-
NodeBuilder::new(node_name, context)
146-
.namespace(node_ns)
147-
.build()
148-
}
149-
15089
/// Returns the name of the node.
15190
///
15291
/// This returns the name after remapping, so it is not necessarily the same as the name that
@@ -180,7 +119,10 @@ impl Node {
180119
/// # use rclrs::{Context, RclReturnCode};
181120
/// // Without remapping
182121
/// let context = Context::new([])?;
183-
/// let node = context.create_node_with_namespace("/my/namespace", "my_node")?;
122+
/// let node = context
123+
/// .create_node_builder("my_node")
124+
/// .namespace("/my/namespace")
125+
/// .build()?;
184126
/// assert_eq!(node.namespace(), "/my/namespace");
185127
/// // With remapping
186128
/// let remapping = ["--ros-args", "-r", "__ns:=/your_namespace"].map(String::from);
@@ -202,7 +144,10 @@ impl Node {
202144
/// ```
203145
/// # use rclrs::{Context, RclReturnCode};
204146
/// let context = Context::new([])?;
205-
/// let node = context.create_node_with_namespace("/my/namespace", "my_node")?;
147+
/// let node = context
148+
/// .create_node_builder("my_node")
149+
/// .namespace("/my/namespace")
150+
/// .build()?;
206151
/// assert_eq!(node.fully_qualified_name(), "/my/namespace/my_node");
207152
/// # Ok::<(), RclReturnCode>(())
208153
/// ```
@@ -308,6 +253,45 @@ impl Node {
308253

309254
impl NodeBuilder {
310255
/// Creates new builder for Node.
256+
///
257+
/// # Naming rule for node name
258+
/// The node name must follow below rules.
259+
/// - must not be an empty.
260+
/// - must only contain alphanumeric characters and underscores(a-z|A-Z|0-9|_).
261+
/// - must not start a number.
262+
/// The validation performs at [`NodeBuilder::build()`][1], and does not perform in this function.
263+
/// For more details, see [`rmw_validate_nodename`][2].
264+
///
265+
/// By convention, a node name with a leading underscore marks the node as hidden.
266+
/// Fully qualified node names(namespace + name) should be unique in the same executable to be unique.
267+
///
268+
/// # Remapping
269+
/// The namespace and name given here can be overriden through the command line.
270+
/// In that sense, the parameters to this constructor and
271+
/// [`NodeBuilder::namespace()`][3] are only the _default_ namespace and name.
272+
/// See also the [official tutorial][4] on the command line arguments for ROS nodes, and
273+
/// the [`Node::namespace()`] and [`Node::name()`] functions for examples.
274+
///
275+
/// # Example
276+
/// ```
277+
/// # use rclrs::{Context, Node, NodeBuilder, RclReturnCode, NodeErrorCode};
278+
/// let context = Context::new([])?;
279+
/// let builder = NodeBuilder::new("foo_node", &context);
280+
/// let node = builder.build()?;
281+
/// assert_eq!(node.name(), "foo_node");
282+
/// // invalid node name
283+
/// let builder = NodeBuilder::new("123abc", &context);
284+
/// assert_eq!(
285+
/// builder.build(),
286+
/// Err(RclReturnCode::NodeError(NodeErrorCode::NodeInvalidName))
287+
/// );
288+
/// # Ok::<(), RclReturnCode>(())
289+
/// ```
290+
///
291+
/// [1]: NodeBuilder::build
292+
/// [2]: https://docs.ros2.org/bouncy/api/rmw/validate__node__name_8h.html
293+
/// [3]: NodeBuilder::namespace
294+
/// [4]: https://docs.ros.org/en/rolling/How-To-Guides/Node-arguments.html
311295
pub fn new(name: &str, context: &Context) -> NodeBuilder {
312296
NodeBuilder {
313297
context: context.handle.clone(),
@@ -317,12 +301,76 @@ impl NodeBuilder {
317301
}
318302

319303
/// Sets node namespace.
304+
///
305+
/// # Naming rule for node namespace
306+
/// The node namespace naming rules is based on rules defined for a [topic][1].
307+
/// namespace naming rules are below.
308+
/// - must not be empty(Note that empty string is allowed in this method. Empty string is replaced to "/".)
309+
/// - may contain alphanumric characters, underscores, or forward slashes(a-z|A-Z|0-9|_|/)
310+
/// - must no start with numeric character(0-9)
311+
/// - must not contain repeated forward slashes(/)
312+
/// - must not contain repeated underscores(_)
313+
///
314+
/// In fully qualified name, Namespace will be prefixed to node name.
315+
/// e.g. `/foo/bar/node_name` when namespace is `/foo/bar` and node name is `node_name`
316+
///
317+
/// Note that namespace naming validation is delayed to [`NodeBuilder::build()`][2].
318+
/// For more details, see [`rmw_validate_namespace()`][3].
319+
///
320+
/// [1]: http://design.ros2.org/articles/topic_and_service_names.html
321+
/// [2]: NodeBuilder::build
322+
/// [3]: https://docs.ros2.org/bouncy/api/rmw/validate__namespace_8h.html
323+
///
324+
/// # Example
325+
/// ```
326+
/// # use rclrs::{Context, Node, NodeBuilder, RclReturnCode, NodeErrorCode};
327+
/// let context = Context::new([])?;
328+
/// let builder = NodeBuilder::new("node_name", &context);
329+
/// let node = builder.namespace("/foo/bar").build()?;
330+
/// assert_eq!(node.fully_qualified_name(), "/foo/bar/node_name");
331+
/// // invalid namespace
332+
/// let builder = NodeBuilder::new("node_name", &context);
333+
/// assert_eq!(
334+
/// builder.namespace("123abc").build(),
335+
/// Err(RclReturnCode::NodeError(NodeErrorCode::NodeInvalidNamespace))
336+
/// );
337+
/// # Ok::<(), RclReturnCode>(())
338+
/// ```
320339
pub fn namespace(mut self, namespace: &str) -> Self {
321340
self.namespace = namespace.to_string();
322341
self
323342
}
324343

325-
/// Builds node instance
344+
/// Builds node instance
345+
///
346+
/// Node name and namespace validation is performed in this method.
347+
/// If invalid name and/or namespace are specified to builder,
348+
/// this method will return RclReturnCode as error.
349+
///
350+
/// # Example
351+
/// ```
352+
/// # use rclrs::{Context, Node, NodeBuilder, RclReturnCode, NodeErrorCode};
353+
/// let context = Context::new([])?;
354+
///
355+
/// let builder = NodeBuilder::new("node_name", &context);
356+
/// let result = builder.namespace("/foo/bar").build();
357+
/// assert!(result.is_ok());
358+
/// // invalid node name
359+
/// let builder = NodeBuilder::new("123abc", &context);
360+
/// let result = builder.namespace("/foo/bar").build();
361+
/// assert_eq!(
362+
/// result,
363+
/// Err(RclReturnCode::NodeError(NodeErrorCode::NodeInvalidName))
364+
/// );
365+
/// // invalid namespace
366+
/// let builder = NodeBuilder::new("node_name", &context);
367+
/// let result = builder.namespace("123abc").build();
368+
/// assert_eq!(
369+
/// result,
370+
/// Err(RclReturnCode::NodeError(NodeErrorCode::NodeInvalidNamespace))
371+
/// );
372+
/// # Ok::<(), RclReturnCode>(())
373+
/// ```
326374
pub fn build(&self) -> Result<Node, RclReturnCode> {
327375
let node_name = CString::new(self.name.as_str()).unwrap();
328376
let node_namespace = CString::new(self.namespace.as_str()).unwrap();

0 commit comments

Comments
 (0)