mamba/generate/convert/
state.rs1use 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}