r2r_rcl/
lib.rs

1#![allow(non_upper_case_globals)]
2#![allow(non_camel_case_types)]
3#![allow(non_snake_case)]
4#![allow(dead_code)]
5// Silence "`extern` fn uses type `u128`, which is not FFI-safe"
6// As of rustc 1.78, this has been fixed.
7// It could be good to still warn if building with an older rust version.
8#![allow(improper_ctypes)]
9#![allow(improper_ctypes_definitions)]
10include!(concat!(env!("OUT_DIR"), "/rcl_bindings.rs"));
11
12use std::ffi::{CStr, CString};
13
14impl Default for rmw_message_info_t {
15    fn default() -> Self {
16        unsafe { rmw_get_zero_initialized_message_info() }
17    }
18}
19
20// special treatment to convert to/from rust strings.
21// ros strings are owned by ros, assignment is a copy
22impl rosidl_runtime_c__String {
23    pub fn to_str(&self) -> &str {
24        let s = unsafe { CStr::from_ptr(self.data) };
25        s.to_str().unwrap_or("")
26    }
27
28    pub fn assign(&mut self, other: &str) {
29        let q = CString::new(other).unwrap();
30        unsafe {
31            rosidl_runtime_c__String__assign(self as *mut _, q.as_ptr());
32        }
33    }
34}
35
36use widestring::U16String;
37impl rosidl_runtime_c__U16String {
38    pub fn to_str(&self) -> String {
39        let s = unsafe { U16String::from_ptr(self.data, self.size) };
40        // U16Str = U16String::from_ptr(buffer, strlen as usize);
41        // let s = unsafe { CStr::from_ptr(self.data as *mut i8) };
42        //s.to_str().unwrap_or("")
43        s.to_string_lossy()
44    }
45
46    pub fn assign(&mut self, other: &str) {
47        let wstr = U16String::from_str(other);
48        let to_send_ptr = wstr.as_ptr() as *const uint_least16_t;
49        unsafe {
50            rosidl_runtime_c__U16String__assignn(self as *mut _, to_send_ptr, wstr.len());
51        }
52    }
53}
54
55impl rosidl_runtime_c__U16String__Sequence {
56    pub fn update(&mut self, values: &[String]) {
57        unsafe {
58            rosidl_runtime_c__U16String__Sequence__fini(self as *mut _);
59        }
60        unsafe {
61            rosidl_runtime_c__U16String__Sequence__init(self as *mut _, values.len());
62        }
63        if self.data != std::ptr::null_mut() {
64            let strs = unsafe { std::slice::from_raw_parts_mut(self.data, values.len()) };
65            for (target, source) in strs.iter_mut().zip(values) {
66                target.assign(source);
67            }
68        }
69    }
70
71    pub fn to_vec(&self) -> Vec<String> {
72        if self.data == std::ptr::null_mut() {
73            return Vec::new();
74        }
75        let mut target = Vec::with_capacity(self.size);
76        let strs = unsafe { std::slice::from_raw_parts(self.data, self.size) };
77        for s in strs {
78            target.push(s.to_str().to_owned());
79        }
80        target
81    }
82}
83
84impl rosidl_runtime_c__String__Sequence {
85    pub fn update(&mut self, values: &[String]) {
86        unsafe {
87            rosidl_runtime_c__String__Sequence__fini(self as *mut _);
88        }
89        unsafe {
90            rosidl_runtime_c__String__Sequence__init(self as *mut _, values.len());
91        }
92        if self.data != std::ptr::null_mut() {
93            let strs = unsafe { std::slice::from_raw_parts_mut(self.data, values.len()) };
94            for (target, source) in strs.iter_mut().zip(values) {
95                target.assign(source);
96            }
97        }
98    }
99
100    pub fn to_vec(&self) -> Vec<String> {
101        if self.data == std::ptr::null_mut() {
102            return Vec::new();
103        }
104        let mut target = Vec::with_capacity(self.size);
105        let strs = unsafe { std::slice::from_raw_parts(self.data, self.size) };
106        for s in strs {
107            target.push(s.to_str().to_owned());
108        }
109        target
110    }
111}
112
113// conversions from/to vectors of built in types
114
115macro_rules! primitive_sequence {
116    ($ctype:ident, $element_type:ident) => {
117        paste::item! {
118            impl [<$ctype __Sequence>] {
119                pub fn update(&mut self, values: &[$element_type]) {
120                    unsafe { [<$ctype __Sequence__fini>] (self as *mut _); }
121                    unsafe { [<$ctype __Sequence__init>] (self as *mut _, values.len()); }
122                    if self.data != std::ptr::null_mut() {
123                        unsafe { std::ptr::copy_nonoverlapping(values.as_ptr(), self.data, values.len()); }
124                    }
125                }
126
127                pub fn to_vec(&self) -> Vec<$element_type> {
128                    if self.data == std::ptr::null_mut() {
129                        return Vec::new();
130                    }
131                    let mut target = Vec::with_capacity(self.size);
132                    unsafe {
133                        std::ptr::copy_nonoverlapping(self.data, target.as_mut_ptr(), self.size);
134                        target.set_len(self.size);
135                    }
136                    target
137                }
138            }
139        }
140    };
141}
142
143primitive_sequence!(rosidl_runtime_c__float32, f32);
144primitive_sequence!(rosidl_runtime_c__float64, f64);
145
146#[cfg(any(
147    all(target_os = "macos", target_arch = "aarch64"),
148    target_arch = "arm",
149    target_os = "windows"
150))]
151primitive_sequence!(rosidl_runtime_c__long_double, f64);
152
153#[cfg(not(any(
154    all(target_os = "macos", target_arch = "aarch64"),
155    target_arch = "arm",
156    target_os = "windows"
157)))]
158primitive_sequence!(rosidl_runtime_c__long_double, u128);
159
160primitive_sequence!(rosidl_runtime_c__char, i8);
161primitive_sequence!(rosidl_runtime_c__wchar, u16);
162primitive_sequence!(rosidl_runtime_c__boolean, bool);
163primitive_sequence!(rosidl_runtime_c__octet, u8);
164primitive_sequence!(rosidl_runtime_c__uint8, u8);
165primitive_sequence!(rosidl_runtime_c__int8, i8);
166primitive_sequence!(rosidl_runtime_c__uint16, u16);
167primitive_sequence!(rosidl_runtime_c__int16, i16);
168primitive_sequence!(rosidl_runtime_c__uint32, u32);
169primitive_sequence!(rosidl_runtime_c__int32, i32);
170primitive_sequence!(rosidl_runtime_c__uint64, u64);
171primitive_sequence!(rosidl_runtime_c__int64, i64);