@@ -53,19 +53,25 @@ impl MavProfile {
5353 }
5454
5555 /// Go over all fields in the messages, and if you encounter an enum,
56- /// update this enum with information about whether it is a bitmask, and what
57- /// is the desired width of such.
56+ /// which is a bitmask, set the bitmask size based on field size
5857 fn update_enums ( mut self ) -> Self {
59- for msg in self . messages . values ( ) {
60- for field in & msg. fields {
58+ for msg in self . messages . values_mut ( ) {
59+ for field in & mut msg. fields {
6160 if let Some ( enum_name) = & field. enumtype {
62- // it is a bitmask
63- if let Some ( "bitmask" ) = & field. display . as_deref ( ) {
64- // find the corresponding enum
65- for enm in self . enums . values_mut ( ) {
66- if enm. name == * enum_name {
67- // this is the right enum
68- enm. bitfield = Some ( field. mavtype . rust_primitive_type ( ) ) ;
61+ // find the corresponding enum
62+ if let Some ( enm) = self . enums . get_mut ( enum_name) {
63+ // Handle legacy definition where bitmask is defined as display="bitmask"
64+ if field. display == Some ( "bitmask" . to_string ( ) ) {
65+ enm. bitmask = true ;
66+ }
67+
68+ // it is a bitmask
69+ if enm. bitmask {
70+ enm. primitive = Some ( field. mavtype . rust_primitive_type ( ) ) ;
71+
72+ // Fix fields in backwards manner
73+ if field. display . is_none ( ) {
74+ field. display = Some ( "bitmask" . to_string ( ) ) ;
6975 }
7076 }
7177 }
@@ -310,8 +316,11 @@ pub struct MavEnum {
310316 pub name : String ,
311317 pub description : Option < String > ,
312318 pub entries : Vec < MavEnumEntry > ,
313- /// If contains Some, the string represents the type witdh for bitflags
314- pub bitfield : Option < String > ,
319+ /// If contains Some, the string represents the primitive type (size) for bitflags.
320+ /// If no fields use this enum, the bitmask is true, but primitive is None. In this case
321+ /// regular enum is generated as primitive is unknown.
322+ pub primitive : Option < String > ,
323+ pub bitmask : bool ,
315324}
316325
317326impl MavEnum {
@@ -356,7 +365,7 @@ impl MavEnum {
356365 let tmp = TokenStream :: from_str ( & tmp_value. to_string ( ) ) . unwrap ( ) ;
357366 value = quote ! ( #tmp) ;
358367 } ;
359- if self . bitfield . is_some ( ) {
368+ if self . primitive . is_some ( ) {
360369 quote ! {
361370 #description
362371 const #name = #value;
@@ -398,14 +407,14 @@ impl MavEnum {
398407 let description = quote ! ( ) ;
399408
400409 let enum_def;
401- if let Some ( width ) = self . bitfield . clone ( ) {
402- let width = format_ident ! ( "{}" , width ) ;
410+ if let Some ( primitive ) = self . primitive . clone ( ) {
411+ let primitive = format_ident ! ( "{}" , primitive ) ;
403412 enum_def = quote ! {
404413 bitflags!{
405414 #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
406415 #[ cfg_attr( feature = "arbitrary" , derive( Arbitrary ) ) ]
407416 #description
408- pub struct #enum_name: #width {
417+ pub struct #enum_name: #primitive {
409418 #( #defs) *
410419 }
411420 }
@@ -1171,6 +1180,8 @@ pub fn parse_profile(
11711180 if attr. key . into_inner ( ) == b"name" {
11721181 mavenum. name = to_pascal_case ( attr. value ) ;
11731182 //mavenum.name = attr.value.clone();
1183+ } else if attr. key . into_inner ( ) == b"bitmask" {
1184+ mavenum. bitmask = true ;
11741185 }
11751186 }
11761187 Some ( & MavXmlElement :: Entry ) => {
@@ -1230,8 +1241,16 @@ pub fn parse_profile(
12301241 field. mavtype = MavType :: parse_type ( & r#type) . unwrap ( ) ;
12311242 }
12321243 b"enum" => {
1233- field. enumtype = Some ( to_pascal_case ( attr. value ) ) ;
1234- //field.enumtype = Some(attr.value.clone());
1244+ field. enumtype = Some ( to_pascal_case ( & attr. value ) ) ;
1245+
1246+ // Update field display if enum is a bitmask
1247+ if let Some ( e) =
1248+ profile. enums . get ( field. enumtype . as_ref ( ) . unwrap ( ) )
1249+ {
1250+ if e. bitmask {
1251+ field. display = Some ( "bitmask" . to_string ( ) ) ;
1252+ }
1253+ }
12351254 }
12361255 b"display" => {
12371256 field. display =
@@ -1439,16 +1458,35 @@ struct ExtensionFilter {
14391458 pub is_in : bool ,
14401459}
14411460
1461+ struct MessageFilter {
1462+ pub is_in : bool ,
1463+ pub messages : Vec < String > ,
1464+ }
1465+
1466+ impl MessageFilter {
1467+ pub fn new ( ) -> Self {
1468+ Self {
1469+ is_in : false ,
1470+ messages : vec ! [
1471+ // device_cap_flags is u32, when enum is u16, which is not handled by the parser yet
1472+ "STORM32_GIMBAL_MANAGER_INFORMATION" . to_string( ) ,
1473+ ] ,
1474+ }
1475+ }
1476+ }
1477+
14421478struct MavXmlFilter {
14431479 #[ cfg( not( feature = "emit-extensions" ) ) ]
14441480 extension_filter : ExtensionFilter ,
1481+ message_filter : MessageFilter ,
14451482}
14461483
14471484impl Default for MavXmlFilter {
14481485 fn default ( ) -> Self {
14491486 Self {
14501487 #[ cfg( not( feature = "emit-extensions" ) ) ]
14511488 extension_filter : ExtensionFilter { is_in : false } ,
1489+ message_filter : MessageFilter :: new ( ) ,
14521490 }
14531491 }
14541492}
@@ -1457,6 +1495,7 @@ impl MavXmlFilter {
14571495 pub fn filter ( & mut self , elements : & mut Vec < Result < Event , quick_xml:: Error > > ) {
14581496 // List of filters
14591497 elements. retain ( |x| self . filter_extension ( x) ) ;
1498+ elements. retain ( |x| self . filter_messages ( x) )
14601499 }
14611500
14621501 #[ cfg( feature = "emit-extensions" ) ]
@@ -1500,6 +1539,52 @@ impl MavXmlFilter {
15001539 Err ( error) => panic ! ( "Failed to filter XML: {error}" ) ,
15011540 }
15021541 }
1542+
1543+ /// Filters messages by their name
1544+ pub fn filter_messages ( & mut self , element : & Result < Event , quick_xml:: Error > ) -> bool {
1545+ match element {
1546+ Ok ( content) => {
1547+ match content {
1548+ Event :: Start ( bytes) | Event :: Empty ( bytes) => {
1549+ let Some ( id) = identify_element ( bytes. name ( ) . into_inner ( ) ) else {
1550+ panic ! (
1551+ "unexpected element {:?}" ,
1552+ String :: from_utf8_lossy( bytes. name( ) . into_inner( ) )
1553+ ) ;
1554+ } ;
1555+ if id == MavXmlElement :: Message {
1556+ for attr in bytes. attributes ( ) {
1557+ let attr = attr. unwrap ( ) ;
1558+ if attr. key . into_inner ( ) == b"name" {
1559+ let value = String :: from_utf8_lossy ( & attr. value ) . into_owned ( ) ;
1560+ if self . message_filter . messages . contains ( & value) {
1561+ self . message_filter . is_in = true ;
1562+ return false ;
1563+ }
1564+ }
1565+ }
1566+ }
1567+ }
1568+ Event :: End ( bytes) => {
1569+ let Some ( id) = identify_element ( bytes. name ( ) . into_inner ( ) ) else {
1570+ panic ! (
1571+ "unexpected element {:?}" ,
1572+ String :: from_utf8_lossy( bytes. name( ) . into_inner( ) )
1573+ ) ;
1574+ } ;
1575+
1576+ if id == MavXmlElement :: Message && self . message_filter . is_in {
1577+ self . message_filter . is_in = false ;
1578+ return false ;
1579+ }
1580+ }
1581+ _ => { }
1582+ }
1583+ !self . message_filter . is_in
1584+ }
1585+ Err ( error) => panic ! ( "Failed to filter XML: {error}" ) ,
1586+ }
1587+ }
15031588}
15041589
15051590fn to_pascal_case ( text : impl AsRef < [ u8 ] > ) -> String {
0 commit comments