1
- use crate :: error:: { RclReturnCode , ToResult } ;
2
- use crate :: qos:: QoSProfile ;
3
- use crate :: rcl_bindings:: * ;
4
- use crate :: Context ;
5
-
6
1
mod publisher;
7
2
mod subscription;
8
3
pub use self :: publisher:: * ;
9
4
pub use self :: subscription:: * ;
10
5
6
+ use crate :: rcl_bindings:: * ;
7
+ use crate :: { Context , QoSProfile , RclReturnCode , ToResult } ;
11
8
use std:: ffi:: { CStr , CString } ;
9
+
10
+ use std:: cmp:: PartialEq ;
11
+ use std:: fmt;
12
12
use std:: sync:: { Arc , Weak } ;
13
13
use std:: vec:: Vec ;
14
14
@@ -62,9 +62,26 @@ pub struct NodeBuilder<'a> {
62
62
pub ( self ) namespace : & ' a str ,
63
63
}
64
64
65
+ impl Eq for Node { }
66
+
67
+ impl PartialEq for Node {
68
+ fn eq ( & self , other : & Self ) -> bool {
69
+ Arc :: ptr_eq ( & self . handle , & other. handle )
70
+ }
71
+ }
72
+
73
+ impl fmt:: Debug for Node {
74
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> Result < ( ) , fmt:: Error > {
75
+ f. debug_struct ( "Node" )
76
+ . field ( "fully_qualified_name" , & self . fully_qualified_name ( ) )
77
+ . finish ( )
78
+ }
79
+ }
80
+
65
81
impl Node {
66
82
/// Creates a new node in the empty namespace.
67
- #[ deprecated( since = "0.2.0" , note = "please use `NodeBuilder` instead" ) ]
83
+ ///
84
+ /// See [`Node::new_with_namespace`] for documentation.
68
85
#[ allow( clippy:: new_ret_no_self) ]
69
86
pub fn new ( node_name : & str , context : & Context ) -> Result < Node , RclReturnCode > {
70
87
NodeBuilder :: new ( node_name, context) . build ( )
@@ -74,7 +91,53 @@ impl Node {
74
91
///
75
92
/// A namespace without a leading forward slash is automatically changed to have a leading
76
93
/// forward slash.
77
- #[ deprecated( since = "0.2.0" , note = "please use `NodeBuilder` instead" ) ]
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
78
141
pub fn new_with_namespace (
79
142
node_ns : & str ,
80
143
node_name : & str ,
@@ -96,12 +159,12 @@ impl Node {
96
159
/// // Without remapping
97
160
/// let context = Context::new([])?;
98
161
/// let node = context.create_node("my_node")?;
99
- /// assert_eq!(node.name(), String::from( "my_node") );
162
+ /// assert_eq!(node.name(), "my_node");
100
163
/// // With remapping
101
164
/// let remapping = ["--ros-args", "-r", "__node:=your_node"].map(String::from);
102
165
/// let context_r = Context::new(remapping)?;
103
166
/// let node_r = context_r.create_node("my_node")?;
104
- /// assert_eq!(node_r.name(), String::from( "your_node") );
167
+ /// assert_eq!(node_r.name(), "your_node");
105
168
/// # Ok::<(), RclReturnCode>(())
106
169
/// ```
107
170
pub fn name ( & self ) -> String {
@@ -119,12 +182,12 @@ impl Node {
119
182
/// // Without remapping
120
183
/// let context = Context::new([])?;
121
184
/// let node = context.create_node_with_namespace("/my/namespace", "my_node")?;
122
- /// assert_eq!(node.namespace(), String::from( "/my/namespace") );
185
+ /// assert_eq!(node.namespace(), "/my/namespace");
123
186
/// // With remapping
124
187
/// let remapping = ["--ros-args", "-r", "__ns:=/your_namespace"].map(String::from);
125
188
/// let context_r = Context::new(remapping)?;
126
189
/// let node_r = context_r.create_node("my_node")?;
127
- /// assert_eq!(node_r.namespace(), String::from( "/your_namespace") );
190
+ /// assert_eq!(node_r.namespace(), "/your_namespace");
128
191
/// # Ok::<(), RclReturnCode>(())
129
192
/// ```
130
193
pub fn namespace ( & self ) -> String {
@@ -141,13 +204,14 @@ impl Node {
141
204
/// # use rclrs::{Context, RclReturnCode};
142
205
/// let context = Context::new([])?;
143
206
/// let node = context.create_node_with_namespace("/my/namespace", "my_node")?;
144
- /// assert_eq!(node.fully_qualified_name(), String::from( "/my/namespace/my_node") );
207
+ /// assert_eq!(node.fully_qualified_name(), "/my/namespace/my_node");
145
208
/// # Ok::<(), RclReturnCode>(())
146
209
/// ```
147
210
pub fn fully_qualified_name ( & self ) -> String {
148
211
self . get_string ( rcl_node_get_fully_qualified_name)
149
212
}
150
213
214
+ // Helper for name(), namespace(), fully_qualified_name()
151
215
fn get_string (
152
216
& self ,
153
217
getter : unsafe extern "C" fn ( * const rcl_node_t ) -> * const c_char ,
0 commit comments