1#![allow(ambiguous_glob_reexports)]
24
25mod r#struct;
26pub use self::r#struct::*;
27
28pub mod common;
29pub use self::common::*;
30
31mod expressions;
32pub use self::expressions::*;
33
34mod functions;
35pub use self::functions::*;
36
37mod indent_display;
38use indent_display::*;
39
40pub mod interpreter_value;
41
42mod mapping;
43pub use self::mapping::*;
44
45mod passes;
46pub use self::passes::*;
47
48mod program;
49pub use self::program::*;
50
51mod statement;
52pub use self::statement::*;
53
54mod types;
55pub use self::types::*;
56
57mod stub;
58pub use self::stub::*;
59
60mod value;
61pub use value::*;
62
63pub use common::node::*;
64
65use leo_errors::{AstError, Result};
66
67#[derive(Clone, Debug, Default, Eq, PartialEq)]
72pub struct Ast {
73 pub ast: Program,
74}
75
76impl Ast {
77 pub fn new(program: Program) -> Self {
79 Self { ast: program }
80 }
81
82 pub fn as_repr(&self) -> &Program {
84 &self.ast
85 }
86
87 pub fn into_repr(self) -> Program {
88 self.ast
89 }
90
91 pub fn to_json_string(&self) -> Result<String> {
93 Ok(serde_json::to_string_pretty(&self.ast).map_err(|e| AstError::failed_to_convert_ast_to_json_string(&e))?)
94 }
95
96 pub fn to_json_value(&self) -> Result<serde_json::Value> {
101 Ok(serde_json::to_value(&self.ast).map_err(|e| AstError::failed_to_convert_ast_to_json_value(&e))?)
102 }
103
104 pub fn to_json_file(&self, mut path: std::path::PathBuf, file_name: &str) -> Result<()> {
106 path.push(file_name);
107 let file = std::fs::File::create(&path).map_err(|e| AstError::failed_to_create_ast_json_file(&path, &e))?;
108 let writer = std::io::BufWriter::new(file);
109 Ok(serde_json::to_writer_pretty(writer, &self.ast)
110 .map_err(|e| AstError::failed_to_write_ast_to_json_file(&path, &e))?)
111 }
112
113 pub fn to_json_file_without_keys(
115 &self,
116 mut path: std::path::PathBuf,
117 file_name: &str,
118 excluded_keys: &[&str],
119 ) -> Result<()> {
120 path.push(file_name);
121 let file = std::fs::File::create(&path).map_err(|e| AstError::failed_to_create_ast_json_file(&path, &e))?;
122 let writer = std::io::BufWriter::new(file);
123
124 let mut value = self.to_json_value().unwrap();
125 for key in excluded_keys {
126 value = remove_key_from_json(value, key);
127 }
128 value = normalize_json_value(value);
129
130 Ok(serde_json::to_writer_pretty(writer, &value)
131 .map_err(|e| AstError::failed_to_write_ast_to_json_file(&path, &e))?)
132 }
133
134 pub fn from_json_string(json: &str) -> Result<Self> {
136 let ast: Program = serde_json::from_str(json).map_err(|e| AstError::failed_to_read_json_string_to_ast(&e))?;
137 Ok(Self { ast })
138 }
139
140 pub fn from_json_file(path: std::path::PathBuf) -> Result<Self> {
142 let data = std::fs::read_to_string(&path).map_err(|e| AstError::failed_to_read_json_file(&path, &e))?;
143 Self::from_json_string(&data)
144 }
145}
146
147impl AsRef<Program> for Ast {
148 fn as_ref(&self) -> &Program {
149 &self.ast
150 }
151}
152
153pub fn remove_key_from_json(value: serde_json::Value, key: &str) -> serde_json::Value {
155 match value {
156 serde_json::Value::Object(map) => serde_json::Value::Object(
157 map.into_iter().filter(|(k, _)| k != key).map(|(k, v)| (k, remove_key_from_json(v, key))).collect(),
158 ),
159 serde_json::Value::Array(values) => {
160 serde_json::Value::Array(values.into_iter().map(|v| remove_key_from_json(v, key)).collect())
161 }
162 _ => value,
163 }
164}
165
166pub fn normalize_json_value(value: serde_json::Value) -> serde_json::Value {
173 match value {
174 serde_json::Value::Array(vec) => {
175 let orig_length = vec.len();
176 let mut new_vec: Vec<serde_json::Value> = vec
177 .into_iter()
178 .filter(|v| !matches!(v, serde_json::Value::Object(map) if map.is_empty()))
179 .map(normalize_json_value)
180 .collect();
181
182 if orig_length == 2 && new_vec.len() == 1 {
183 new_vec.pop().unwrap()
184 } else {
185 serde_json::Value::Array(new_vec)
186 }
187 }
188 serde_json::Value::Object(map) => {
189 serde_json::Value::Object(map.into_iter().map(|(k, v)| (k, normalize_json_value(v))).collect())
190 }
191 _ => value,
192 }
193}