bitis_lib/lib_impl/
compiler.rs

1use std::collections::HashMap;
2use std::process::{abort};
3use askama::Template;
4use logos::{Lexer, Logos, Span};
5use regex::Regex;
6use stringcase::Caser;
7
8
9// ************************************************************************
10// ************************************************************************
11fn integer_bit_size(bit_size: &u8) -> u8 {
12    match bit_size {
13        0..=8 => 8,
14        9..=16 => 16,
15        17..=32 => 32,
16        _ => 64
17    }
18}
19// ************************************************************************
20#[derive(Debug, Clone )]
21#[allow(unused)]
22pub struct AttributeEx {
23    base: Attribute,
24    rust_type_str: String,
25    // rust_pyo3_str: String,
26    base_type_str: String,
27    is_py_wrapped: bool, is_msg: bool, is_enum: bool, is_oo: bool, add_val: bool,
28}
29#[derive(Debug, Clone )]
30pub struct MessageR {
31    pub name: String,
32    // pub version_info: VersionInfo,
33    pub comment: Option<String>,
34    pub parent: Option<String>,
35    pub attributes: Vec<AttributeEx>,
36}
37#[derive(Debug, Clone )]
38#[allow(dead_code)]
39pub struct OneOfInfoR {
40    msg_name: String,
41    name: String,
42    dyn_bits: u8,
43    attributes: Vec<AttributeEx>,
44}
45fn to_rust_attribute(attribute: &Attribute, msg_names: &Vec<String>) -> AttributeEx {
46    let (rtype, base_type, is_py_wrapped, is_msg, is_enum, is_oo, add_val) = {
47        let mut is_py_wrapped = false;
48        let mut is_enum = false;
49        let mut is_msg = false;
50        let mut is_oo = false;
51        let mut add_val = false;
52
53        let (rtype, base_type) = match &attribute.specific_details {
54            AttributeDetails::AttributeSimple(a) => {
55                match a {
56                    SimpleType::NoTypeSetYet => {
57                        println!("Unexpected unspecified attribute type");
58                        abort()
59                    },
60                    SimpleType::Bool => { ("bool".to_string(), "bool".to_string()) }
61                    SimpleType::UIntFixed(b) => {
62                        add_val = true;
63                        let base = format!("u{}", integer_bit_size(&b));
64                        (format!("VarWithGivenBitSize<{}, {}>", base.clone(), b), base) }
65                    SimpleType::IntFixed(b) => {
66                        add_val = true;
67                        let base = format!("i{}", integer_bit_size(&b));
68                        (format!("VarWithGivenBitSize<{}, {}>", base.clone(), b), base) }
69                    SimpleType::UIntDyn(b) => {
70                        add_val = true;
71                        let base = format!("u{}", integer_bit_size(&b.0));
72                        (format!("DynInteger<{}, {}>", base.clone(), b.1), base) }
73                    SimpleType::IntDyn(b) => {
74                        add_val = true;
75                        let base = format!("i{}", integer_bit_size(&b.0));
76                        (format!("DynInteger<{}, {}>", base.clone(), b.1), base) }
77                    SimpleType::Float => {
78                        add_val = true;
79                        let base = "f32".to_string();
80                        (base.clone(), base)
81                    }
82                    SimpleType::Double => {
83                        let base = "f64".to_string();
84                        (base.clone(), base) }
85                    SimpleType::FixedPrecision(fpp) => {
86                        add_val = true;
87                        (format!("FixPrecisionMinMax<{}, {}, {}>", fpp.bits, fpp.min_val, fpp.max_val), "f64".to_string())
88                    }
89                    SimpleType::Binary(b) => {
90                        add_val = true;
91                        (format!("Binary<{}>", b), "Vec<u8>".to_string()) }
92                }
93            }
94            AttributeDetails::AttributeEnumOrMsg(em) => {
95                is_py_wrapped = true;
96                is_msg = msg_names.contains(&em);
97                is_enum = !is_msg.clone();
98                (em.clone(), em.clone()) }
99            AttributeDetails::AttributeOneOf(ooi) => {
100                is_py_wrapped=true; is_oo = true;
101                (ooi.name.clone(), ooi.name.clone()) }
102        };
103        (rtype, base_type, is_py_wrapped, is_msg, is_enum, is_oo,  add_val)
104    };
105    AttributeEx{base: attribute.clone(), rust_type_str: rtype, base_type_str: base_type,
106        is_py_wrapped, is_msg, is_enum, is_oo, add_val }
107}
108
109pub fn to_rust_messages(msgs: &Vec<Message>) -> Vec<MessageR> {
110    let msgs_names: Vec<_> = msgs.iter().map(|m| {m.name.clone()}).collect();
111
112    msgs.iter().map(|msg| {
113        let attrs_rust: Vec<_> = msg.attributes.iter().map(|attribute| {
114            to_rust_attribute(attribute, &msgs_names) }).collect();
115        MessageR{name: msg.name.clone(), comment: msg.comment.clone(), parent: msg.parent.clone(),
116            attributes: attrs_rust}
117    }).collect()
118}
119pub fn to_rust_oneofs(oos: &Vec<(String, OneOfInfo)>, msgs: &Vec<Message>) -> HashMap<String, OneOfInfoR> {
120    let msgs_names: Vec<_> = msgs.iter().map(|m| {m.name.clone()}).collect();
121
122    oos.iter().map(|(msg_name, oo)| {
123        let attrs_rust: Vec<_> = oo.attributes.iter().map(|attribute| {
124            to_rust_attribute(attribute, &msgs_names) }).collect();
125        (oo.name.clone(), OneOfInfoR{msg_name: msg_name.clone(), name: oo.name.clone(), dyn_bits: oo.dyn_bits, attributes: attrs_rust})
126    }).collect()
127}
128
129fn to_cpp_attribute(attribute: &Attribute, msg_names: &Vec<String>) -> AttributeEx {
130    let (rtype, base_type, is_py_wrapped, is_msg, is_enum, is_oo, add_val) = {
131        let mut is_py_wrapped = false;
132        let mut is_enum = false;
133        let mut is_msg = false;
134        let mut is_oo = false;
135        let mut add_val = false;
136
137        let (rtype, base_type) = match &attribute.specific_details {
138            AttributeDetails::AttributeSimple(a) => {
139                match a {
140                    SimpleType::NoTypeSetYet => {
141                        println!("Unexpected unspecified attribute type");
142                        abort()
143                    },
144                    SimpleType::Bool => { ("BitisBool".to_string(), "bool".to_string()) }
145                    SimpleType::UIntFixed(b) => {
146                        add_val = true;
147                        let base = format!("uint{}_t", integer_bit_size(&b));
148                        (format!("IntgralWithGivenBitSize<{}, {}>", base.clone(), b), base) }
149                    SimpleType::IntFixed(b) => {
150                        add_val = true;
151                        let base = format!("int{}_t", integer_bit_size(&b));
152                        (format!("IntgralWithGivenBitSize<{}, {}>", base.clone(), b), base) }
153                    SimpleType::UIntDyn(b) => {
154                        add_val = true;
155                        let base = format!("uint{}_t", integer_bit_size(&b.0));
156                        (format!("DynInteger<{}, {}>", base.clone(), b.1), base) }
157                    SimpleType::IntDyn(b) => {
158                        add_val = true;
159                        let base = format!("int{}_t", integer_bit_size(&b.0));
160                        (format!("DynInteger<{}, {}>", base.clone(), b.1), base) }
161                    SimpleType::Float => {
162                        add_val = true;
163                        let base = "float".to_string();
164                        (base.clone(), base)
165                    }
166                    SimpleType::Double => {
167                        let base = "double".to_string();
168                        (base.clone(), base) }
169                    SimpleType::FixedPrecision(fpp) => {
170                        add_val = true;
171                        (format!("FixPrecisionMinMax<{}, {}, {}>", fpp.bits, fpp.min_val, fpp.max_val), "double".to_string())
172                    }
173                    SimpleType::Binary(b) => {
174                        add_val = true;
175                        (format!("Binary<{}>", b), "Vec<u8>".to_string()) }
176                }
177            }
178            AttributeDetails::AttributeEnumOrMsg(em) => {
179                is_py_wrapped = true;
180                is_msg = msg_names.contains(&em);
181                is_enum = !is_msg.clone();
182                (em.clone(), em.clone()) }
183            AttributeDetails::AttributeOneOf(ooi) => {
184                is_py_wrapped=true; is_oo = true;
185                (ooi.name.clone(), ooi.name.clone()) }
186        };
187        (rtype, base_type, is_py_wrapped, is_msg, is_enum, is_oo,  add_val)
188    };
189    AttributeEx{base: attribute.clone(), rust_type_str: rtype, base_type_str: base_type,
190        is_py_wrapped, is_msg, is_enum, is_oo, add_val }
191}
192pub fn to_cpp_messages(msgs: &Vec<Message>) -> Vec<MessageR> {
193    let msgs_names: Vec<_> = msgs.iter().map(|m| {m.name.clone()}).collect();
194
195    msgs.iter().map(|msg| {
196        let attrs_rust: Vec<_> = msg.attributes.iter().map(|attribute| {
197            to_cpp_attribute(attribute, &msgs_names) }).collect();
198        MessageR{name: msg.name.clone(), comment: msg.comment.clone(), parent: msg.parent.clone(),
199            attributes: attrs_rust}
200    }).collect()
201}
202pub fn to_cpp_oneofs(oos: &Vec<(String, OneOfInfo)>, msgs: &Vec<Message>) -> HashMap<String, OneOfInfoR> {
203    let msgs_names: Vec<_> = msgs.iter().map(|m| {m.name.clone()}).collect();
204
205    oos.iter().map(|(msg_name, oo)| {
206        let attrs_cpp: Vec<_> = oo.attributes.iter().map(|attribute| {
207            to_cpp_attribute(attribute, &msgs_names) }).collect();
208        (oo.name.clone(), OneOfInfoR{msg_name: msg_name.clone(), name: oo.name.clone(), dyn_bits: oo.dyn_bits, attributes: attrs_cpp })
209    }).collect()
210}
211
212#[derive(Clone, Debug)]
213pub struct JinjaData {
214    pub enums: Vec<Enum>,
215    pub msgs: Vec<MessageR>,
216    pub oos: HashMap<String, OneOfInfoR>,
217}
218
219#[derive(Template, Clone, Debug)]
220#[template(path = "data_objects.rs.jinja")]
221pub struct RustDataObjects {
222    pub d: JinjaData
223}
224#[derive(Template, Clone, Debug)]
225#[template(path = "pyclasses.py.rs.jinja")]
226pub struct RustPyDataObjects {
227    pub d: JinjaData
228}
229#[derive(Template, Clone, Debug)]
230#[template(path = "pylib.py.rs.jinja")]
231pub struct RustPyLib {
232    pub d: JinjaData,
233    pub lib_name: String
234}
235#[derive(Template, Clone, Debug)]
236#[template(path = "py_type_hints.pyi.jinja")]
237pub struct PyTypeHints {
238    pub d: JinjaData
239}
240#[derive(Template, Clone, Debug)]
241#[template(path = "data_objects.cpp.jinja")]
242pub struct CppDataObjects {
243    pub d: JinjaData,
244    pub object_order: Vec<String>,
245}
246
247
248mod filters {
249    #[allow(dead_code)]
250    pub fn snake_case<T: std::fmt::Display>(s: T, _: &dyn askama::Values) -> ::askama::Result<String> {
251        Ok(stringcase::snake_case(s.to_string().as_str()))
252    }
253    #[allow(dead_code)]
254    pub fn camel_case<T: std::fmt::Display>(s: T, _: &dyn askama::Values,) -> ::askama::Result<String> {
255        Ok(stringcase::camel_case(s.to_string().as_str()))
256    }
257    #[allow(dead_code)]
258    pub fn pascal_case<T: std::fmt::Display>(s: T, _: &dyn askama::Values,) -> ::askama::Result<String> {
259        Ok(stringcase::pascal_case(s.to_string().as_str()))
260    }
261    #[allow(dead_code)]
262    pub fn to_py_type<T: std::fmt::Display>(s: T, _: &dyn askama::Values,) -> ::askama::Result<String> {
263        if ["u8", "u16", "u32", "u64", "i8", "i16", "i32", "i64"].contains(&s.to_string().as_str()) {
264            Ok("int".to_string()) }
265        else if ["f32", "f64"].contains(&s.to_string().as_str()) {
266            Ok("float".to_string())
267        }
268        else { Ok(s.to_string()) }
269    }
270}
271
272// ************************************************************************
273type Error = (String, Span);
274
275type Result<T> = std::result::Result<T, Error>;
276
277#[derive(Debug, Clone)]
278pub enum DynOrFixedType {
279    Dyn(u8),
280    Fixed(u8)
281}
282#[derive(Debug, PartialEq, Eq, Clone, Copy)]
283pub struct FixedPrecisionProperties {
284    bits: u8, min_val: i64, max_val: i64
285}
286#[derive(Debug, PartialEq, Eq, Clone, Copy)]
287pub enum SimpleType {
288    NoTypeSetYet,
289    Bool,
290    UIntFixed(u8), IntFixed(u8),
291    UIntDyn((u8,u8)), IntDyn((u8,u8)),
292    Float, Double,
293    FixedPrecision(FixedPrecisionProperties),
294    Binary(u8),
295}
296/*impl SimpleType {
297    fn int_size(min_bits: u8) -> std::result::Result<u8, String> {
298        match min_bits {
299            1..=8 => Ok(8),
300            9..=16 => Ok(16),
301            17..=32 => Ok(32),
302            33..=64 => Ok(64),
303            34..=128 => Ok(128),
304            0 => Err("Bitsize of zero for integer is not allowed".into()),
305            _ => Err("Bitsize larger than 128  for integer are not allowed".into())
306        }
307    }
308    fn get_int_bits(self) -> std::result::Result<u8, String> {
309        match self {
310            SimpleType::UIntFixed(s) => Ok(SimpleType::int_size(s)?),
311            SimpleType::IntFixed(s) => Ok(SimpleType::int_size(s)?),
312            SimpleType::UIntDyn((s,_)) => Ok(SimpleType::int_size(s)?),
313            SimpleType::IntDyn((s,_)) => Ok(SimpleType::int_size(s)?),
314            SimpleType::FixedPrecision(fps) => Ok(SimpleType::int_size(fps.bits)?),
315            SimpleType::UFixedPrecision(fps) => Ok(SimpleType::int_size(fps.bits)?),
316            _ => Err("get_int_bits(): Only integers types allowed.".into())
317        }
318    }
319    fn get_int_bits_no_error(self) -> u8 {
320        match self.get_int_bits() {
321            Ok(bits) => bits,
322            Err(e) => { println!("Error: {}", e); abort(); }
323        }
324    }
325}*/
326
327#[derive(Debug, Clone )]
328pub struct OneOfInfo {
329    name: String,
330    dyn_bits: u8,
331    attributes: Vec<Attribute>,
332}
333#[derive(Debug, Clone )]
334pub enum AttributeDetails {
335    AttributeSimple(SimpleType),
336    AttributeEnumOrMsg(String),
337    AttributeOneOf(OneOfInfo),
338}
339#[derive(Debug, Clone )]
340pub struct Attribute {
341    name: String,
342    comment: Option<String>,
343    is_repeated_and_size: Option<DynOrFixedType>,
344    is_optional: bool,
345    specific_details: AttributeDetails
346}
347// #[derive(Debug, Clone)]
348// pub enum VersionInfo {
349//     Version(u16),
350//     BaseWithAllowedVersion(u16),
351// }
352#[derive(Debug, Clone)]
353pub struct Message {
354    pub name: String,
355    // pub version_info: VersionInfo,
356    pub comment: Option<String>,
357    pub parent: Option<String>,
358    pub attributes: Vec<Attribute>,
359}
360
361/// Enum information for bitis. The ids are always DynInteger with a given bit size.
362#[derive(Debug, Clone)]
363pub struct Enum {
364    pub name: String,
365    // pub version_info: VersionInfo,
366    pub comment: Option<String>,
367    pub bit_size: u8,
368    pub values: Vec<String>,
369    pub default: String
370}
371
372pub fn get_suffix_number(lex: &mut Lexer<Token>) -> Option<u8> {
373    let slice = lex.slice();
374    let re = Regex::new(r".*_d?([0-9]+)$").unwrap();
375    let num_str = re.captures(slice)?.get(1)?;
376    num_str.as_str().parse().ok()
377}
378pub fn get_d_suffix_numbers(lex: &mut Lexer<Token>) -> Option<(u8,u8)> {
379    let slice = lex.slice();
380    let re = Regex::new(r".*_([0-9]+)d([0-9]+)$").unwrap();
381    let first_num_str = re.captures(slice)?.get(1)?.as_str().parse().ok()?;
382    let second_num_str = re.captures(slice)?.get(2)?.as_str().parse().ok()?;
383    Some((first_num_str, second_num_str))
384}
385pub fn get_fp_properties_number(lex: &mut Lexer<Token>) -> Option<FixedPrecisionProperties> {
386    let slice = lex.slice();
387    let re = Regex::new(r"fp_([0-9]+)\[ *(-?[0-9]+) *, *(-?[0-9]+) *]").unwrap();
388    let bits = re.captures(slice)?.get(1)?.as_str().parse::<u8>().ok()?;
389    let min_val = re.captures(slice)?.get(2)?.as_str().parse::<i64>().ok()?;
390    let max_val = re.captures(slice)?.get(3)?.as_str().parse::<i64>().ok()?;
391    Some(FixedPrecisionProperties {bits, min_val, max_val})
392}
393/*pub fn get_dyn_or_fixed_from_args(lex: &mut Lexer<Token>) -> Option<DynOrFixedType> {
394    let slice = lex.slice();
395    let re = Regex::new(r" *(dyn|fixed) *, *([0-9]+)").unwrap();
396    let type_str = re.captures(slice)?.get(1)?.as_str();
397    let bits = re.captures(slice)?.get(2)?.as_str().parse::<u8>().ok()?;
398    if type_str == "dyn" {
399        Some(DynOrFixedType::Dyn(bits))
400    }
401    else {
402        Some(DynOrFixedType::Fixed(bits))
403    }
404}*/
405pub fn get_enum_bit_size(lex: &mut Lexer<Token>) -> Option<u8> {
406    let slice = lex.slice();
407    let re = Regex::new(r"\( *([0-9]+) *\)").unwrap();
408    let bits = re.captures(slice)?.get(1)?.as_str().parse::<u8>().ok()?;
409    Some(bits)
410}
411pub fn get_version(lex: &mut Lexer<Token>) -> Option<u16> {
412    let slice = lex.slice();
413    let re = Regex::new(r"\[.* +(v[0-9]+) *]").unwrap();
414    let ver_str = re.captures(slice)?.get(1)?.as_str();
415    Some(ver_str.parse::<u16>().ok()?)
416}
417
418#[derive(Debug, Logos)]
419#[logos(skip r"[ \t\r\n\f]+")]
420#[logos(extras = u16)]
421#[allow(dead_code)]
422pub enum Token{
423    #[regex(r"//[^\n]*\n?", priority=40)] Comment,
424    #[regex(r"//\|[^\n]*\n?", |lex| lex.slice()[3..].to_owned(), priority=41)] SpecificComment(String),
425    #[token("msg", priority=20)] Msg,
426    #[token("enum", priority=20)] Enum,
427    #[token("oneof", priority=20)] OneOf,
428    #[token("{")] CBraceOpen,
429    #[token("}")] CBraceClose,
430    #[token("(")] BraceOpen,
431    #[token(")")] BraceClose,
432    #[token(":")] Colon,
433    #[token(";")] SemiColon,
434    #[token(",")] Comma,
435    #[token("*")] Star,
436    // #[token("fixed", priority=20)] FixedFlag,
437    // #[token("dyn", priority=20)] DynFlag,
438    #[regex(r"\[ *base +use +starting +with +v[0-9]+ *\]", get_version, priority=35)] MsgBaseInfoToken(u16),
439    #[regex(r"\[ *version +v[0-9]+ *\]", get_version, priority=35)] MsgVersionToken(u16),
440    // #[regex(r"\[ *base +use +starting +with +v[0-9]+ *\]", get_version, priority=35)] MsgVersionToken((MsgVersion, u16)),
441    #[regex("[0-9]+", |lex| lex.slice().parse::<isize>().unwrap(), priority=1)] IntegerVal(isize),
442    #[regex(r"-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?",
443        |lex| lex.slice().parse::<f64>().unwrap(), priority=2)] Number(f64),
444    #[token("bool", priority=30)] Bool,
445    #[token("msg_size_type", priority=30)] MsgSizeType,
446    #[regex(r"uint_[0-9]+", get_suffix_number, priority=30)] UIntFixed(u8),
447    #[regex(r"int_[0-9]+", get_suffix_number, priority=30)] IntFixed(u8),
448    #[regex(r"uint_[0-9]+d[0-9]+", get_d_suffix_numbers, priority=31)] UIntDyn((u8,u8)),
449    #[regex(r"int_[0-9]+d[0-9]+", get_d_suffix_numbers, priority=31)] IntDyn((u8,u8)),
450    #[token("float", priority=30)] Float,
451    #[token("double", priority=30)] Double,
452    #[regex(r"fp_[0-9]+\[ *-?[0-9]+ *, *-?[0-9]+ *]", get_fp_properties_number, priority=30)] FixedPoint(FixedPrecisionProperties),
453    // #[regex(r"ufp_[0-9]+\[ *-?[0-9]+ *, *-?[0-9]+ *]", get_fp_properties_number, priority=30)] UFixedPoint(FixedPrecisionProperties),
454    //#[token("str", priority=30)] String,
455    #[token("binary_d[0-9]+", get_suffix_number, priority=30)] Binary(u8),
456    #[regex(r"repeated_dyn_[0-9]+", get_suffix_number, priority=30)] RepeatedDyn(u8),
457    #[regex(r"repeated_fixed_[0-9]+", get_suffix_number, priority=30)] RepeatedFixed(u8),
458    #[token("optional", priority=30)] Optional,
459    #[regex(r"[A-Za-z][A-Za-z0-9_-]+", |lex| lex.slice().to_owned(), priority=11)] StringVal(String),
460    #[token("false", |_| false, priority=20)]
461    #[token("true", |_| true, priority=20)] BoolVal(bool),
462    #[regex(r"\( *([0-9]+) *\)", get_enum_bit_size, priority=40)] EnumDynSize(u8),
463}
464
465#[derive(Debug, Clone)]
466pub enum Value {
467    /// null.
468    Message(Message),
469    /// Enum.
470    Enum(Enum)
471}
472
473macro_rules! parse_one_token {
474    ($token_enum: path, $lexer: expr, $error_msg_or_empty: expr) => {
475        loop {
476            let rv = $lexer.next();
477            if let Some(token) = rv {
478                match token {
479                    Ok($token_enum) => {
480                        break Ok(Ok(()));
481                    },
482                    Ok(Token::Comment) => (),
483                    _ => {
484                        if let Some(err_str) = $error_msg_or_empty {
485                            break Err((format!("{err_str}\nToken: {token:?}").to_owned(), $lexer.span()));
486                        }
487                        else {
488                            break Ok(Err($lexer.span()));
489                        }
490                    }
491                }
492            }
493            else {
494                break Err((format!("Unexpected end or text {rv:?}").to_owned(), $lexer.span()));
495            }
496        }
497    }
498}
499macro_rules! parse_one_token_with_arg {
500    ($token_enum: path, $lexer: expr, $error_msg_or_empty: expr) => {
501        loop {
502            let rv = $lexer.next();
503            if let Some(token) = rv {
504                match token {
505                    Ok($token_enum(s)) => {
506                        break Ok(Ok(s));
507                    },
508                    Ok(Token::Comment) => (),
509                    _ => {
510                        if let Some(err_str) = $error_msg_or_empty {
511                            break Err((format!("{}\nFound token: {:?}.",
512                                err_str, token).to_owned(), $lexer.span()));
513                        }
514                        else {
515                            break Ok(Err($lexer.span()));
516                        }
517                    }
518                }
519            }
520            else {
521                break Err((format!("Unexpected end or text {rv:?}").to_owned(), $lexer.span()));
522            }
523        }
524    }
525}
526
527pub fn parse_root(lexer: &mut Lexer<'_, Token>) -> Result<Vec<Value>> {
528    let mut list: Vec<Value> = Vec::new();
529    let mut specific_comment: Option<String> = None;
530    loop {
531        if let Some(token) = lexer.next() {
532            let rv = match token {
533                Ok(Token::Msg) => Some(parse_msg(lexer, specific_comment.clone())),
534                Ok(Token::Enum) => Some(parse_enum(lexer, specific_comment.clone())),
535                Ok(Token::Comment) => None,
536                Ok(Token::SpecificComment(s)) => {
537                    specific_comment = Some(s); None },
538                _ => Some(Err((format!("Unexpected token {:?}", token).to_owned(), lexer.span()))),
539            };
540            match rv {
541                None => (),
542                Some(Ok(value)) => { list.push(value); specific_comment = None; },
543                Some(Err(err)) => return Err(err)
544            }
545        }
546        else { break; }
547    }
548    Ok(list)
549}
550
551pub fn parse_msg(lexer: &mut Lexer<'_, Token>, comment_for_msg: Option<String>) -> Result<Value> {
552    let mut attributes = Vec::new();
553
554    let name = match parse_one_token_with_arg!(Token::StringVal, lexer, Some("Expected msg name but received:"))? {
555        Ok(s) => s,
556        Err(s) => { return Err(("Code should not be reached".into(), s)); }
557    };
558
559    // let version_info = if(lexer.extras == 0) {
560    //     if let Some(token) = lexer.next() {
561    //         match token {
562    //             Ok(Token::MsgVersionToken(v)) => VersionInfo::Version(v),
563    //             Ok(Token::MsgBaseInfoToken(v)) => VersionInfo::BaseWithAllowedVersion(v),
564    //             Ok(_) => { return Err((format!("Unexpected token {:?} for message '{}' when expecting version info", token, name)
565    //                                    .to_owned(), lexer.span())); }
566    //             Err(_) => { return Err((format!("Error: Syntax error for message '{}'", name).to_owned(), lexer.span())); }
567    //         }
568    //     } else { return Err(("Unexpectedly did not find version information".to_owned(), lexer.span())); }
569    // }
570    // else { VersionInfo::Version(lexer.extras) };
571
572    let parent = {
573        let has_parent; let p;
574        if let Some(token) = lexer.next() {
575            match token {
576                Ok(Token::Colon) => has_parent = true,
577                Ok(Token::CBraceOpen) => has_parent = false,
578                _ => { return Err((format!("Unexpected text for msg '{name}'.").into(), lexer.span())) },
579            }
580            if has_parent {
581                match parse_one_token_with_arg!(Token::StringVal, lexer, Some("Expected msg name."))? {
582                    Ok(s) => p = Some(s),
583                    Err(s) => { return Err((format!("For msg '{name} colon found but no parent name").into(), s)); }
584                };
585                parse_one_token!(Token::CBraceOpen, lexer, Some(format!("Expected curly bracket open for msg '{name}'")))?.unwrap();
586            }
587            else {
588                p = None
589            }
590        }
591        else { return Err(("Unexpected end of file".into(), lexer.span())); }
592        p
593    };
594
595    loop {
596        if let Some(token) = lexer.next() {
597            match token {
598                Ok(Token::CBraceClose) => break,
599                Ok(Token::Comment) => (),
600                Ok(ctoken) => match parse_attribute(ctoken, lexer, name.clone(), false) {
601                    Ok(a) => { attributes.push(a); },
602                    Err(e) => { return Err(e); }
603                },
604                _ => { return Err((format!("Error: Unexpected text found for msg '{name}'.").into(), lexer.span())) },
605            };
606        }
607        else { return Err(("Unexpected end of file".into(), lexer.span())); }
608    }
609
610    Ok(Value::Message(Message{name, /*version_info,*/ comment: comment_for_msg, parent, attributes}))
611}
612
613pub fn parse_attribute(last_token: Token, lexer: &mut Lexer<'_, Token>,
614                       parent_name: String, attributes_for_oneof: bool) -> Result<Attribute> {
615    let mut is_optional = false;
616    let mut is_repeated_and_size: Option<DynOrFixedType> = None;
617    let mut attr_type = SimpleType::NoTypeSetYet;
618    let mut ctoken = last_token;
619    let mut enum_or_msg_str = None;
620    let mut oneof_infos = None;
621    let lexer_span_start = lexer.span();
622    let mut specific_comment: Option<String> = None;
623
624    loop {
625        match ctoken {
626            Token::SpecificComment(s) => {
627                specific_comment = Some(s); () },
628            Token::Optional if is_repeated_and_size.is_some() =>
629                return Err(("Error: Optional and repeated not allowed together".to_owned(), lexer.span())),
630            Token::RepeatedFixed(_) | Token::RepeatedDyn(_) if is_optional =>
631                return Err(("Error: Optional and repeated are not allowed together".to_owned(), lexer.span())),
632
633            Token::Optional | Token::RepeatedDyn(_) | Token::RepeatedFixed(_) if attributes_for_oneof =>
634                return Err(("Error: Optional and repeated are not allowed in oneof".to_owned(), lexer.span())),
635
636            Token::Optional => is_optional = true,
637            Token::RepeatedDyn(b) => is_repeated_and_size = Some(DynOrFixedType::Dyn(b)),
638            Token::RepeatedFixed(b) => is_repeated_and_size = Some(DynOrFixedType::Fixed(b)),
639            Token::Bool => { attr_type = SimpleType::Bool; break; },
640            Token::UIntFixed(s) => { attr_type = SimpleType::UIntFixed(s); break; },
641            Token::UIntDyn((m,s)) if m < s =>
642                return Err(("Error: Unsigned dyn integer bit size of integer type must be bigger than the bit size of the package".to_owned(), lexer.span())),
643            Token::UIntDyn((m,_)) if (m & 3) != 0 =>
644                return Err(("Error: Unsigned dyn integer bit size of integer type must be a multiple of 8".to_owned(), lexer.span())),
645            Token::UIntDyn((m,s)) => { attr_type = SimpleType::UIntDyn((m, s)); break; },
646            Token::IntFixed(s) => { attr_type = SimpleType::IntFixed(s); break; },
647            Token::IntDyn((m,s)) if m < s =>
648                return Err(("Error: Unsigned dyn integer bit size of integer type must be bigger than the bit size of the package".to_owned(), lexer.span())),
649            Token::IntDyn((m,_)) if (m & 3) != 0 =>
650                return Err(("Error: Unsigned dyn integer bit size of integer type must be a multiple of 8".to_owned(), lexer.span())),
651            Token::IntDyn((m,s)) => {
652                attr_type = SimpleType::IntDyn((m,s)); break;
653            },
654            //Token::String => { attr_type = SimpleType::String; break; },
655            Token::Float => { attr_type = SimpleType::Float; break; },
656            Token::Double => { attr_type = SimpleType::Double; break; },
657            Token::FixedPoint(s) => { attr_type = SimpleType::FixedPrecision(s); break; },
658            Token::Binary(b) => { attr_type = SimpleType::Binary(b); break; },
659            Token::StringVal(s) => { enum_or_msg_str = Some(s); break; }
660            Token::OneOf => {
661                oneof_infos = match parse_oneof(lexer, parent_name.clone(), specific_comment.clone(),
662                                                is_repeated_and_size.clone(), is_optional.clone()) {
663                    Ok(oo) => Some(oo),
664                    Err(s) => { return Err(s); }
665                };
666                break;
667            }
668            _ => { return Err((format!("Error: Expected attribute type or modifier (got {ctoken:?}) when parsing msg or oneof '{parent_name}'")
669                                   .to_owned(), lexer.span())); }
670        }
671        if let Some(token) = lexer.next() {
672            match token {
673                Ok(t) => ctoken = t,
674                Err(_) => { return Err((format!("Error: Unexpected text found for msg '{parent_name}'.").to_owned(), lexer.span())); }
675            }
676        } else {
677            return Err(("Unexpected end of file".to_string(), lexer.span()));
678        }
679    }
680
681    let mut name= "".to_owned();
682    if oneof_infos.is_none() {
683        name = parse_one_token_with_arg!(
684            Token::StringVal, lexer, Some(format!("Error: Expected attribute name for msg '{parent_name}' (type: {attr_type:?}/{enum_or_msg_str:?})")))?.unwrap();
685
686        parse_one_token!(Token::SemiColon, lexer, Some(format!(
687            "Error: Expected semicolon to end line of attribute '{name}' of msg or oneof '{parent_name}'")))?.unwrap();
688    }
689    let num_of_set_types_or_opts = vec![(attr_type != SimpleType::NoTypeSetYet), enum_or_msg_str.is_some(), oneof_infos.is_some()]
690        .iter().map(|&x| if x { 1_u8 } else { 0_u8 }).sum::<u8>();
691    if num_of_set_types_or_opts > 1 {
692        let mut span = lexer_span_start.clone();
693        span.end = lexer.span().end;
694        return Err(("Error: Attribute contains inconsistent optional, simple types and messages or Enums".to_string(), span));
695    }
696
697    if let Some(oo) = oneof_infos {
698        Ok(oo)
699    }
700    else if let Some(t) = enum_or_msg_str {
701        Ok(Attribute{name, comment: specific_comment, is_repeated_and_size, is_optional,
702            specific_details: AttributeDetails::AttributeEnumOrMsg(t)})
703    }
704    else {
705        Ok(Attribute{name, comment: specific_comment, is_repeated_and_size, is_optional,
706            specific_details: AttributeDetails::AttributeSimple(attr_type)})
707    }
708}
709
710pub fn parse_oneof(lexer: &mut Lexer<'_, Token>, parent_name: String, comment: Option<String>,
711                   is_repeated_and_size: Option<DynOrFixedType>, is_optional: bool) -> Result<Attribute> {
712    let oo_name = parse_one_token_with_arg!(
713            Token::StringVal, lexer, Some(format!("Error: Expected name for oneof in parent '{parent_name}'")))?.unwrap();
714
715    let bit_size = match parse_one_token_with_arg!(Token::EnumDynSize, lexer, Some("Expected oneof properties for dyn size, e.g. (4)."))? {
716        Ok(s) => s, Err(s) => { return Err(("Code should not be reached".into(), s)); }
717    };
718
719    parse_one_token!(Token::CBraceOpen, lexer, Some("Error: Expected open curly bracket to enclose oneof elements"))?.unwrap();
720
721    let mut oo_attribs = Vec::new();
722    loop {
723        if let Some(token) = lexer.next() {
724            match token {
725                Ok(Token::CBraceClose) => break,
726                Ok(last_token) => {
727                    match parse_attribute(last_token, lexer, oo_name.clone(), true) {
728                        Ok(o) => oo_attribs.push(o),
729                        Err(s) => return Err(s),
730                    }
731                }
732                Err(_) => { return Err((format!("Error: Unexpected text when decoding oneof ({token:?})").to_owned(), lexer.span())); },
733            }
734        }
735    }
736    Ok(Attribute{name: oo_name.clone(), comment, is_repeated_and_size, is_optional,
737        specific_details: AttributeDetails::AttributeOneOf(OneOfInfo{
738            name: format!("OO_{}_{}", parent_name.to_pascal_case(), oo_name.to_pascal_case()),
739            dyn_bits: bit_size, attributes: oo_attribs})})
740}
741
742pub fn parse_enum(lexer: &mut Lexer<'_, Token>, comment: Option<String>) -> Result<Value> {
743    let name = match parse_one_token_with_arg!(Token::StringVal, lexer, Some("Expected msg name but received."))? {
744        Ok(s) => s, Err(s) => { return Err(("Code should not be reached".into(), s)); }
745    };
746
747    let bit_size = match parse_one_token_with_arg!(Token::EnumDynSize, lexer, Some("Expected enum properties for dyn size, e.g. (4)."))? {
748        Ok(s) => s, Err(s) => { return Err(("Code should not be reached".into(), s)); }
749    };
750
751    // let version_info = if(lexer.extras == 0) {
752    //     if let Some(token) = lexer.next() {
753    //         match token {
754    //             Ok(Token::MsgVersionToken(v)) => VersionInfo::Version(v),
755    //             Ok(Token::MsgBaseInfoToken(v)) => VersionInfo::BaseWithAllowedVersion(v),
756    //             Ok(_) => { return Err((format!("Unexpected token {:?} for enum '{}' when expecting version info", token, name)
757    //                                        .to_owned(), lexer.span())); }
758    //             Err(_) => { return Err((format!("Error: Syntax error for enum '{}'", name).to_owned(), lexer.span())); }
759    //         }
760    //     } else { return Err(("Unexpectedly did not find version information".to_owned(), lexer.span())); }
761    // }
762    // else { VersionInfo::Version(lexer.extras) };
763
764    parse_one_token!(Token::CBraceOpen, lexer, Some(format!("Expected open curly bracket for enum '{name}'")))?.unwrap();
765
766    let mut values = Vec::new();
767    let (mut value_found, mut is_default) = (false, false);
768    let mut default_val = None;
769    loop {
770        if let Some(token) = lexer.next() {
771            match token {
772                Ok(Token::CBraceClose) => break,
773                Ok(Token::StringVal(s)) => {
774                    values.push(s.clone()); value_found=true;
775                    if is_default { default_val = Some(s); }
776                    is_default = false;
777                },
778                Ok(Token::Comma) => {
779                    if !value_found { return Err(("Error: found comma but no enum value.".to_string(), lexer.span())) }
780                    value_found=false },
781                Ok(Token::Comment) => (),
782                Ok(Token::Star) => {
783                    if default_val.is_some() || value_found {
784                        return Err(("Error: found default value marker (*) but default already set or marker not preceding value.".to_string(), lexer.span()))}
785                    is_default = true;
786                }
787                _ => { return Err((format!("Error: Unexpected text found for enum '{name}'."), lexer.span())) },
788            }
789        } else { return Err(("Unexpected end of file".into(), lexer.span())); }
790    }
791    if default_val.is_none() { return Err(("Error: missing default value marker.".to_string(), lexer.span())); }
792
793    Ok(Value::Enum(Enum{name, comment, bit_size, values, default: default_val.unwrap() }))
794}
795
796
797/*pub fn validate_bitis(parsed_bitis: &Vec<Value>) -> Option<String> {
798    let enum_types = parsed_bitis.iter().filter_map(|x|
799        match x { Value::Enum(ev) => Some(ev.name.clone()), _ => None }).collect::<Vec<String>>();
800    let msg_types = parsed_bitis.iter().filter_map(|x|
801        match x { Value::Message(msg) => Some(msg.name.clone()), _ => None }).collect::<Vec<String>>();
802
803    // ***
804    if let Some (err_str) = parsed_bitis.iter().find_map(|s| match s {
805        Value::Message(msg) => {
806            msg.attributes.iter().find_map(|a| match a.specific_details.clone() {
807                AttributeDetails::AttributeEnumOrMsg(eon) => {
808                    if !enum_types.contains(&eon) && !msg_types.contains(&eon) {
809                        Some(format!("Type or enum '{eon}' unknown"))
810                    }
811                    else { None }
812                },
813                _ => None
814            })
815        },
816        _ => None,
817    }) { return Some(err_str); };
818
819    // *** check msg versions
820    let msgs_with_version: Vec<_> = parsed_bitis.iter().filter_map(|s| match s {
821        Value::Message(msg) => {
822            Some(match msg.version {
823                MsgVersion::Fixed => format!("{}_fixed", msg.name),
824                // MsgVersion::VersionedMsg => format!("{}_versioned", msg.name),
825                // MsgVersion::Base => format!("{}_base", msg.name),
826                MsgVersion::Versioned(v) => format!("{}_v{}", msg.name, v)
827            })
828        },
829        _ => None,
830    }).collect();
831    match (1..msgs_with_version.len()).into_iter().find_map(|i| {
832        let s = &msgs_with_version[i - 1];
833        if msgs_with_version[i..].contains(s) { Some(s.clone()) } else { None }
834    })
835    {
836        Some(msg) => return Some(format!("Conflicting versions of {}.", msg)),
837        None => ()
838    };
839
840    let fixed_msgs: Vec<_> = parsed_bitis.iter().filter_map(|s| match s {
841        Value::Message(msg) => {
842            match msg.version.clone() {
843                MsgVersion::Fixed => Some(msg.name.clone()), _ => None }
844        }, _ => None,
845    }).collect();
846    if let Some (err_str) = parsed_bitis.iter().find_map(|s| match s {
847        Value::Message(msg) => {
848            match msg.version.clone() {
849                MsgVersion::Fixed => None,
850                _ => {
851                    if fixed_msgs.contains(&msg.name) {
852                        Some(format!("Multiple conflicting versions of {} (fixed and version).", msg.name))
853                    }
854                    else { None }
855                }
856            }
857        }, _ => None,
858    }) { return Some(err_str); };
859
860    // ***
861    // Check that only attributes were added
862    // parsed_bitis.iter().for_each(|s| match s {
863    //     Value::Message(msg) => {
864    //
865    //     },
866    //     Value::Enum(eon) => {
867    //
868    //     }
869    // })
870
871    None
872}
873*/
874// Struct that collects all bitis information
875#[derive(Debug, Clone)]
876pub struct Dependencies {
877    pub in_deps: Vec<String>,
878    pub out_deps: Vec<String>,
879}
880#[derive(Debug, Clone)]
881pub struct BitisProcessed {
882    pub max_version_number: u16,
883    pub msgs: Vec<Message>,
884    pub enums: Vec<Enum>,
885    pub oo_enums: Vec<(String, OneOfInfo)>,
886}
887
888/// This function prepares message and enums for rendering
889pub fn process_and_validate_bitis(parsed_bitis: &Vec<Value>) -> BitisProcessed {
890    /*let (processed_msgs, max_msg_version_number) = {
891        let msgs: Vec<_> = parsed_bitis.iter().filter_map(|v| {
892            match v { Value::Message(msg) => Some(msg.clone()), _ => None }
893        }).collect();
894
895        let max_version_number: u16 = msgs.iter().fold(0_u16, |cur_max, v| {
896            std::cmp::max(cur_max, match v.version_info.clone()
897            { VersionInfo::BaseWithAllowedVersion(_) => 0, VersionInfo::Version(v) => v })
898        });
899        println!("Max version number for msgs found: {}", max_version_number);
900
901        // ***
902        // sort msgs per versions
903        let msgs_per_version: HashMap<u16, HashMap<String, Message>> = (0..=max_version_number).map(|cver| {
904            let msgs: HashMap<String, Message> = msgs.iter().filter_map(|cmsg| {
905                match &cmsg.version_info {
906                    VersionInfo::BaseWithAllowedVersion(_) if cver==0  => Some(cmsg.clone()),
907                    VersionInfo::Version(msg_ver) => {
908                        if *msg_ver == 0 {
909                            println!("Error: Message '{}' has version zero which is not allowed", cmsg.name);
910                            abort();
911                        } else if *msg_ver == cver { Some(cmsg.clone()) }
912                        else { None }
913                    }, _ => None
914                } }
915            ).map(|msg| { (msg.name.clone(), msg) }).collect();
916            (cver, msgs)
917        }).collect();
918
919        // todo check that messages as attributes are used with the correct version
920
921        // todo check that messages have the same allowed_to_be_used_starting_with_version for all versions
922
923        // todo check that attributes for different versions are unique
924
925        // ***
926        let msg_names_and_ver_type: HashMap<_, _> = msgs.iter().map(|v| {
927            (v.name.clone(), v.version_info.clone()) }).collect();
928
929        let msg_version_to_use_per_version: HashMap<String, HashMap<u16, u16>> = {
930            let mut temp_msg_last_version: HashMap<String, u16> =
931                msgs.iter().enumerate().map(|(x1, x2)| { (x2.name.clone(), x1.clone() as u16) }).collect();
932
933            msgs.iter().map(|v| {
934                (1..=max_version_number).map(|cver| {
935
936                }
937            }
938        }
939
940
941        // let msg_base_with_version: Vec<_> = msgs.iter().filter_map(|msg| {
942        // });
943
944        let msgs_processed: Vec<Vec<Message>> = msgs_per_version.iter()
945            .map(|(&cver, cver_msgs) | {
946                let mut msgs_for_version: HashMap<String, Message> = HashMap::new();
947
948                println!("Processing V{} msgs: {:?}", cver, cver_msgs);
949                if cver == 0 {
950                    msg_names_and_ver_type.iter().for_each(|(mi_name, _)| {
951                        if !cver_msgs.contains_key(mi_name) {
952                            println!("Error: Message '{}' not found in base version. All messages must be declared in base.", mi_name);
953                            abort();
954                        }
955                    });
956                }
957                else {
958                    // add missing msg definitions for each version
959                    let new_msgs: HashMap<_, _> = msg_names_and_ver_type.iter().filter_map(|(mi_name, ver_type)| {
960                        // do it only for versioned msgs
961                        if let VersionInfo::BaseWithAllowedVersion(_) = ver_type { None } else {
962                            // check if
963                            if !cver_msgs.contains_key(mi_name) {
964                                println!("Generating empty version msg '{mi_name}'");
965
966                                let base_ver_msg = msgs_per_version.get(&0).unwrap().get(mi_name).unwrap();
967
968                                let name = format!("{}_DataV{}", mi_name, cver);
969                                Some((name.clone(), Message { name, attributes: vec![], comment: Some("Automatically generated empty msg".to_string()),
970                                    ..base_ver_msg.clone() }))
971                            } else { None }
972                        }
973                    }).collect();
974                    msgs_for_version.extend(new_msgs);
975                }
976
977                cver_msgs.iter().for_each(|(_, cmsg)| {
978                    if let VersionInfo::Version(msg_ver) = &cmsg.version_info {
979                        match cver {
980                            cver_iter if cver_iter >= *msg_ver => {
981                                let cname = format!("{}_DataV{}", cmsg.name, cver_iter);
982                                msgs_for_version.insert(cname.clone(), Message { name: cname, ..cmsg.clone() });
983                            },
984                            _ => ()
985                        };
986                    }
987                    else {
988                        let processed_attributes: Vec<_> = cmsg.attributes.iter().map(|attr| {
989                            match &attr.specific_details {
990                                AttributeDetails::AttributeSimple(_) => attr.clone(),
991                                AttributeDetails::AttributeEnumOrMsg(at) => {
992                                    Attribute{specific_details: AttributeEnumOrMsg(format!("{}_V{}", at, cver)), ..attr.clone()}
993                                }
994                                AttributeDetails::AttributeOneOf(_) => {
995                                    Attribute{name: format!("{}_TODO", attr.name), ..attr.clone()}
996                                }
997                            }
998                        }).collect();
999                        let cname = format!("{}_BaseV{}", cmsg.name, cver);
1000                        msgs_for_version.insert(cname.clone(), Message { name: cname, attributes: processed_attributes, ..cmsg.clone() });
1001                    }
1002                });
1003                msgs_for_version.values().cloned().collect::<Vec<Message>>()
1004            }).collect();
1005
1006        let mut msg_processed_concat: Vec<_> = msgs_processed.concat();
1007        msg_processed_concat.sort_by_key(|msg| { msg.name.to_lowercase() });
1008
1009
1010        (msg_processed_concat, max_version_number)
1011    };*/
1012
1013    //
1014    let msgs: Vec<_> = parsed_bitis.iter().filter_map(|v| {
1015        match v { Value::Message(msg) => Some(msg.clone()), _ => None }
1016    }).collect();
1017    let enums: Vec<_> = parsed_bitis.iter().filter_map(|v| {
1018        match v { Value::Enum(enm) => Some(enm.clone()), _ => None }
1019    }).collect();
1020
1021    fn get_oneofs(msg_name: String, attrs: &Vec<Attribute>) -> Option<Vec<(String, OneOfInfo)>> {
1022        let direct_oos = attrs.iter().filter_map(|attr| {
1023            match &attr.specific_details {
1024                AttributeDetails::AttributeOneOf(oo) => Some(vec![(msg_name.clone(), oo.clone())]),
1025                _ => None
1026            }
1027        }).collect::<Vec<Vec<(String, OneOfInfo)>>>().concat();
1028
1029        let inner_oos = direct_oos.iter().filter_map(|(_, doo)| {
1030            get_oneofs(msg_name.clone(), &doo.attributes)
1031        }).collect::<Vec<Vec<_>>>().concat();
1032
1033        let all_oos = vec![direct_oos, inner_oos].concat();
1034        if all_oos.len() == 0 { None }
1035        else { Some(all_oos) }
1036    }
1037    let oo_enums: Vec<_> = msgs.iter().filter_map(|msg| {
1038        get_oneofs(msg.name.clone(), &msg.attributes)
1039    }).collect::<Vec<_>>().concat();
1040
1041    // println!("\noo_enums:\n{:?}\n", oo_enums);
1042
1043    { // Test msgs and enum
1044        let msg_names = msgs.iter().map(|msg| &msg.name).collect::<Vec<_>>();
1045        msg_names.iter().for_each(|name| {
1046            // println!("name: {}", name);
1047            if msg_names.iter().filter(|cname| **cname == *name).count() > 1 {
1048                println!("Error: Multiple instances of msg '{}' found.", name);
1049                abort()
1050            }
1051        });
1052        let enum_names = enums.iter().map(|enm| &enm.name).collect::<Vec<_>>();
1053        enum_names.iter().for_each(|name| {
1054            if enum_names.iter().filter(|cname| **cname == *name).count() > 1 {
1055                println!("Error: Multiple instances of enum '{}' found.", name); abort()
1056            }
1057        });
1058
1059        // check that all attributes are defined
1060        //...
1061    }
1062
1063
1064    BitisProcessed { max_version_number: 0, msgs, enums, oo_enums}
1065}
1066
1067pub fn dependencies_process(jd: JinjaData) -> Vec<String>{
1068    let mut dependencies = HashMap::new();
1069
1070    for msgs in jd.msgs.clone() {
1071        dependencies.insert(
1072            msgs.name.clone(), Dependencies{in_deps: vec![], out_deps: vec![]});
1073    }
1074    for enm in jd.enums {
1075        dependencies.insert(
1076            enm.name.clone(), Dependencies{in_deps: vec![], out_deps: vec![]});
1077    }
1078    for (_, oos) in jd.oos.clone() {
1079        dependencies.insert(
1080            oos.name.clone(), Dependencies{in_deps: vec![], out_deps: vec![]});
1081    }
1082
1083    // msgs
1084    for msgs in jd.msgs {
1085        for attr in msgs.attributes {
1086            if attr.is_enum || attr.is_msg || attr.is_oo {
1087                dependencies.get_mut(&attr.rust_type_str).unwrap().out_deps.push(msgs.name.clone());
1088                dependencies.get_mut(&msgs.name).unwrap().in_deps.push(attr.rust_type_str.clone());
1089            }
1090        }
1091    }
1092    for (_, msgs) in jd.oos {
1093        for attr in msgs.attributes {
1094            if attr.is_enum || attr.is_msg || attr.is_oo {
1095                dependencies.get_mut(&attr.rust_type_str).unwrap().out_deps.push(msgs.name.clone());
1096                dependencies.get_mut(&msgs.name).unwrap().in_deps.push(attr.rust_type_str.clone());
1097            }
1098        }
1099    }
1100    println!("{:#?}", dependencies.clone());
1101
1102    let mut object_order = Vec::new();
1103    while dependencies.len() > 0 {
1104        let mut cobjs: Vec<_> = dependencies.clone().iter().filter_map(|(obj_name, deps)| {
1105            if deps.in_deps.len() == 0 { Some(obj_name.clone()) }
1106            else { None }
1107        }).collect();
1108
1109        for co in cobjs.clone() {
1110            dependencies.remove(&co);
1111        }
1112        for co in cobjs.clone() {
1113            for (_, deps) in &mut dependencies {
1114                deps.in_deps.retain(|x| *x != co);
1115            }
1116        }
1117        object_order.append(&mut cobjs);
1118    }
1119    println!("{:?}", object_order);
1120
1121    object_order
1122}
1123// ***************************************************
1124
1125#[cfg(test)]
1126mod bitis_semantic {
1127    use rstest::rstest;
1128    use super::*;
1129
1130    #[rstest]
1131    fn msg_empty_msg() {
1132        let test_empty_msg = "msg Lala { }";
1133
1134        let mut lexer = Token::lexer(test_empty_msg);
1135        lexer.extras = 0;
1136
1137        let parsed_bitis = parse_root(&mut lexer);
1138        if let Err(s) = parsed_bitis.clone() {
1139            panic!("Error: {} ('{}' ,span: {:?})", s.0, &test_empty_msg[s.1.clone()], s.1);
1140        }
1141        assert_eq!(parsed_bitis.is_ok(), true);
1142
1143        let parsed_bitis = parsed_bitis.unwrap();
1144        assert_eq!(parsed_bitis.len(), 1);
1145
1146        assert!(if let Value::Message(_) = parsed_bitis[0].clone() { true } else { false });
1147
1148        if let Value::Message(msg) = parsed_bitis[0].clone() {
1149            assert_eq!(msg.name, "Lala".to_string());
1150        }
1151
1152        // let validate_result = validate_bitis(&parsed_bitis);
1153        // println!("validate_result: {:?}", validate_result);
1154
1155        let process_result = process_and_validate_bitis(&parsed_bitis);
1156        println!("process_result {:?}", process_result);
1157
1158        assert_eq!(process_result.msgs.len(), 1);
1159        assert_eq!(process_result.enums.len(), 0);
1160    }
1161
1162    #[rstest]
1163    fn msg_simple_msg() {
1164        let test_empty_msg = "msg Lala { uint_7 a1; }";
1165
1166        let mut lexer = Token::lexer(test_empty_msg);
1167        lexer.extras = 0;
1168
1169        let parsed_bitis = parse_root(&mut lexer);
1170        if let Err(s) = parsed_bitis.clone() {
1171            panic!("Error: {} ('{}' ,span: {:?})", s.0, &test_empty_msg[s.1.clone()], s.1);
1172        }
1173        assert_eq!(parsed_bitis.is_ok(), true);
1174
1175        let parsed_bitis = parsed_bitis.unwrap();
1176        assert_eq!(parsed_bitis.len(), 1);
1177
1178        if let Value::Message(msg) = parsed_bitis[0].clone() {
1179            assert_eq!(msg.attributes.len(), 1);
1180            assert_eq!(msg.attributes[0].name, "a1".to_string());
1181            if let AttributeDetails::AttributeSimple(s) = msg.attributes[0].specific_details.clone() {
1182                assert_eq!(s, SimpleType::UIntFixed(7));
1183            }
1184            else { assert!(false, "Attribute type must be AttributeSimple."); }
1185        }
1186        else { assert!(false, "Value must be a message."); }
1187    }
1188
1189    #[rstest]
1190    fn msg_simple_enum() {
1191        let test_empty_msg = "enum Lala(4) { one, two }";
1192
1193        let mut lexer = Token::lexer(test_empty_msg);
1194        lexer.extras = 0;
1195
1196        let parsed_bitis = parse_root(&mut lexer);
1197        if let Err(s) = parsed_bitis.clone() {
1198            panic!("Error: {} ('{}' ,span: {:?})", s.0, &test_empty_msg[s.1.clone()], s.1);
1199        }
1200        assert_eq!(parsed_bitis.is_ok(), true);
1201
1202        let parsed_bitis = parsed_bitis.unwrap();
1203        assert_eq!(parsed_bitis.len(), 1);
1204
1205        if let Value::Enum(enm) = parsed_bitis[0].clone() {
1206            assert_eq!(enm.values.len(), 2);
1207            assert_eq!(enm.values[0], "one".to_string());
1208            assert_eq!(enm.values[1], "two".to_string());
1209        }
1210        else { assert!(false, "Value must be a message."); }
1211    }
1212
1213
1214    /*#[rstest]
1215        #[case::float("float", SimpleType::Float)]
1216        #[case::uint_12("uint_12", SimpleType::UIntFixed(12))]
1217        #[case::uint_32d4("uint_32d4", SimpleType::UIntDyn((32,4)))]
1218        #[case::bool("bool", SimpleType::Bool)]
1219        fn msg_various_attribute_types(#[case] attr_type_str: String, #[case] attr_type: SimpleType) {
1220            let test_msg = format!("msg Lala [fixed] {{ {attr_type_str} attr; }}");
1221
1222            let mut lexer = Token::lexer(test_msg.as_str());
1223            lexer.extras = 0;
1224
1225            let parsed_bitis = parse_root(&mut lexer);
1226            assert_eq!(parsed_bitis.is_ok(), true);
1227
1228            let parsed_bitis = parsed_bitis.unwrap();
1229            assert_eq!(parsed_bitis.len(), 1);
1230
1231            assert!(if let Value::Message(_) = parsed_bitis[0].clone() { true } else { false });
1232
1233            if let Value::Message(msg) = parsed_bitis[0].clone() {
1234                assert_eq!(msg.name, "Lala".to_string());
1235
1236                assert_eq!(msg.attributes.len(), 1);
1237                assert_eq!(msg.attributes[0].name, "attr".to_string());
1238
1239                assert!(if let AttributeDetails::AttributeSimple(_) = msg.attributes[0].specific_details.clone() { true } else { false });
1240
1241                if let AttributeDetails::AttributeSimple(at) = msg.attributes[0].specific_details.clone() {
1242                    assert_eq!(at, attr_type);
1243                }
1244            }
1245
1246            let validate_result = validate_bitis(&parsed_bitis);
1247            println!("validate_result: {:?}", validate_result);
1248            assert!(validate_result.is_none());
1249        }*/
1250}
1251
1252#[cfg(test)]
1253mod bitis_generate_rust {
1254    use rstest::rstest;
1255    use super::*;
1256
1257    const HEADER: &str = "use bitis_lib::*;\n\n";
1258    const ENUMS_HEADER: &str = "// Enums\n";
1259    const OO_HEADER: &str = "// Enums for oneof\n";
1260    const MSG_HEADER: &str = "// Messages\n";
1261    const PER_ENUM_HEADER: &str = "#[derive(BiserdiEnum, Debug, Clone, PartialEq)]\n#[biserdi_enum_id_dynbits(3)]\n#[allow(nonstandard_style)]\n";
1262    const PER_OO_HEADER: &str = "#[derive(BiserdiOneOf, Debug, Clone, PartialEq)]\n#[biserdi_enum_id_dynbits(3)]\n#[allow(nonstandard_style)]\n";
1263    const PER_MSG_HEADER: &str = "#[derive(BiserdiMsg, Debug, Clone, PartialEq)]\n#[allow(nonstandard_style)]\n";
1264
1265    #[rstest]
1266    fn msg_empty_msg() {
1267        let test_empty_msg = "msg Lala { }";
1268
1269        let mut lexer = Token::lexer(test_empty_msg);
1270        lexer.extras = 0;
1271
1272        let parsed_bitis = parse_root(&mut lexer);
1273        if let Err(s) = parsed_bitis.clone() {
1274            panic!("Error: {} ('{}' ,span: {:?})", s.0, &test_empty_msg[s.1.clone()], s.1);
1275        }
1276        assert_eq!(parsed_bitis.is_ok(), true);
1277
1278        let parsed_bitis = parsed_bitis.unwrap();
1279        assert_eq!(parsed_bitis.len(), 1);
1280
1281        let processed_bitis = process_and_validate_bitis(&parsed_bitis);
1282        let rdo = RustDataObjects{ d: JinjaData{
1283            enums: processed_bitis.enums,
1284            msgs: to_rust_messages(&processed_bitis.msgs),
1285            oos: to_rust_oneofs(&processed_bitis.oo_enums, &processed_bitis.msgs) } };
1286
1287        let rendered = rdo.render().unwrap();
1288        let lala_empty = "pub struct Lala {\n}\n";
1289        assert_eq!(rendered, (HEADER.to_owned() + ENUMS_HEADER + "\n\n" + OO_HEADER + "\n\n"  +
1290            MSG_HEADER + PER_MSG_HEADER +lala_empty).to_string());
1291    }
1292
1293    #[rstest]
1294    fn msg_simple_msg() {
1295        let test_empty_msg = "//| comment for Lala\nmsg Lala { int_5 a1; repeated_fixed_4 bool bool_array; }";
1296        println!("Input code:\n{}", test_empty_msg);
1297
1298        let mut lexer = Token::lexer(test_empty_msg);
1299        lexer.extras = 0;
1300
1301        let parsed_bitis = parse_root(&mut lexer);
1302        if let Err(s) = parsed_bitis.clone() {
1303            panic!("Error: {} ('{}' ,span: {:?})", s.0, &test_empty_msg[s.1.clone()], s.1);
1304        }
1305        assert_eq!(parsed_bitis.is_ok(), true);
1306
1307        let parsed_bitis = parsed_bitis.unwrap();
1308        assert_eq!(parsed_bitis.len(), 1);
1309
1310        let processed_bitis = process_and_validate_bitis(&parsed_bitis);
1311        let rdo = RustDataObjects{ d: JinjaData{
1312            enums: processed_bitis.enums, msgs: to_rust_messages(&processed_bitis.msgs),
1313            oos: to_rust_oneofs(&processed_bitis.oo_enums, &processed_bitis.msgs) } };
1314
1315        let rendered = rdo.render().unwrap();
1316        let lala_commment = "/// comment for Lala\n";
1317        let lala_empty = "pub struct Lala {\n  pub a1: VarWithGivenBitSize<i8, 5>,\n  pub bool_array: FixedArray<bool,4>,\n}\n";
1318        println!("rendered:\n{}",rendered);
1319        assert_eq!(rendered, (HEADER.to_owned() + ENUMS_HEADER + "\n\n" + OO_HEADER + "\n\n" +
1320            MSG_HEADER + lala_commment + PER_MSG_HEADER +lala_empty).to_string());
1321    }
1322
1323    #[rstest]
1324    fn msg_simple_enum() {
1325        let test_enum_msg = "//| comment for Numbers\nenum Numbers(3) {\n  // Comment for One\n  One,\n  Two,\n  Three\n}";
1326        println!("Input code:\n{}", test_enum_msg);
1327
1328        let mut lexer = Token::lexer(test_enum_msg);
1329        lexer.extras = 0;
1330
1331        let parsed_bitis = parse_root(&mut lexer);
1332        if let Err(s) = parsed_bitis.clone() {
1333            panic!("Error: {} ('{}' ,span: {:?})", s.0, &test_enum_msg[s.1.clone()], s.1);
1334        }
1335        assert_eq!(parsed_bitis.is_ok(), true);
1336
1337        let parsed_bitis = parsed_bitis.unwrap();
1338        assert_eq!(parsed_bitis.len(), 1);
1339
1340        let processed_bitis = process_and_validate_bitis(&parsed_bitis);
1341        let rdo = RustDataObjects{ d: JinjaData{ enums: processed_bitis.enums,
1342            msgs: to_rust_messages(&processed_bitis.msgs),
1343            oos: to_rust_oneofs(&processed_bitis.oo_enums, &processed_bitis.msgs) } };
1344
1345        let rendered = rdo.render().unwrap();
1346        let lala_commment = "/// comment for Numbers\n";
1347        let lala_enum = "pub enum Numbers {\n  One,\n  Two,\n  Three,\n}\n\n";
1348        println!("*rendered:\n{}",rendered);
1349        assert_eq!(rendered, (HEADER.to_owned() + ENUMS_HEADER + lala_commment + PER_ENUM_HEADER + lala_enum + OO_HEADER +
1350            "\n\n" + MSG_HEADER ).to_string());
1351    }
1352
1353    #[rstest]
1354    fn msg_simple_oneof() {
1355        let test_enum_msg = "//| comment for Oneof\nmsg TestOO {\n  oneof oo_li(3) { uint_3 test1; float test2; }\n  bool b1;\n}";
1356        println!("Input code:\n{}", test_enum_msg);
1357
1358        let mut lexer = Token::lexer(test_enum_msg);
1359        lexer.extras = 0;
1360
1361        let parsed_bitis = parse_root(&mut lexer);
1362        if let Err(s) = parsed_bitis.clone() {
1363            panic!("Error: {} ('{}' ,span: {:?})", s.0, &test_enum_msg[s.1.clone()], s.1);
1364        }
1365        assert_eq!(parsed_bitis.is_ok(), true);
1366
1367        let parsed_bitis = parsed_bitis.unwrap();
1368        assert_eq!(parsed_bitis.len(), 1);
1369
1370        let processed_bitis = process_and_validate_bitis(&parsed_bitis);
1371        let rdo = RustDataObjects{ d: JinjaData{ enums: processed_bitis.enums,
1372            msgs: to_rust_messages(&processed_bitis.msgs),
1373            oos: to_rust_oneofs(&processed_bitis.oo_enums, &processed_bitis.msgs) } };
1374
1375        let rendered = rdo.render().unwrap();
1376        let testoo_commment = "/// comment for Oneof\n";
1377        let testoo_enum = "pub enum OO_TestOo_OoLi {\n  Test1(VarWithGivenBitSize<u8, 3>),\n  Test2(f32),\n}\n\n";
1378        let testoo_msg = "pub struct TestOo {\n  pub oo_li: OO_TestOo_OoLi,\n  pub b1: bool,\n}\n";
1379        println!("*rendered:\n{}",rendered);
1380        assert_eq!(rendered, (HEADER.to_owned() + ENUMS_HEADER + "\n\n" + OO_HEADER + PER_OO_HEADER
1381            + testoo_enum + MSG_HEADER + testoo_commment + PER_MSG_HEADER + testoo_msg).to_string());
1382    }
1383}
1384
1385#[cfg(test)]
1386mod bitis_compile {
1387    use std::fs;
1388    use std::path::Path;
1389    use rstest::rstest;
1390    use super::*;
1391
1392    fn compile(content: &str) -> BitisProcessed {
1393        let mut lexer = Token::lexer(content);
1394        lexer.extras = 0;
1395        println!("*** content:\n{}", content);
1396        let bitis_parsed = match parse_root(&mut lexer) {
1397            Ok(v) => v,
1398            Err(e) => {
1399                let (err_str, err_span) = e.clone();
1400                let content_err = &content[err_span];
1401                println!("Error: {}\n  -> Source: '{}'", err_str, content_err);
1402                abort()
1403            }
1404        };
1405        println!("** content:\n{:?}", bitis_parsed);
1406        process_and_validate_bitis(&bitis_parsed)
1407    }
1408    fn render(d: JinjaData) {
1409        let rdo = RustDataObjects{ d: d.clone() };
1410        let rendered_rust = rdo.render().unwrap();
1411        println!("*** rendered DO:\n{}", rendered_rust);
1412        fs::write(Path::new("./test_data/test_py/bitis/src/messages_test.rs"), rendered_rust).expect("Unable to write file");
1413
1414        let rdo = RustPyDataObjects{ d: d.clone() };
1415        let rendered_rust = rdo.render().unwrap();
1416        println!("*** rendered PyDO:\n{}", rendered_rust);
1417        fs::write(Path::new("./test_data/test_py/bitis/src/pyrust_test.rs"), rendered_rust).expect("Unable to write file");
1418
1419        let rdo = RustPyLib{ d: d.clone(), lib_name: "bitis_msgs".into() };
1420        let rendered_rust = rdo.render().unwrap();
1421        println!("*** rendered pyLib:\n{}", rendered_rust);
1422        fs::write(Path::new("./test_data/test_py/bitis/src/lib_test.rs"), rendered_rust).expect("Unable to write file");
1423
1424        let rdo = PyTypeHints{ d };
1425        let rendered_rust = rdo.render().unwrap();
1426        println!("*** rendered py_type_hints:\n{}", rendered_rust);
1427        fs::write(Path::new("./test_data/test_py/bitis/bitis_msgs/bitis_msgs.pyi"), rendered_rust).expect("Unable to write file");
1428    }
1429
1430    #[rstest]
1431    #[ignore]
1432    fn simple_rust_py() {
1433        let bitis_str = "msg ParamTestSimple { uint_4 param_1; bool param_2; }";
1434
1435        let bitis_processed_org = compile(bitis_str);
1436
1437        let bitis_processed = bitis_processed_org.clone();
1438        let d = JinjaData{
1439            enums: bitis_processed.enums,
1440            msgs: to_rust_messages(&bitis_processed.msgs),
1441            oos: to_rust_oneofs(&bitis_processed.oo_enums, &bitis_processed.msgs)
1442        };
1443        render(d);
1444    }
1445
1446    #[rstest]
1447    #[ignore]
1448    fn nested_rust_py() {
1449        let bitis_str = "msg Inner { uint_2 val; }\nmsg ParamTestWithInner { uint_4 param_1; bool param_2; Inner inner; }";
1450
1451        let bitis_processed_org = compile(bitis_str);
1452
1453        let bitis_processed = bitis_processed_org.clone();
1454
1455        let d = JinjaData{
1456            enums: bitis_processed.enums,
1457            msgs: to_rust_messages(&bitis_processed.msgs),
1458            oos: to_rust_oneofs(&bitis_processed.oo_enums, &bitis_processed.msgs)
1459        };
1460        render(d);
1461    }
1462    #[test]
1463    #[ignore]
1464    fn nested_and_enum_rust_py() {
1465        let bitis_str = [
1466            "enum Numbers(4) { one, two, three, four }\n/// Test comment for Inner\nmsg Inner { uint_3 val; Numbers num; }\n",
1467            "msg ParamTestWithInner { uint_4 param_1; bool param_2; Inner inner; } }"
1468        ].join("");
1469
1470        let bitis_processed_org = compile(bitis_str.as_str());
1471
1472        let bitis_processed = bitis_processed_org.clone();
1473
1474        let d = JinjaData{
1475            enums: bitis_processed.enums,
1476            msgs: to_rust_messages(&bitis_processed.msgs),
1477            oos: to_rust_oneofs(&bitis_processed.oo_enums, &bitis_processed.msgs)
1478        };
1479        render(d);
1480    }
1481    #[rstest]
1482    fn oneof_nested_and_enum_rust_py() {
1483        let bitis_str = [
1484            "//| Test comment for Enum\nenum Numbers(4) { one, two, three, four }\n\n//| Test comment for Inner\nmsg Inner { uint_3 val; Numbers num; }\n",
1485            "msg ParamTestWithInner { uint_4 param_1; bool param_2; oneof action(4) { Inner inner; uint_3 val; } }"
1486        ].join("");
1487
1488        let bitis_processed_org = compile(bitis_str.as_str());
1489
1490        let bitis_processed = bitis_processed_org.clone();
1491
1492        let d = JinjaData{
1493            enums: bitis_processed.enums,
1494            msgs: to_rust_messages(&bitis_processed.msgs),
1495            oos: to_rust_oneofs(&bitis_processed.oo_enums, &bitis_processed.msgs)
1496        };
1497        render(d);
1498    }
1499}
1500
1501#[cfg(test)]
1502mod bitis_serialization {
1503    // use std::fs;
1504    use rstest::rstest;
1505    use super::*;
1506
1507    //noinspection DuplicatedCode
1508    #[rstest]
1509    fn msg_simple_msg_compile() {
1510        let test_empty_msg = "msg Lala { repeated_fixed_10 bool data_bool; uint_4 data1_uint; uint_12 data2_uint; }";
1511
1512        let mut lexer = Token::lexer(test_empty_msg);
1513        lexer.extras = 0;
1514
1515        let parsed_bitis = parse_root(&mut lexer);
1516        assert_eq!(parsed_bitis.is_ok(), true);
1517
1518        let _parsed_bitis = parsed_bitis.unwrap();
1519
1520        // let rdo = RustDataObjects {
1521        //     enums: parsed_bitis.iter().filter_map(|x|
1522        //         match x {
1523        //             Value::Enum(ev) => Some((ev.name.clone(), ev.clone())),
1524        //             _ => None
1525        //         })
1526        //         .collect::<HashMap<_, _>>(),
1527        //     msgs: parsed_bitis.iter().filter_map(|x|
1528        //         match x {
1529        //             Value::Message(mv) => Some((mv.name.clone(), mv.clone())),
1530        //             _ => None
1531        //         })
1532        //         .collect::<HashMap<_, _>>(),
1533        // };
1534        //
1535        // let rendered = rdo.render().unwrap();
1536        //
1537        // let current_test_simple_code = String::from(std::str::from_utf8(&fs::read("test_data/test_simple_msg.rs")
1538        //     .expect("Unable to read test_simple_msg.rs file")).unwrap());
1539        // assert_eq!(current_test_simple_code, rendered);
1540        //
1541        // let validate_result = validate_bitis(&parsed_bitis);
1542        // println!("validate_result: {:?}", validate_result);
1543        // assert!(validate_result.is_none());
1544    }
1545}
1546
1547#[cfg(test)]
1548mod bitis_processing {
1549    use rstest::rstest;
1550    use crate::AttributeDetails::{AttributeEnumOrMsg, AttributeSimple};
1551    use super::*;
1552
1553    #[rstest]
1554    #[ignore]
1555    fn msg_base_and_v2() {
1556        let bitis_values = vec![
1557            Value::Message(Message{
1558                name: "TestMsg".to_string(),
1559                /*version_info: VersionInfo::BaseWithAllowedVersion(0),*/
1560                comment: Some("This is a test".to_string()),
1561                parent: None,
1562                attributes: vec![Attribute{name: "a1".to_string(), comment: None,
1563                    is_repeated_and_size: None, is_optional: false,
1564                    specific_details: AttributeSimple(SimpleType::UIntFixed(4)),
1565                }],
1566            }),
1567            Value::Message(Message{
1568                name: "TestMsg".to_string(),
1569                /*version_info: VersionInfo::Version(2),*/
1570                comment: Some("This is a test".to_string()),
1571                parent: None,
1572                attributes: vec![Attribute{name: "a2".to_string(), comment: None,
1573                    is_repeated_and_size: None, is_optional: false,
1574                    specific_details: AttributeSimple(SimpleType::UIntFixed(4)),
1575                }],
1576            })
1577        ];
1578        let pb = process_and_validate_bitis(&bitis_values);
1579
1580        assert_eq!(pb.max_version_number, 2);
1581        assert_eq!(pb.msgs.len(), 3);
1582
1583        assert_eq!(pb.msgs[0].name, "TestMsg_Base".to_string());
1584        assert_eq!(pb.msgs[1].name, "TestMsg_V1".to_string());
1585        assert_eq!(pb.msgs[2].name, "TestMsg_V2".to_string());
1586
1587        assert_eq!(pb.msgs[0].attributes.len(), 1);
1588        assert_eq!(pb.msgs[0].attributes.get(0).unwrap().name, "a1".to_string());
1589        assert_eq!(pb.msgs[1].attributes.len(), 0);
1590        assert_eq!(pb.msgs[2].attributes.len(), 1);
1591        assert_eq!(pb.msgs[2].attributes.get(0).unwrap().name, "a2".to_string());
1592    }
1593
1594    #[rstest]
1595    #[ignore]
1596    fn msg_base_and_v2_and_add_msg() {
1597        let bitis_values = vec![
1598            Value::Message(Message{
1599                name: "TestMsgInner".to_string(),
1600                /*version_info: VersionInfo::BaseWithAllowedVersion(0),*/
1601                comment: Some("This is a test2".to_string()),
1602                parent: None,
1603                attributes: vec![Attribute{name: "lala".to_string(), comment: None,
1604                    is_repeated_and_size: None, is_optional: false,
1605                    specific_details: AttributeSimple(SimpleType::UIntFixed(4)),
1606                }],
1607            }),
1608            Value::Message(Message{
1609                name: "TestMsgInner".to_string(),
1610                /*version_info: VersionInfo::Version(1),*/
1611                comment: Some("This is a test2".to_string()),
1612                parent: None,
1613                attributes: vec![
1614                    Attribute{name: "lala".to_string(), comment: None, is_repeated_and_size: None, is_optional: false,
1615                        specific_details: AttributeSimple(SimpleType::UIntFixed(4)),},
1616                    Attribute{name: "lala2".to_string(), comment: None, is_repeated_and_size: None, is_optional: false,
1617                        specific_details: AttributeSimple(SimpleType::UIntFixed(3)),},
1618                ],
1619            }),
1620            Value::Message(Message{
1621                name: "TestMsg".to_string(),
1622                /*version_info: VersionInfo::BaseWithAllowedVersion(0),*/
1623                comment: Some("This is a test".to_string()),
1624                parent: None,
1625                attributes: vec![
1626                    Attribute{ name: "a1".to_string(), comment: None, is_repeated_and_size: None, is_optional: false,
1627                        specific_details: AttributeSimple(SimpleType::UIntFixed(4)) },
1628                    Attribute{ name: "lala_use".to_string(), comment: None, is_repeated_and_size: None, is_optional: false,
1629                        specific_details: AttributeEnumOrMsg("TestMsgInner".to_string()) },
1630                ],
1631            }),
1632            Value::Message(Message{
1633                name: "TestMsg".to_string(),
1634                /*version_info: VersionInfo::Version(2),*/
1635                comment: Some("This isa test".to_string()),
1636                parent: None,
1637                attributes: vec![Attribute{name: "a2".to_string(), comment: None,
1638                    is_repeated_and_size: None, is_optional: false,
1639                    specific_details: AttributeSimple(SimpleType::UIntFixed(4)),
1640                }],
1641            }),
1642        ];
1643        let pb = process_and_validate_bitis(&bitis_values);
1644
1645        assert_eq!(pb.max_version_number, 2);
1646        assert_eq!(pb.msgs.len(), 4);
1647
1648/*        assert_eq!(pb.msgs[0].name, "TestMsg_Base".to_string());
1649        assert_eq!(pb.msgs[1].name, "TestMsg_V1".to_string());
1650        assert_eq!(pb.msgs[2].name, "TestMsg_V2".to_string());
1651        assert_eq!(pb.msgs[3].name, "TestMsgLala".to_string());
1652
1653        if let MsgVersion::Versioned(l) = pb.msgs[0].version { assert_eq!(l, 0); }
1654        assert_eq!(pb.msgs[0].attributes.len(), 1);
1655        assert_eq!(pb.msgs[0].attributes.get(0).unwrap().name, "a1".to_string());
1656        assert_eq!(pb.msgs[1].attributes.len(), 0);
1657        assert_eq!(pb.msgs[2].attributes.len(), 1);
1658        assert_eq!(pb.msgs[2].attributes.get(0).unwrap().name, "a2".to_string());
1659        if let MsgVersion::Fixed = pb.msgs[0].version { assert!(false) }
1660        assert_eq!(pb.msgs[3].attributes.len(), 1);
1661        assert_eq!(pb.msgs[3].attributes.get(0).unwrap().name, "lala".to_string());*/
1662    }
1663}
1664