pidl_core/
info.rs

1use std::{collections::BTreeMap, fmt::Display};
2
3use nom::{
4    bytes::complete::{tag, take_while_m_n}, character::complete::{alphanumeric1, multispace0}, multi::many0, sequence::delimited, IResult
5};
6
7use crate::{merge, parse_attr, Attr};
8#[derive(Default,Clone)]
9pub struct Info {
10    pub interfaces: BTreeMap<[u8; 32], InfoEntry>,
11}
12impl Info{
13    pub fn merge(self, x: Info) -> Info{
14        let mut m: BTreeMap<[u8;32],InfoEntry> = BTreeMap::new();
15        for (a,b) in self.interfaces.into_iter().chain(x.interfaces.into_iter()){
16            let c = m.remove(&a).unwrap_or_default().merge(b);
17            m.insert(a, c);
18        }
19        Info { interfaces: m }
20    }
21}
22#[derive(Default,Clone)]
23pub struct InfoEntry {
24    pub attrs: Vec<Attr>,
25    pub methods: BTreeMap<String,MethEntry>
26}
27impl InfoEntry{
28    pub fn merge(self, x: InfoEntry) -> InfoEntry{
29        let mut m: BTreeMap<String, MethEntry> = BTreeMap::new();
30        for (a,b) in self.methods.into_iter().chain(x.methods.into_iter()){
31            let c = m.remove(&a).unwrap_or_default().merge(b);
32            m.insert(a, c);
33        }
34        InfoEntry { attrs: merge(self.attrs, x.attrs), methods: m }
35    }
36}
37#[derive(Default,Clone)]
38pub struct MethEntry{
39    pub attrs: Vec<Attr>
40}
41impl MethEntry{
42    pub fn merge(self, x: MethEntry) -> MethEntry{
43        MethEntry { attrs: merge(self.attrs, x.attrs) }
44    }
45}
46impl Display for InfoEntry {
47    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
48        for a in self.attrs.iter(){
49            write!(f,"root {a}")?;
50        }
51        for (k,m) in self.methods.iter(){
52            for a in m.attrs.iter(){
53                write!(f,"method {k} {a}")?;
54            }
55        }
56       Ok(())
57    }
58}
59impl Display for Info {
60    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61        for (i, j) in self.interfaces.iter() {
62            write!(f, "{}: [{j}]", hex::encode(i))?;
63        }
64        Ok(())
65    }
66}
67pub fn parse_entry(a: &str) -> IResult<&str, InfoEntry> {
68    let (a,_) = multispace0(a)?;
69    pub fn go1(a: &str) -> IResult<&str,Attr>{
70        let (a,_) = multispace0(a)?;
71        let (a,_) = tag("root")(a)?;
72        let (a,_) = multispace0(a)?;
73        return parse_attr(a);
74    }
75    pub fn go2(a: &str) -> IResult<&str,(&str,Attr)>{
76        let (a,_) = multispace0(a)?;
77        let (a,_) = tag("method")(a)?;
78        let (a,_) = multispace0(a)?;
79        let (a,b) =         alphanumeric1(a)?;
80        let (a,_) = multispace0(a)?;
81        let (a,c) = parse_attr(a)?;
82        Ok((a,(b,c)))
83    }
84    let (a,mut e) = many0(go1)(a)?;
85    e.sort_by_key(|k|k.name.clone());
86    let mut n: BTreeMap<String, MethEntry> = BTreeMap::new();
87    let (a,l) = many0(go2)(a)?;
88    for (k,v) in l{
89        n.entry(k.to_owned()).or_insert_with(Default::default).attrs.push(v);
90    }
91    for v in n.values_mut(){
92        v.attrs.sort_by_key(|k|k.name.clone());
93    }
94    let (a,_) = multispace0(a)?;
95    Ok((a, InfoEntry { attrs: e, methods: n }))
96}
97pub fn parse_info(a: &str) -> IResult<&str, Info> {
98    pub fn go(a: &str) -> IResult<&str, ([u8; 32], InfoEntry)> {
99        let (a,_) = multispace0(a)?;
100        let (a, d) = take_while_m_n(64, 64, |a: char| a.is_digit(16))(a)?;
101        let mut b = [0u8; 32];
102        hex::decode_to_slice(d, &mut b).unwrap();
103        let (a,_) = multispace0(a)?;
104        let (a,_) = tag(":")(a)?;
105        let (a,_) = multispace0(a)?;
106        let (a, c) = delimited(tag("["), parse_entry, tag("]"))(a)?;
107        return Ok((a, (b, c)));
108    }
109    let (a, all) = many0(go)(a)?;
110    Ok((
111        a,
112        Info {
113            interfaces: all.into_iter().collect(),
114        },
115    ))
116}