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}
19#[derive(Debug, PartialEq, Default, Clone)]
20pub struct AnnFun {
21    pub tags: TagKvs,
22    pub copy_raw: Option<CopyRaw>,
23}
24
25impl MergeTags for AnnFun {
26    fn merge_tags(&mut self, other_tags: &Option<AnnFun>) {
27        if let Some(atags) = other_tags {
28            for (other_k, other_v) in &atags.tags {
29                if self.tags.get_mut(other_k).is_none() {
30                    self.tags.insert(other_k.clone(), other_v.clone());
31                }
32            }
33
34            if self.copy_raw.is_none() {
35                self.copy_raw = atags.copy_raw.clone()
36            }
37        }
38    }
39}
40
41impl AnnFun {
42    pub fn export_tags(&self) -> Vec<WplTag> {
43        let mut tags = Vec::new();
44        for (k, v) in &self.tags {
45            tags.push(WplTag::new(k.clone(), v.clone()))
46        }
47        tags
48    }
49}
50
51impl DebugFormat for AnnFun {
52    fn write<W>(&self, w: &mut W) -> std::io::Result<()>
53    where
54        W: ?Sized + Write + DepIndent,
55    {
56        write!(w, "#[tag")?;
57        let tag_count = self.tags.len();
58
59        for (index, t) in self.tags.iter().enumerate() {
60            if tag_count == 1 && index == 0 {
61                self.write_open_parenthesis(w)?;
62                write!(w, "{}:\"{}\"", t.0, t.1)?;
63                self.write_close_parenthesis(w)?;
64
65                write!(w, "]")?;
66                self.write_new_line(w)?;
67                return Ok(());
68            }
69            if index == 0 {
70                self.write_open_parenthesis(w)?;
71            }
72            write!(w, "{}:\"{}\"", t.0, t.1)?;
73
74            if index == tag_count - 1 {
75                self.write_close_parenthesis(w)?;
76            } else {
77                write!(w, ", ")?;
78            }
79        }
80
81        if let Some((ck, cv)) = &self.copy_raw {
82            write!(w, ", copy_raw")?;
83            self.write_open_parenthesis(w)?;
84            write!(w, "{}:\"{}\"", ck, cv)?;
85            self.write_close_parenthesis(w)?;
86        }
87        write!(w, "]")?;
88        self.write_new_line(w)?;
89        Ok(())
90    }
91}
92
93impl Accumulate<()> for AnnFun {
94    fn initial(_: Option<usize>) -> Self {
95        AnnFun::default()
96    }
97
98    fn accumulate(&mut self, _acc: ()) {}
99}