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