sway_fmt/
code_builder_helpers.rs1use super::code_line::CodeLine;
2use crate::constants::{ALREADY_FORMATTED_LINE_PATTERN, NEW_LINE_PATTERN};
3use std::{
4 iter::{Enumerate, Peekable},
5 str::Chars,
6};
7
8pub fn is_comment(line: &str) -> bool {
9 let mut chars = line.trim().chars();
10 chars.next() == Some('/') && chars.next() == Some('/')
11}
12
13pub fn is_else_statement_next(line: &str) -> bool {
14 let trimmed = line.trim();
15 trimmed.len() >= 4 && &trimmed[0..4] == "else"
16}
17
18pub fn is_multiline_comment(line: &str) -> bool {
19 let mut chars = line.trim().chars();
20 chars.next() == Some('/') && chars.next() == Some('*')
21}
22
23pub fn is_newline_incoming(line: &str) -> bool {
25 let chars = line.chars();
26
27 for c in chars {
28 match c {
29 '\n' => return true,
30 ' ' => {}
31 _ => return false,
32 }
33 }
34
35 false
36}
37
38pub fn handle_multiline_comment_case(
39 code_line: &mut CodeLine,
40 current_char: char,
41 iter: &mut Peekable<Enumerate<Chars>>,
42) {
43 code_line.push_char(current_char);
44
45 if current_char == '*' {
46 if let Some((_, '/')) = iter.peek() {
48 code_line.push_char('/');
49 iter.next();
50 code_line.become_default();
51 }
52 }
53}
54
55pub fn handle_string_case(code_line: &mut CodeLine, current_char: char) {
57 code_line.push_char(current_char);
58 if current_char == '"' {
59 let previous_char = code_line.text.chars().last();
60 if previous_char != Some('\\') {
62 code_line.become_default();
63 }
64 }
65}
66
67pub fn handle_logical_not_case(code_line: &mut CodeLine, iter: &mut Peekable<Enumerate<Chars>>) {
68 code_line.push_char('!');
69 clean_all_whitespace(iter);
70}
71
72pub fn handle_whitespace_case(code_line: &mut CodeLine, iter: &mut Peekable<Enumerate<Chars>>) {
73 clean_all_whitespace(iter);
74
75 if let Some((_, next_char)) = iter.peek() {
76 let next_char = *next_char;
77
78 match next_char {
79 '(' | ';' | ':' | ')' | ',' | '}' => {} _ => {
81 code_line.append_whitespace();
83 }
84 }
85 }
86}
87
88pub fn handle_assignment_case(code_line: &mut CodeLine, iter: &mut Peekable<Enumerate<Chars>>) {
89 if let Some((_, next_char)) = iter.peek() {
90 let next_char = *next_char;
91 if next_char == '=' {
92 code_line.append_with_whitespace("== ");
94 iter.next();
95 } else if next_char == '>' {
96 code_line.append_with_whitespace("=> ");
98 iter.next();
99 } else {
100 code_line.append_equal_sign();
101 }
102 } else {
103 code_line.append_with_whitespace("= ");
104 }
105}
106
107pub fn handle_plus_case(code_line: &mut CodeLine, iter: &mut Peekable<Enumerate<Chars>>) {
108 if let Some((_, next_char)) = iter.peek() {
109 let next_char = *next_char;
110 if next_char == '=' {
111 code_line.append_with_whitespace("+= ");
113 iter.next();
114 } else {
115 code_line.append_with_whitespace("+ ");
116 }
117 } else {
118 code_line.append_with_whitespace("+ ");
119 }
120}
121
122pub fn handle_colon_case(code_line: &mut CodeLine, iter: &mut Peekable<Enumerate<Chars>>) {
123 if let Some((_, next_char)) = iter.peek() {
124 let next_char = *next_char;
125 if next_char == ':' {
126 code_line.push_str("::");
128 iter.next();
129 } else {
130 code_line.push_str(": ");
131 }
132 } else {
133 code_line.push_str(": ");
134 }
135}
136
137pub fn handle_dash_case(code_line: &mut CodeLine, iter: &mut Peekable<Enumerate<Chars>>) {
138 if let Some((_, next_char)) = iter.peek() {
139 if *next_char == '>' {
140 code_line.append_with_whitespace("-> ");
142 iter.next();
143 } else if *next_char == '=' {
144 code_line.append_with_whitespace("-= ");
146 iter.next();
147 } else {
148 code_line.append_with_whitespace("- ");
150 }
151 } else {
152 code_line.append_with_whitespace("- ");
153 }
154}
155
156pub fn handle_multiply_case(code_line: &mut CodeLine, iter: &mut Peekable<Enumerate<Chars>>) {
157 if let Some((_, next_char)) = iter.peek() {
158 let next_char = *next_char;
159 if next_char == '=' {
160 code_line.append_with_whitespace("*= ");
162 iter.next();
163 } else {
164 code_line.append_with_whitespace("* ");
165 }
166 } else {
167 code_line.append_with_whitespace("* ");
168 }
169}
170
171pub fn handle_pipe_case(code_line: &mut CodeLine, iter: &mut Peekable<Enumerate<Chars>>) {
172 if let Some((_, next_char)) = iter.peek() {
173 if *next_char == '|' {
174 code_line.append_with_whitespace("|| ");
176 iter.next();
177 } else {
178 code_line.append_with_whitespace("| ");
180 }
181 } else {
182 code_line.append_with_whitespace("| ");
183 }
184}
185
186pub fn handle_forward_slash_case(code_line: &mut CodeLine, iter: &mut Peekable<Enumerate<Chars>>) {
187 if let Some((_, next_char)) = iter.peek() {
189 let next_char = *next_char;
190 if next_char == '=' {
191 code_line.append_with_whitespace("/= ");
193 iter.next();
194 } else {
195 code_line.append_with_whitespace("/ ");
196 }
197 } else {
198 code_line.append_with_whitespace("/ ");
199 }
200}
201
202pub fn handle_ampersand_case(code_line: &mut CodeLine, iter: &mut Peekable<Enumerate<Chars>>) {
203 if let Some((_, next_char)) = iter.peek() {
204 if *next_char == '&' {
205 code_line.append_with_whitespace("&& ");
207 iter.next();
208 } else {
209 code_line.append_with_whitespace("& ");
211 }
212 } else {
213 code_line.append_with_whitespace("& ");
214 }
215}
216
217pub fn clean_all_whitespace(iter: &mut Peekable<Enumerate<Chars>>) {
219 while let Some((_, next_char)) = iter.peek() {
220 if next_char.is_whitespace() {
221 iter.next();
222 } else {
223 break;
224 }
225 }
226}
227
228pub fn get_new_line_pattern(line: &str) -> Option<&str> {
231 let pattern_len = NEW_LINE_PATTERN.len();
232
233 if line.len() >= pattern_len && &line[0..pattern_len] == NEW_LINE_PATTERN {
234 return Some(&line[pattern_len..]);
235 }
236
237 None
238}
239
240pub fn get_already_formatted_line_pattern(line: &str) -> Option<(&str, &str)> {
243 let pattern_len = ALREADY_FORMATTED_LINE_PATTERN.len();
244
245 if line.starts_with(ALREADY_FORMATTED_LINE_PATTERN) {
246 let char_idxs = vec![
247 line.find(';').unwrap_or(0),
248 line.rfind(',').unwrap_or(0),
249 line.rfind('}').unwrap_or(0),
250 line.rfind('{').unwrap_or(0),
251 ];
252
253 let end = char_idxs.iter().max().unwrap();
254
255 let formatted_line = &line[pattern_len..end + 1];
256 let rest = &line[end + 1..];
258
259 return Some((formatted_line, rest));
260 }
261
262 None
263}