@@ -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
+ /// ```
100
+ /// # use rclrs::{Context, RclReturnCode};
101
+ /// // Without remapping
102
+ /// let context = Context::new([])?;
103
+ /// let node = context.create_node("my_node")?;
104
+ /// assert_eq!(node.name(), String::from("my_node"));
105
+ /// // With remapping
106
+ /// let remapping = ["--ros-args", "-r", "__node:=your_node"].map(String::from);
107
+ /// let context_r = Context::new(remapping)?;
108
+ /// let node_r = context_r.create_node("my_node")?;
109
+ /// assert_eq!(node_r.name(), String::from("your_node"));
110
+ /// # Ok::<(), RclReturnCode>(())
111
+ /// ```
112
+ pub fn name ( & self ) -> String {
113
+ self . get_string ( rcl_node_get_name)
114
+ }
115
+
116
+ /// Returns the namespace of the node.
117
+ ///
118
+ /// This returns the namespace after remapping, so it is not necessarily the same as the
119
+ /// namespace that was used when creating the node.
120
+ ///
121
+ /// # Example
122
+ ///
123
+ /// ```
124
+ /// # use rclrs::{Context, RclReturnCode};
125
+ /// // Without remapping
126
+ /// let context = Context::new([])?;
127
+ /// let node = context.create_node_with_namespace("/my/namespace", "my_node")?;
128
+ /// assert_eq!(node.namespace(), String::from("/my/namespace"));
129
+ /// // With remapping
130
+ /// let remapping = ["--ros-args", "-r", "__ns:=/your_namespace"].map(String::from);
131
+ /// let context_r = Context::new(remapping)?;
132
+ /// let node_r = context_r.create_node("my_node")?;
133
+ /// assert_eq!(node_r.namespace(), String::from("/your_namespace"));
134
+ /// # Ok::<(), RclReturnCode>(())
135
+ /// ```
136
+ pub fn namespace ( & self ) -> String {
137
+ self . get_string ( rcl_node_get_namespace)
138
+ }
139
+
140
+ /// Returns the fully qualified name of the node.
141
+ ///
142
+ /// The fully qualified name of the node is the node namespace combined with the node name.
143
+ /// It is subject to the remappings shown in [`Node::name`] and [`Node::namespace`].
144
+ ///
145
+ /// # Example
146
+ ///
147
+ /// ```
148
+ /// # use rclrs::{Context, RclReturnCode};
149
+ /// let context = Context::new([])?;
150
+ /// let node = context.create_node_with_namespace("/my/namespace", "my_node")?;
151
+ /// assert_eq!(node.fully_qualified_name(), String::from("/my/namespace/my_node"));
152
+ /// # Ok::<(), RclReturnCode>(())
153
+ /// ```
154
+ pub fn fully_qualified_name ( & self ) -> String {
155
+ self . get_string ( rcl_node_get_fully_qualified_name)
156
+ }
157
+
158
+ fn get_string ( & self , getter : unsafe extern "C" fn ( * const rcl_node_t ) -> * const c_char ) -> 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