Skip to main content

tsain_pattern/patterns/
vars.rs

1use super::*;
2
3/// None for skipped enum
4/// Some((var-ts-name (without enum prefix), var props pattern))
5pub type EnumPattern = Composition<Vec<Option<(&'static str, PropsPattern)>>>;
6
7impl EnumPattern {
8    pub fn list(&self) -> &Vec<Option<(&'static str, PropsPattern)>> {
9        &self.list
10    }
11
12    fn union_script(&self) -> String {
13        let ts_name = &self.ts_name;
14        let type_args = crate::format_type_args(&self.type_args);
15        let var_names = self
16            .list
17            .iter()
18            .filter_map(|var| {
19                var.as_ref().map(|(_, var)| {
20                    format!(
21                        "{}{}",
22                        var.ts_name,
23                        &crate::format_type_args(&var.type_args),
24                    )
25                })
26            })
27            .collect::<Vec<_>>()
28            .join(" | ");
29
30        // NOTE: enum itself should not have brand
31        format!(r#"export type {ts_name}{type_args} = {var_names};"#)
32    }
33
34    fn var_ids_script(&self) -> String {
35        self.list
36            .iter()
37            .enumerate()
38            .filter_map(|(var_id, var)| {
39                var.as_ref().map(|(_, var)| {
40                    let var_ts_name = &var.ts_name;
41                    format!("export const {var_ts_name}Id: number = {var_id};")
42                })
43            })
44            .collect::<Vec<_>>()
45            .join("\n")
46    }
47
48    fn vars_script(&self, props_formatter: &impl PropsFormatter) -> String {
49        self.list
50            .iter()
51            .enumerate()
52            .filter_map(|(var_id, var)| {
53                let (_, var) = var.as_ref()?;
54                Some(props_formatter.format_type_script(var, Some(var_id as u32)))
55            })
56            .collect::<Vec<_>>()
57            .join("\n")
58    }
59
60    fn as_vars_script(&self, props_formatter: &impl PropsFormatter) -> String {
61        self.list
62            .iter()
63            .enumerate()
64            .filter_map(|(var_id, var)| {
65                let (_, var) = var.as_ref()?;
66                let script = props_formatter.as_variant_script(
67                    var,
68                    self.ts_name,
69                    &crate::format_type_args(&self.type_args),
70                    var_id as u32,
71                );
72                Some(script)
73            })
74            .collect::<Vec<_>>()
75            .join("\n")
76    }
77
78    pub(super) fn format_enum_type_script(&self, props_formatter: &impl PropsFormatter) -> String {
79        crate::formatter::format_script(
80            format!("// # Enum {}", &self.ts_name),
81            vec![
82                (
83                    // 1. Union
84                    String::new(),
85                    self.union_script(),
86                ),
87                (
88                    // 2. Var Ids
89                    format!("// ## Var Ids"),
90                    self.var_ids_script(),
91                ),
92                (
93                    // 3. As Each Vars
94                    format!("// ## As Each Var"),
95                    self.as_vars_script(props_formatter),
96                ),
97                (
98                    // 4. Each Vars
99                    format!(""),
100                    self.vars_script(props_formatter),
101                ),
102            ],
103        )
104    }
105}