pub fn coloured_html(s: String) -> String {
let mut new = String::new();
for line in s.lines() {
if line.contains("{") {
let entity = line.split_once(" {").unwrap().0.trim_start();
let newline = &line.replace(entity, &html_tag(entity));
new.push_str(newline);
new.push('\n');
} else if line.contains(":") {
let split = line.split_once(':').unwrap();
let property = split.0.trim_start();
let newline = &line.replace(property, &html_property(property));
let mut value = split.1.chars();
value.next(); value.next_back(); let value_first_char = value.next().unwrap();
let value = value_first_char.to_string() + value.as_str();
let html_value = if value_first_char.is_numeric() {
html_value_numeric(&value)
} else {
html_value_string(&value)
};
let newline = newline.replace(&value, &html_value);
new.push_str(&newline);
new.push('\n');
} else if line == "}" {
new.push('}');
new.push('\n');
}
}
new
}
fn html_tag(s: &str) -> String {
format!("<span class=\"tag\">{}</span>", s)
}
fn html_property(s: &str) -> String {
format!("<span class=\"property\">{}</span>", s)
}
fn html_value_numeric(s: &str) -> String {
format!("<span class=\"numeric\">{}</span>", s)
}
fn html_value_string(s: &str) -> String {
format!("<span class=\"string\">{}</span>", s)
}
fn valid_braces<'a>(s: &'a str) -> bool {
let mut stack = Vec::with_capacity(s.len());
for c in s.chars() {
match c {
'}' => {
if !stack.is_empty() && stack.last() == Some(&'{') {
stack.pop();
} else {
return false;
}
}
'{' => stack.push(c),
_ => (),
}
}
if stack.is_empty() {
true
} else {
false
}
}
#[cfg(test)]
mod tests {
#[test]
fn one_open_brace() {
assert_eq!(super::valid_braces("{"), false);
}
#[test]
fn one_closed_brace() {
assert_eq!(super::valid_braces("}"), false);
}
#[test]
fn two_open_braces() {
assert_eq!(super::valid_braces("{{"), false);
}
#[test]
fn two_closed_braces() {
assert_eq!(super::valid_braces("}}"), false);
}
#[test]
fn one_brace_pair() {
assert_eq!(super::valid_braces("{}"), true);
}
#[test]
fn two_brace_pairs() {
assert_eq!(super::valid_braces("{}{}"), true);
}
#[test]
fn one_brace_pair_with_word() {
assert_eq!(super::valid_braces("{hi}"), true);
}
#[test]
fn html_html_tag() {
assert_eq!(super::html_tag("html"), "<span class=\"tag\">html</span>");
}
#[test]
fn html_body_tag() {
assert_eq!(super::html_tag("body"), "<span class=\"tag\">body</span>");
}
#[test]
fn html_main_tag() {
assert_eq!(super::html_tag("main"), "<span class=\"tag\">main</span>");
}
#[test]
fn html_value_int() {
assert_eq!(
super::html_value_numeric("5"),
"<span class=\"numeric\">5</span>"
);
}
#[test]
fn html_value_pct() {
assert_eq!(
super::html_value_numeric("10%"),
"<span class=\"numeric\">10%</span>"
);
}
#[test]
fn html_value_flex() {
assert_eq!(
super::html_value_string("flex"),
"<span class=\"string\">flex</span>"
);
}
}