Skip to main content

wpl/ast/package/
mod.rs

1use crate::parser::error::{WPLCodeErrorTrait, WplCodeError};
2use derive_getters::Getters;
3use smol_str::SmolStr;
4use std::collections::VecDeque;
5use std::fmt::{Display, Formatter};
6use std::io::Write;
7use wp_primitives::Parser;
8
9use crate::ast::debug::{DebugFormat, DepIndent};
10use crate::ast::{WplRule, WplRuleMeta, WplTag};
11use crate::parser::MergeTags;
12use crate::parser::wpl_pkg::wpl_package;
13
14use super::AnnFun;
15
16#[derive(Default, Clone, Getters, Debug)]
17pub struct WplPackage {
18    pub name: SmolStr,
19    pub rules: VecDeque<WplRule>,
20    pub tags: Option<AnnFun>,
21}
22
23impl WplPackage {
24    pub(crate) fn append(&mut self, p0: Vec<WplRule>) {
25        for i in p0 {
26            self.rules.push_back(i);
27        }
28    }
29}
30
31impl WplPackage {
32    pub fn export_tags(&self) -> Option<Vec<WplTag>> {
33        self.tags.as_ref().map(|x| x.export_tags())
34    }
35}
36
37#[derive(Serialize, Deserialize)]
38pub struct WplPkgMeta {
39    pub name: SmolStr,
40    pub rules: Vec<WplRuleMeta>,
41}
42
43impl From<&WplPackage> for WplPkgMeta {
44    fn from(value: &WplPackage) -> Self {
45        let mut rules = Vec::new();
46        let pkg_tags = value.export_tags();
47        for i in &value.rules {
48            let mut r_stat = WplRuleMeta::from(i);
49            if let Some(mut x) = pkg_tags.clone() {
50                r_stat.tags.append(&mut x);
51            }
52            rules.push(r_stat);
53        }
54        Self {
55            name: value.name.clone(),
56            rules,
57        }
58    }
59}
60
61impl DebugFormat for WplPackage {
62    fn write<W>(&self, w: &mut W) -> std::io::Result<()>
63    where
64        W: ?Sized + Write + DepIndent,
65    {
66        if let Some(tag) = &self.tags {
67            tag.write(w)?;
68        }
69
70        write!(w, "package {} ", self.name)?;
71        self.write_open_brace(w)?;
72        self.write_new_line(w)?;
73
74        for rule in &self.rules {
75            rule.write(w)?;
76            self.write_new_line(w)?;
77        }
78        self.write_close_brace(w)?;
79        self.write_new_line(w)?;
80
81        Ok(())
82    }
83}
84
85impl Display for WplPackage {
86    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
87        write!(f, "{}", self.fmt_string().unwrap_or_default())
88    }
89}
90
91impl MergeTags for WplPackage {
92    fn merge_tags(&mut self, _: &Option<AnnFun>) {
93        self.rules.merge_tags(&self.tags);
94    }
95}
96
97impl WplPackage {
98    pub fn new<S: Into<SmolStr>>(name: S, rules: Vec<WplRule>) -> Self {
99        let name = name.into();
100        debug_assert!(!name.is_empty());
101
102        Self {
103            name,
104            rules: VecDeque::from(rules),
105            tags: None,
106        }
107    }
108
109    pub fn parse(data: &mut &str, path: &str) -> Result<Self, WplCodeError> {
110        let package = wpl_package
111            .parse_next(data)
112            .map_err(|e| WplCodeError::from_syntax(e, data, path))?;
113        Ok(package)
114    }
115
116    pub fn is_empty(&self) -> bool {
117        self.rules.is_empty()
118    }
119}