@@ -65,7 +65,23 @@ fn parse_schema_name(line: &str) -> Option<&str> {
65
65
line. trim ( ) . strip_prefix ( "MSG: " ) . map ( str:: trim)
66
66
}
67
67
68
- /// A message field.
68
+ /// A message field definition.
69
+ /// Includes type, name, and optional default value.
70
+ ///
71
+ /// Examples:
72
+ /// ```text
73
+ /// // Simple int32 field with no default value
74
+ /// int32 field_name
75
+ ///
76
+ /// // Bounded string with max length 10, default value "default"
77
+ /// string<=10 name "default"
78
+ ///
79
+ /// // Array of 3 float64s with default value [0.0, 0.0, 0.0]
80
+ /// float64[3] position [0.0, 0.0, 0.0]
81
+ ///
82
+ /// // Unbounded array of complex types
83
+ /// pkg/Type[] items
84
+ /// ```
69
85
#[ derive( Debug , Clone , PartialEq ) ]
70
86
pub struct Field {
71
87
pub ty : Type ,
@@ -179,17 +195,30 @@ impl Type {
179
195
let len_str = & s[ "string<=" . len ( ) ..s. len ( ) - 1 ] ;
180
196
let len = len_str
181
197
. parse :: < usize > ( )
182
- . context ( "failed to parse bounded string length" ) ?;
198
+ . with_context ( || "failed to parse bounded string length" ) ?;
183
199
Ok ( Self :: String ( Some ( len) ) )
184
200
} else {
185
201
bail ! ( "invalid string type specifier: `{s}`" ) ;
186
202
}
187
203
}
188
204
}
189
205
206
+ /// A complex (non-primitive) type, possibly qualified with a package path.
207
+ ///
208
+ /// Examples:
209
+ /// ```text
210
+ /// // Absolute type with package
211
+ /// pkg/Type
212
+ ///
213
+ /// // Relative type without package
214
+ /// Type
215
+ /// ```
190
216
#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
191
217
pub enum ComplexType {
218
+ /// An absolute type with package, e.g. `pkg/Type`
192
219
Absolute { package : String , name : String } ,
220
+
221
+ /// A relative type without package, e.g. `Type`
193
222
Relative { name : String } ,
194
223
}
195
224
@@ -211,12 +240,14 @@ impl ComplexType {
211
240
"invalid complex type specifier: `{s}`, expected `some_package/SomeMessage` or `SomeMessage` format"
212
241
) ;
213
242
}
243
+
214
244
Ok ( Self :: Relative { name : s. to_owned ( ) } )
215
245
}
216
246
}
217
247
}
218
248
219
- #[ derive( Debug , Clone , PartialEq ) ]
249
+ /// Size specifier for array types.
250
+ #[ derive( Debug , Clone , PartialEq , Eq ) ]
220
251
pub enum ArraySize {
221
252
Fixed ( usize ) ,
222
253
Bounded ( usize ) ,
@@ -227,7 +258,8 @@ impl ArraySize {
227
258
fn parse ( array_part : & str ) -> Result < Self > {
228
259
let array_part = array_part
229
260
. strip_suffix ( ']' )
230
- . context ( "missing closing ']' in array type" ) ?;
261
+ . with_context ( || "Missing closing ']' in array type" ) ?;
262
+
231
263
let array_size = if array_part. is_empty ( ) {
232
264
Self :: Unbounded
233
265
} else if let Ok ( size) = array_part. parse :: < usize > ( ) {
@@ -236,7 +268,7 @@ impl ArraySize {
236
268
let size_str = & array_part[ 1 ..array_part. len ( ) - 1 ] ;
237
269
let size = size_str
238
270
. parse :: < usize > ( )
239
- . context ( "failed to parse bounded array size") ?;
271
+ . with_context ( || "Failed to parse bounded array size") ?;
240
272
Self :: Bounded ( size)
241
273
} else {
242
274
bail ! ( "invalid array size specifier: `{array_part}`" ) ;
@@ -245,6 +277,8 @@ impl ArraySize {
245
277
}
246
278
}
247
279
280
+ /// A literal value, used for default values and constant definitions.
281
+ /// Can be a primitive, string, or array of literals.
248
282
#[ derive( Debug , Clone , PartialEq ) ]
249
283
pub enum Literal {
250
284
Bool ( bool ) ,
@@ -272,25 +306,21 @@ impl Literal {
272
306
| PrimitiveType :: Int8
273
307
| PrimitiveType :: Int16
274
308
| PrimitiveType :: Int32
275
- | PrimitiveType :: Int64 => {
276
- let v = s
277
- . parse :: < i64 > ( )
278
- . context ( "failed to parse integer literal" ) ?;
279
- Ok ( Self :: Int ( v) )
280
- }
309
+ | PrimitiveType :: Int64 => s
310
+ . parse :: < i64 > ( )
311
+ . map ( Self :: Int )
312
+ . with_context ( || "failed to parse integer literal" ) ,
281
313
PrimitiveType :: UInt8
282
314
| PrimitiveType :: UInt16
283
315
| PrimitiveType :: UInt32
284
- | PrimitiveType :: UInt64 => {
285
- let v = s
286
- . parse :: < u64 > ( )
287
- . context ( "failed to parse unsigned integer literal" ) ?;
288
- Ok ( Self :: UInt ( v) )
289
- }
290
- PrimitiveType :: Float32 | PrimitiveType :: Float64 => {
291
- let v = s. parse :: < f64 > ( ) . context ( "failed to parse float literal" ) ?;
292
- Ok ( Self :: Float ( v) )
293
- }
316
+ | PrimitiveType :: UInt64 => s
317
+ . parse :: < u64 > ( )
318
+ . map ( Self :: UInt )
319
+ . with_context ( || "failed to parse unsigned integer literal" ) ,
320
+ PrimitiveType :: Float32 | PrimitiveType :: Float64 => s
321
+ . parse :: < f64 > ( )
322
+ . map ( Self :: Float )
323
+ . with_context ( || "failed to parse float literal" ) ,
294
324
} ,
295
325
Type :: String ( _) => {
296
326
let s = s. trim_matches ( '"' ) ;
@@ -301,6 +331,7 @@ impl Literal {
301
331
size : _,
302
332
} => {
303
333
let s = s. trim ( ) ;
334
+
304
335
if !s. starts_with ( '[' ) || !s. ends_with ( ']' ) {
305
336
bail ! ( "array literal must start with '[' and end with ']': `{s}`" ) ;
306
337
}
@@ -311,6 +342,7 @@ impl Literal {
311
342
let elem = Self :: parse ( elem_str, elem_ty) ?;
312
343
elems. push ( elem) ;
313
344
}
345
+
314
346
Ok ( Self :: Array ( elems) )
315
347
}
316
348
Type :: Complex ( _) => bail ! ( "cannot parse literal for named type" ) ,
@@ -319,6 +351,19 @@ impl Literal {
319
351
}
320
352
321
353
/// A compile-time constant defined alongside fields.
354
+ /// Includes type, name, and value.
355
+ ///
356
+ /// Examples:
357
+ /// ```text
358
+ /// // Integer constant
359
+ /// int32 CONST_NAME=42
360
+ ///
361
+ /// // String constant
362
+ /// string CONST_STR="hello"
363
+ ///
364
+ /// // Float constant
365
+ /// float64 CONST_FLOAT=3.14
366
+ /// ```
322
367
#[ derive( Debug , Clone , PartialEq ) ]
323
368
pub struct Constant {
324
369
pub ty : Type ,
@@ -354,11 +399,11 @@ impl Constant {
354
399
fn parse ( line : & str ) -> anyhow:: Result < Self > {
355
400
let ( type_and_name, value_str) = line
356
401
. split_once ( '=' )
357
- . context ( "constant definition missing '='" ) ?;
402
+ . with_context ( || "constant definition missing '='" ) ?;
358
403
let ( type_str, name) = type_and_name
359
404
. trim ( )
360
405
. rsplit_once ( ' ' )
361
- . context ( "constant definition missing space between type and name" ) ?;
406
+ . with_context ( || "constant definition missing space between type and name" ) ?;
362
407
363
408
let ty = Type :: parse ( type_str) ?;
364
409
let value = Literal :: parse ( value_str. trim ( ) , & ty) ?;
@@ -471,13 +516,8 @@ fn parse_section(lines: &[&str]) -> Option<(String, String)> {
471
516
472
517
#[ cfg( test) ]
473
518
mod tests {
519
+ use crate :: parsers:: dds;
474
520
use cdr_encoding:: CdrDeserializer ;
475
- use serde:: Deserializer ;
476
-
477
- use crate :: {
478
- cdr,
479
- parsers:: { dds, ros2msg:: definitions:: sensor_msgs} ,
480
- } ;
481
521
482
522
use super :: * ;
483
523
0 commit comments