Skip to main content

wpl/ast/syntax/
tag.rs

1use std::collections::BTreeMap;
2use std::io::Write;
3
4use smol_str::SmolStr;
5use winnow::stream::Accumulate;
6
7use crate::ast::WplTag;
8use crate::ast::debug::{DebugFormat, DepIndent};
9use crate::parser::MergeTags;
10
11pub type TagKvs = BTreeMap<SmolStr, SmolStr>;
12pub type CopyRaw = (SmolStr, SmolStr);
13
14#[derive(Debug, PartialEq, Clone)]
15pub enum AnnEnum {
16    Tags(TagKvs),
17    Copy(CopyRaw),
18    CopyEventParse(SmolStr),
19}
20#[derive(Debug, PartialEq, Default, Clone)]
21pub struct AnnFun {
22    pub tags: TagKvs,
23    pub copy_raw: Option<CopyRaw>,
24    pub copy_event_parse: Option<SmolStr>,
25}
26
27impl MergeTags for AnnFun {
28    fn merge_tags(&mut self, other_tags: &Option<AnnFun>) {
29        if let Some(atags) = other_tags {
30            for (other_k, other_v) in &atags.tags {
31                if self.tags.get_mut(other_k).is_none() {
32                    self.tags.insert(other_k.clone(), other_v.clone());
33                }
34            }
35
36            if self.copy_raw.is_none() {
37                self.copy_raw = atags.copy_raw.clone()
38            }
39            if self.copy_event_parse.is_none() {
40                self.copy_event_parse = atags.copy_event_parse.clone()
41            }
42        }
43    }
44}
45
46impl AnnFun {
47    pub fn export_tags(&self) -> Vec<WplTag> {
48        let mut tags = Vec::new();
49        for (k, v) in &self.tags {
50            tags.push(WplTag::new(k.clone(), v.clone()))
51        }
52        tags
53    }
54}
55
56impl DebugFormat for AnnFun {
57    fn write<W>(&self, w: &mut W) -> std::io::Result<()>
58    where
59        W: ?Sized + Write + DepIndent,
60    {
61        write!(w, "#[tag")?;
62        let tag_count = self.tags.len();
63
64        for (index, t) in self.tags.iter().enumerate() {
65            if tag_count == 1 && index == 0 {
66                self.write_open_parenthesis(w)?;
67                write!(w, "{}:\"{}\"", t.0, t.1)?;
68                self.write_close_parenthesis(w)?;
69
70                write!(w, "]")?;
71                self.write_new_line(w)?;
72                return Ok(());
73            }
74            if index == 0 {
75                self.write_open_parenthesis(w)?;
76            }
77            write!(w, "{}:\"{}\"", t.0, t.1)?;
78
79            if index == tag_count - 1 {
80                self.write_close_parenthesis(w)?;
81            } else {
82                write!(w, ", ")?;
83            }
84        }
85
86        if let Some((ck, cv)) = &self.copy_raw {
87            write!(w, ", copy_raw")?;
88            self.write_open_parenthesis(w)?;
89            write!(w, "{}:\"{}\"", ck, cv)?;
90            self.write_close_parenthesis(w)?;
91        }
92        if let Some(rule) = &self.copy_event_parse {
93            write!(w, ", copy_event_parse")?;
94            self.write_open_parenthesis(w)?;
95            write!(w, "rule:\"{}\"", rule)?;
96            self.write_close_parenthesis(w)?;
97        }
98        write!(w, "]")?;
99        self.write_new_line(w)?;
100        Ok(())
101    }
102}
103
104impl Accumulate<()> for AnnFun {
105    fn initial(_: Option<usize>) -> Self {
106        AnnFun::default()
107    }
108
109    fn accumulate(&mut self, _acc: ()) {}
110}