1use arc_parser::{ArcParser, Rule};
2use pest::iterators::Pair;
3use pest::Parser;
4use std::fs::{read_to_string, File};
5use std::io::Write;
6use textwrap::indent;
7
8macro_rules! debug_cases {
9 ($i:ident) => {{
10 println!("Rule::{:?}=>continue,", $i.as_rule());
11 println!("Span: {:?}", $i.as_span());
12 println!("Text: {}", $i.as_str());
13 unreachable!();
14 }};
15}
16
17#[derive(Debug)]
18pub struct Settings {
19 pub arc_indent: usize,
20 pub arc_symbol_set: String,
21 pub arc_dict_separator: String,
22 pub arc_list_separator: String,
23 pub arc_list_max_length: usize,
24}
25
26impl Settings {
27 pub fn format_file(&self, path_from: &str, path_to: &str) -> Result<(), std::io::Error> {
28 let r = read_to_string(path_from)?;
29 let s = self.format(&r);
30 let mut file = File::create(path_to)?;
31 file.write_all(s.as_bytes())?;
32 return Ok(());
33 }
34 pub fn format(&self, text: &str) -> String {
35 let pairs = ArcParser::parse(Rule::program, text).unwrap_or_else(|e| panic!("{}", e));
36 let mut code = String::new();
37 for pair in pairs {
38 match pair.as_rule() {
39 Rule::EOI => continue,
40 Rule::WHITESPACE => continue,
41 Rule::dict_literal => {
42 return self.format_json_dict(pair);
43 }
44 _ => debug_cases!(pair),
45 };
46 }
47 return code;
50 }
51 fn format_json_dict(&self, pairs: Pair<Rule>) -> String {
52 let mut codes = vec![];
53 for pair in pairs.into_inner() {
54 match pair.as_rule() {
55 Rule::WHITESPACE => continue,
56 Rule::SEPARATOR => continue,
57 Rule::dict_pair => codes.push(self.format_dict_pair(pair)),
58 _ => debug_cases!(pair),
59 };
60 }
61 return codes.join("\n");
62 }
63 fn format_dict_literal(&self, pairs: Pair<Rule>) -> String {
64 let mut max = 0;
65 let mut codes = vec![];
66 for pair in pairs.into_inner() {
67 match pair.as_rule() {
68 Rule::WHITESPACE => continue,
69 Rule::SEPARATOR => continue,
70 Rule::dict_empty => return String::from("{}"),
71 Rule::dict_pair => {
72 let s = self.format_dict_pair(pair);
73 if s.lines().count() > max {
74 max = s.lines().count()
75 }
76 codes.push(s)
77 }
78 _ => debug_cases!(pair),
79 };
80 }
81 let i = &" ".repeat(self.arc_indent);
82
83 if codes.len() == 1 {
84 if max <= 1 {
85 format!("{{{}}}", codes[0])
86 } else {
87 println!("{:#?}", codes);
88 unreachable!();
89 }
90 } else {
91 let s = match self.arc_dict_separator.as_str() {
92 "," => ",",
93 ";" => ";",
94 _ => "",
95 };
96 let mut code = String::new();
97 for c in &codes {
98 code.push_str(c);
99 code.push_str(s);
100 code.push('\n')
101 }
102 format!("{{\n{}}}", indent(&code, i))
103 }
104 }
105 fn format_list_literal(&self, pairs: Pair<Rule>) -> String {
106 let mut lens = 0;
107 let mut max = 0;
108 let mut codes = vec![];
109 for pair in pairs.into_inner() {
110 match pair.as_rule() {
111 Rule::WHITESPACE => continue,
112 Rule::SEPARATOR => continue,
113 Rule::list_empty => return String::from("[]"),
114 Rule::Value => {
115 let s = self.format_value(pair);
116 lens += s.chars().count();
117 if s.lines().count() > max {
118 max = s.lines().count()
119 }
120 codes.push(s)
121 }
122 _ => debug_cases!(pair),
123 };
124 }
125 let i = &" ".repeat(self.arc_indent);
126 if codes.len() == 1 {
127 if max <= 1 {
128 format!("[{}]", codes[0])
129 } else {
130 format!("[\n{}]", indent(&codes[0], i))
131 }
132 } else if lens <= self.arc_list_max_length {
133 format!("[{}]", codes.join(", "))
134 } else {
135 let s = match self.arc_list_separator.as_str() {
136 "," => ",",
137 ";" => ";",
138 _ => "",
139 };
140 let mut code = String::new();
141 for c in &codes {
142 code.push_str(c);
143 code.push_str(s);
144 code.push('\n')
145 }
146 format!("[\n{}]", indent(&code, i))
147 }
148 }
149 fn format_dict_pair(&self, pairs: Pair<Rule>) -> String {
150 let mut key = String::new();
151 let mut value = String::new();
152 for pair in pairs.into_inner() {
153 match pair.as_rule() {
154 Rule::WHITESPACE => continue,
155 Rule::Set => continue,
156 Rule::NameSpace => {
157 key = self.format_name_space(pair);
158 }
159 Rule::Value => {
160 value = self.format_value(pair);
161 }
162 _ => debug_cases!(pair),
163 };
164 }
165 match self.arc_symbol_set.as_str() {
166 "=" => format!("{} = {}", key, value),
167 _ => format!("{}: {}", key, value),
168 }
169 }
170 fn format_name_space(&self, pairs: Pair<Rule>) -> String {
171 let mut codes = vec![];
172 for pair in pairs.into_inner() {
173 match pair.as_rule() {
174 Rule::Key => {
175 codes.push(self.format_key(pair));
176 }
177 _ => debug_cases!(pair),
178 };
179 }
180 return codes.join(".");
181 }
182 fn format_key(&self, pairs: Pair<Rule>) -> String {
183 for pair in pairs.into_inner() {
184 match pair.as_rule() {
185 Rule::StringNormal => {
186 let s = pair.as_str();
187 return if s.contains('.') {
189 pair.as_str().to_string()
190 } else {
191 s.trim_matches('"').to_string()
192 };
193 }
194 _ => debug_cases!(pair),
195 };
196 }
197 return String::new();
198 }
199 fn format_value(&self, pairs: Pair<Rule>) -> String {
200 let mut code = String::new();
201 for pair in pairs.into_inner() {
202 match pair.as_rule() {
203 Rule::String => {
204 return self.format_string(pair);
205 }
206 Rule::dict_literal => {
207 return self.format_dict_literal(pair);
208 }
209 Rule::list_literal => {
210 return self.format_list_literal(pair);
211 }
212 Rule::Number => {
213 return self.format_number(pair);
214 }
215 Rule::Boolean => {
216 return pair.as_str().to_string();
217 }
218 _ => debug_cases!(pair),
219 };
220 }
221 return code;
222 }
223 fn format_string(&self, pairs: Pair<Rule>) -> String {
224 let mut code = String::new();
225 let mut text = String::new();
226 for pair in pairs.into_inner() {
227 match pair.as_rule() {
228 Rule::StringNormal => {
229 text = pair.as_str().to_string();
230 return text;
231 }
232 _ => debug_cases!(pair),
233 };
234 }
235 return code;
236 }
237 fn format_number(&self, pairs: Pair<Rule>) -> String {
238 let mut code = String::new();
239 let mut text = String::new();
240 for pair in pairs.into_inner() {
241 match pair.as_rule() {
242 Rule::SignedNumber => continue,
244 _ => debug_cases!(pair),
245 };
246 }
247 return code;
248 }
249}