@@ -110,7 +110,7 @@ pub struct StringExceedsBoundsError {
110
110
111
111
// There is a lot of redundancy between String and WString, which this macro aims to reduce.
112
112
macro_rules! string_impl {
113
- ( $string: ty, $char_type: ty, $string_conversion_func: ident, $init: ident, $fini: ident, $assignn: ident, $sequence_init: ident, $sequence_fini: ident, $sequence_copy: ident) => {
113
+ ( $string: ty, $char_type: ty, $unsigned_char_type : ty , $ string_conversion_func: ident, $init: ident, $fini: ident, $assignn: ident, $sequence_init: ident, $sequence_fini: ident, $sequence_copy: ident) => {
114
114
#[ link( name = "rosidl_runtime_c" ) ]
115
115
extern "C" {
116
116
fn $init( s: * mut $string) -> bool ;
@@ -159,21 +159,26 @@ macro_rules! string_impl {
159
159
fn deref( & self ) -> & Self :: Target {
160
160
// SAFETY: self.data points to self.size consecutive, initialized elements and
161
161
// isn't modified externally.
162
- unsafe { std:: slice:: from_raw_parts( self . data as * const $char_type , self . size) }
162
+ unsafe { std:: slice:: from_raw_parts( self . data, self . size) }
163
163
}
164
164
}
165
165
166
166
impl DerefMut for $string {
167
167
fn deref_mut( & mut self ) -> & mut Self :: Target {
168
168
// SAFETY: self.data points to self.size consecutive, initialized elements and
169
169
// isn't modified externally.
170
- unsafe { std:: slice:: from_raw_parts_mut( self . data as * mut $char_type , self . size) }
170
+ unsafe { std:: slice:: from_raw_parts_mut( self . data, self . size) }
171
171
}
172
172
}
173
173
174
174
impl Display for $string {
175
175
fn fmt( & self , f: & mut fmt:: Formatter <' _>) -> Result <( ) , fmt:: Error > {
176
- let converted = std:: string:: String :: $string_conversion_func( self . deref( ) ) ;
176
+ // SAFETY: Same as deref, but with an additional cast to the unsigned type.
177
+ // See also https://users.rust-lang.org/t/how-to-convert-i8-to-u8/16308/11
178
+ let u8_slice = unsafe {
179
+ std:: slice:: from_raw_parts( self . data as * mut $unsigned_char_type, self . size)
180
+ } ;
181
+ let converted = std:: string:: String :: $string_conversion_func( u8_slice) ;
177
182
Display :: fmt( & converted, f)
178
183
}
179
184
}
@@ -238,6 +243,7 @@ macro_rules! string_impl {
238
243
239
244
string_impl ! (
240
245
String ,
246
+ libc:: c_char,
241
247
u8 ,
242
248
from_utf8_lossy,
243
249
rosidl_runtime_c__String__init,
@@ -250,6 +256,7 @@ string_impl!(
250
256
string_impl ! (
251
257
WString ,
252
258
libc:: c_ushort,
259
+ u16 ,
253
260
from_utf16_lossy,
254
261
rosidl_runtime_c__U16String__init,
255
262
rosidl_runtime_c__U16String__fini,
@@ -321,7 +328,7 @@ impl<const N: usize> Debug for BoundedString<N> {
321
328
}
322
329
323
330
impl < const N : usize > Deref for BoundedString < N > {
324
- type Target = [ u8 ] ;
331
+ type Target = [ libc :: c_char ] ;
325
332
fn deref ( & self ) -> & Self :: Target {
326
333
self . inner . deref ( )
327
334
}
0 commit comments