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