Skip to content

Commit 5b9729b

Browse files
committed
Add doc comments for detal and Fix example code
1 parent e82cb54 commit 5b9729b

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, RclrsError> {
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: "/"
@@ -87,67 +87,6 @@ impl Node {
8787
NodeBuilder::new(node_name, context).build()
8888
}
8989

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

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

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

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

0 commit comments

Comments
 (0)