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}