@@ -8,10 +8,11 @@ mod subscription;
8
8
pub use self :: publisher:: * ;
9
9
pub use self :: subscription:: * ;
10
10
11
- use std:: ffi:: CString ;
11
+ use std:: ffi:: { CStr , CString } ;
12
12
use std:: sync:: { Arc , Weak } ;
13
13
use std:: vec:: Vec ;
14
14
15
+ use libc:: c_char;
15
16
use parking_lot:: Mutex ;
16
17
17
18
use rosidl_runtime_rs:: Message ;
@@ -43,16 +44,16 @@ impl Node {
43
44
/// Creates a new node in the empty namespace.
44
45
#[ allow( clippy:: new_ret_no_self) ]
45
46
pub fn new ( node_name : & str , context : & Context ) -> Result < Node , RclReturnCode > {
46
- Self :: new_with_namespace ( node_name , "" , context)
47
+ Self :: new_with_namespace ( "" , node_name , context)
47
48
}
48
49
49
50
/// Creates a new node in a namespace.
50
51
///
51
52
/// A namespace without a leading forward slash is automatically changed to have a leading
52
53
/// forward slash.
53
54
pub fn new_with_namespace (
54
- node_name : & str ,
55
55
node_ns : & str ,
56
+ node_name : & str ,
56
57
context : & Context ,
57
58
) -> Result < Node , RclReturnCode > {
58
59
let raw_node_name = CString :: new ( node_name) . unwrap ( ) ;
@@ -88,6 +89,87 @@ impl Node {
88
89
} )
89
90
}
90
91
92
+ /// Returns the name of the node.
93
+ ///
94
+ /// This returns the name after remapping, so it is not necessarily the same as the name that
95
+ /// was used when creating the node.
96
+ ///
97
+ /// # Example
98
+ /// ```
99
+ /// # use rclrs::{Context, RclReturnCode};
100
+ /// // Without remapping
101
+ /// let context = Context::new([])?;
102
+ /// let node = context.create_node("my_node")?;
103
+ /// assert_eq!(node.name(), String::from("my_node"));
104
+ /// // With remapping
105
+ /// let remapping = ["--ros-args", "-r", "__node:=your_node"].map(String::from);
106
+ /// let context_r = Context::new(remapping)?;
107
+ /// let node_r = context_r.create_node("my_node")?;
108
+ /// assert_eq!(node_r.name(), String::from("your_node"));
109
+ /// # Ok::<(), RclReturnCode>(())
110
+ /// ```
111
+ pub fn name ( & self ) -> String {
112
+ self . get_string ( rcl_node_get_name)
113
+ }
114
+
115
+ /// Returns the namespace of the node.
116
+ ///
117
+ /// This returns the namespace after remapping, so it is not necessarily the same as the
118
+ /// namespace that was used when creating the node.
119
+ ///
120
+ /// # Example
121
+ /// ```
122
+ /// # use rclrs::{Context, RclReturnCode};
123
+ /// // Without remapping
124
+ /// let context = Context::new([])?;
125
+ /// let node = context.create_node_with_namespace("/my/namespace", "my_node")?;
126
+ /// assert_eq!(node.namespace(), String::from("/my/namespace"));
127
+ /// // With remapping
128
+ /// let remapping = ["--ros-args", "-r", "__ns:=/your_namespace"].map(String::from);
129
+ /// let context_r = Context::new(remapping)?;
130
+ /// let node_r = context_r.create_node("my_node")?;
131
+ /// assert_eq!(node_r.namespace(), String::from("/your_namespace"));
132
+ /// # Ok::<(), RclReturnCode>(())
133
+ /// ```
134
+ pub fn namespace ( & self ) -> String {
135
+ self . get_string ( rcl_node_get_namespace)
136
+ }
137
+
138
+ /// Returns the fully qualified name of the node.
139
+ ///
140
+ /// The fully qualified name of the node is the node namespace combined with the node name.
141
+ /// It is subject to the remappings shown in [`Node::name`] and [`Node::namespace`].
142
+ ///
143
+ /// # Example
144
+ /// ```
145
+ /// # use rclrs::{Context, RclReturnCode};
146
+ /// let context = Context::new([])?;
147
+ /// let node = context.create_node_with_namespace("/my/namespace", "my_node")?;
148
+ /// assert_eq!(node.fully_qualified_name(), String::from("/my/namespace/my_node"));
149
+ /// # Ok::<(), RclReturnCode>(())
150
+ /// ```
151
+ pub fn fully_qualified_name ( & self ) -> String {
152
+ self . get_string ( rcl_node_get_fully_qualified_name)
153
+ }
154
+
155
+ fn get_string (
156
+ & self ,
157
+ getter : unsafe extern "C" fn ( * const rcl_node_t ) -> * const c_char ,
158
+ ) -> String {
159
+ let char_ptr = unsafe {
160
+ // SAFETY: The node handle is valid.
161
+ getter ( & * self . handle . lock ( ) )
162
+ } ;
163
+ debug_assert ! ( !char_ptr. is_null( ) ) ;
164
+ let cstr = unsafe {
165
+ // SAFETY: The returned CStr is immediately converted to an owned string,
166
+ // so the lifetime is no issue. The ptr is valid as per the documentation
167
+ // of rcl_node_get_name.
168
+ CStr :: from_ptr ( char_ptr)
169
+ } ;
170
+ cstr. to_string_lossy ( ) . into_owned ( )
171
+ }
172
+
91
173
/// Creates a [`Publisher`][1].
92
174
///
93
175
/// [1]: crate::Publisher
0 commit comments