use crate::cursor;
use crate::extractor::pre_processors::pre_processor::PreProcessor;
use bstr::ByteSlice;
#[derive(Debug, Default)]
pub struct Clojure;
impl PreProcessor for Clojure {
fn process(&self, content: &[u8]) -> Vec<u8> {
let content = content
.replace(":class", " ")
.replace(":className", " ");
let len = content.len();
let mut result = content.to_vec();
let mut cursor = cursor::Cursor::new(&content);
while cursor.pos < len {
match cursor.curr {
b'"' => {
cursor.advance();
while cursor.pos < len {
match cursor.curr {
b'\\' => cursor.advance_twice(),
b'"' => break,
_ => cursor.advance(),
};
}
}
b';' if matches!(cursor.next, b';') => {
while cursor.pos < len && cursor.curr != b'\n' {
cursor.advance();
}
}
b':' | b'.' => {
result[cursor.pos] = b' ';
}
_ => {}
};
cursor.advance();
}
result
}
}
#[cfg(test)]
mod tests {
use super::Clojure;
use crate::extractor::pre_processors::pre_processor::PreProcessor;
#[test]
fn test_clojure_pre_processor() {
for (input, expected) in [
(":div.flex-1.flex-2", " div flex-1 flex-2"),
(
":.flex-3.flex-4 ;defaults to div",
" flex-3 flex-4 ;defaults to div",
),
("{:class :flex-5.flex-6", "{ flex-5 flex-6"),
(r#"{:class "flex-7 flex-8"}"#, r#"{ "flex-7 flex-8"}"#),
(
r#"{:class ["flex-9" :flex-10]}"#,
r#"{ ["flex-9" flex-10]}"#,
),
(
r#"(dom/div {:class "flex-11 flex-12"})"#,
r#"(dom/div { "flex-11 flex-12"})"#,
),
("(dom/div :.flex-13.flex-14", "(dom/div flex-13 flex-14"),
] {
Clojure::test(input, expected);
}
}
#[test]
fn test_extract_candidates() {
let input = r#"
:div.c1.c2
:.c3.c4 ;defaults to div
{:class :c5.c6
{:class "c7 c8"}
{:class ["c9" :c10]}
(dom/div {:class "c11 c12"})
(dom/div :.c13.c14
{:className :c15.c16
{:className "c17 c18"}
{:className ["c19" :c20]}
(dom/div {:className "c21 c22"})
"#;
Clojure::test_extract_contains(
input,
vec![
"c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10", "c11", "c12", "c13",
"c14", "c15", "c16", "c17", "c18", "c19", "c20", "c21", "c22",
],
);
let input = r#"
:div.flex-1.flex-2
:.flex-3.flex-4 ;defaults to div
{:class :flex-5.flex-6
{:class "flex-7 flex-8"}
{:class ["flex-9" :flex-10]}
(dom/div {:class "flex-11 flex-12"})
(dom/div :.flex-13.flex-14
{:className :flex-15.flex-16
{:className "flex-17 flex-18"}
{:className ["flex-19" :flex-20]}
(dom/div {:className "flex-21 flex-22"})
"#;
Clojure::test_extract_contains(
input,
vec![
"flex-1", "flex-2", "flex-3", "flex-4", "flex-5", "flex-6", "flex-7", "flex-8",
"flex-9", "flex-10", "flex-11", "flex-12", "flex-13", "flex-14", "flex-15",
"flex-16", "flex-17", "flex-18", "flex-19", "flex-20", "flex-21", "flex-22",
],
);
}
#[test]
fn test_special_characters_are_valid_in_strings() {
let input = r#"
(dom/div {:class "hover:flex px-1.5"})
"#;
Clojure::test_extract_contains(input, vec!["hover:flex", "px-1.5"]);
}
#[test]
fn test_ignore_comments_with_invalid_strings() {
let input = r#"
;; This is an unclosed string: "
(dom/div {:class "hover:flex px-1.5"})
"#;
Clojure::test_extract_contains(input, vec!["hover:flex", "px-1.5"]);
}
}