1use crate::{
2 emitter::{Emitter, TagInfo},
3 parser::ParserError,
4};
5
6pub fn concat_ignore_spaces(start: &str, content: &str, end: &str) -> String {
7 let trimmed_content = content.trim_start(); format!("{}{}{}", start, trimmed_content, end)
9}
10
11pub fn get_tag_from_string(string: &str) -> String {
12 let mut i = 3;
13 let mut tag = "".to_string();
14 while i < string.len()
15 && string.chars().nth(i).unwrap() != ' '
16 && string.chars().nth(i).unwrap() != '>'
17 {
18 tag.push(string.chars().nth(i).unwrap());
19 i += 1
20 }
21 tag
22}
23
24pub fn tag_loop(tag_stack: &mut Vec<TagInfo>, output: &mut String, indent: &usize) {
25 while let Some(last_tag_info) = tag_stack.last() {
26 if *indent <= last_tag_info.indent {
27 if last_tag_info.is_self_closing {
28 output.push_str("/>\n");
29 } else {
30 output.push_str(&format!("</{}>\n", last_tag_info.name));
31 }
32 tag_stack.pop();
33 } else {
34 break;
35 }
36 }
37}
38
39pub fn get_line_indent(line: &str) -> usize {
40 if line.is_empty() || line.chars().all(char::is_whitespace) {
41 return 0;
42 };
43 line.len() - line.trim_start().len()
44}
45
46pub fn check_indent_size(size: isize, line: usize) -> Result<(), ParserError> {
47 if size % 4 != 0 {
48 return Err(ParserError::None4xSpacesError(line));
54 }
55 Ok(())
56}
57
58pub fn check_extra_spaces(
59 indent: usize,
60 parent_indent: usize,
61 line: usize,
62) -> Result<(), ParserError> {
63 if indent > parent_indent + 4 {
64 return Err(ParserError::ExtraSpacesError(line));
70 }
71 Ok(())
72}
73
74pub fn get_slice(text: &str, start: usize, end: usize) -> Option<&str> {
75 assert!(end >= start);
76
77 let mut iter = text
78 .char_indices()
79 .map(|(pos, _)| pos)
80 .chain(Some(text.len()))
81 .skip(start)
82 .peekable();
83 let start_pos = *iter.peek()?;
84 for _ in start..end {
85 iter.next();
86 }
87
88 Some(&text[start_pos..*iter.peek()?])
89}
90
91