mamba/generate/convert/
state.rs

1use std::collections::BTreeMap;
2
3use itertools::Itertools;
4
5use crate::check::name::Name;
6use crate::generate::ast::node::Core;
7use crate::generate::GenArguments;
8
9#[derive(Clone, Debug)]
10pub struct State {
11    pub interface: bool,
12
13    pub tup: usize,
14    pub expand_ty: bool,
15    pub def_as_fun_arg: bool,
16
17    pub tup_lit: bool,
18    pub annotate: bool,
19
20    pub is_last_must_be_ret: bool,
21    pub must_assign_to: Option<(Core, Option<Name>)>,
22    pub is_remove_last_ret: bool,
23}
24
25impl From<&GenArguments> for State {
26    fn from(gen_arguments: &GenArguments) -> Self {
27        State { annotate: gen_arguments.annotate, ..State::new() }
28    }
29}
30
31impl State {
32    pub fn new() -> State {
33        State {
34            tup: 1,
35            interface: false,
36            expand_ty: true,
37            def_as_fun_arg: false,
38            tup_lit: false,
39            is_last_must_be_ret: false,
40            is_remove_last_ret: false,
41            must_assign_to: None,
42            annotate: false,
43        }
44    }
45
46    pub fn in_tup(&self, tup: usize) -> State {
47        State { tup, ..self.clone() }
48    }
49
50    pub fn tuple_literal(&self) -> State {
51        State { tup_lit: true, ..self.clone() }
52    }
53
54    pub fn in_interface(&self, interface: bool) -> State {
55        State { interface, ..self.clone() }
56    }
57
58    pub fn expand_ty(&self, expand_ty: bool) -> State {
59        State { expand_ty, ..self.clone() }
60    }
61
62    pub fn remove_ret(&self, remove_ret: bool) -> State {
63        State { is_remove_last_ret: remove_ret, ..self.clone() }
64    }
65
66    pub fn is_last_must_be_ret(&self, last_return: bool) -> State { State { is_last_must_be_ret: last_return, ..self.clone() } }
67
68    pub fn def_as_fun_arg(&self, def_as_fun_arg: bool) -> State {
69        State { def_as_fun_arg, ..self.clone() }
70    }
71
72    pub fn must_assign_to(&self, must_assign_to: Option<&Core>, name: Option<Name>) -> State {
73        if let Some(must_assign_to) = must_assign_to {
74            State { must_assign_to: Some((must_assign_to.clone(), name)), ..self.clone() }
75        } else {
76            State { must_assign_to: None, ..self.clone() }
77        }
78    }
79}
80
81pub struct Imports {
82    imports: Vec<Core>,
83    from_imports: BTreeMap<String, Core>,
84}
85
86impl Default for Imports {
87    fn default() -> Self {
88        Self::new()
89    }
90}
91
92impl Imports {
93    pub fn new() -> Imports {
94        Imports { imports: vec![], from_imports: BTreeMap::new() }
95    }
96
97    pub fn add_import(&mut self, import: &str) {
98        let import = Core::Import {
99            from: None,
100            import: vec![Core::Id { lit: String::from(import) }],
101            alias: vec![],
102        };
103        if !self.imports.contains(&import) {
104            self.imports.push(import);
105        }
106    }
107
108    pub fn add_from_import(&mut self, from: &str, import: &str) {
109        if let Some(Core::Import { import: imports, alias, .. }) =
110            self.from_imports.get(&String::from(from))
111        {
112            let new = Core::Id { lit: String::from(import) };
113            let imports: Vec<Core> = if !imports.contains(&new) {
114                imports.clone().into_iter().chain(vec![new]).collect()
115            } else {
116                imports.to_vec()
117            };
118
119            let import = Core::Import {
120                from: Some(Box::from(Core::Id { lit: String::from(from) })),
121                import: imports
122                    .iter()
123                    .sorted_by_key(|c| match c {
124                        Core::Id { lit } => lit.clone(),
125                        _ => String::from(""),
126                    })
127                    .cloned()
128                    .collect(),
129                alias: alias.clone(),
130            };
131            self.from_imports.insert(String::from(from), import);
132            return;
133        }
134
135        let import = Core::Import {
136            from: Some(Box::from(Core::Id { lit: String::from(from) })),
137            import: vec![Core::Id { lit: String::from(import) }],
138            alias: vec![],
139        };
140        self.from_imports.insert(String::from(from), import);
141    }
142
143    pub fn is_empty(&self) -> bool {
144        self.imports.is_empty() && self.from_imports.is_empty()
145    }
146
147    pub fn imports(&self) -> Vec<Core> {
148        let mut statements = self.imports.clone();
149        statements.append(&mut self.from_imports.clone().into_values().collect());
150        statements
151    }
152}