refactor: cleanup utils macros
This commit is contained in:
parent
346ebc83d7
commit
0b355b498c
18 changed files with 285 additions and 297 deletions
|
|
@ -1,4 +1,5 @@
|
|||
use jetscii::Substring;
|
||||
use memchr::memchr2;
|
||||
|
||||
#[cfg_attr(test, derive(PartialEq))]
|
||||
#[derive(Debug)]
|
||||
|
|
@ -7,54 +8,83 @@ pub struct Macros<'a> {
|
|||
pub args: Option<&'a str>,
|
||||
}
|
||||
|
||||
fn valid_name(ch: u8) -> bool {
|
||||
ch.is_ascii_alphanumeric() || ch == b'-' || ch == b'_'
|
||||
}
|
||||
|
||||
impl<'a> Macros<'a> {
|
||||
pub fn parse(src: &'a str) -> Option<(Macros<'a>, usize)> {
|
||||
starts_with!(src, "{{{");
|
||||
debug_assert!(src.starts_with("{{{"));
|
||||
|
||||
expect!(src, 3, |c: u8| c.is_ascii_alphabetic())?;
|
||||
|
||||
let name = until_while!(src, 3, |c| c == b'}' || c == b'(', valid_name)?;
|
||||
let bytes = src.as_bytes();
|
||||
let name = memchr2(b'}', b'(', bytes).filter(|&i| {
|
||||
bytes[3..i]
|
||||
.iter()
|
||||
.all(|&c| c.is_ascii_alphanumeric() || c == b'-' || c == b'_')
|
||||
})?;
|
||||
|
||||
if src.as_bytes()[name] == b'}' {
|
||||
Some(if bytes[name] == b'}' {
|
||||
expect!(src, name + 1, b'}')?;
|
||||
expect!(src, name + 2, b'}')?;
|
||||
Some((
|
||||
(
|
||||
Macros {
|
||||
name: &src[3..name],
|
||||
args: None,
|
||||
},
|
||||
name + 3,
|
||||
))
|
||||
)
|
||||
} else {
|
||||
let end = Substring::new("}}}").find(&src[name..]).map(|i| i + name)?;
|
||||
expect!(src, end - 1, b')')?;
|
||||
Some((
|
||||
let end = Substring::new(")}}}")
|
||||
.find(&src[name..])
|
||||
.map(|i| i + name)?;
|
||||
(
|
||||
Macros {
|
||||
name: &src[3..name],
|
||||
args: if name == end {
|
||||
None
|
||||
} else {
|
||||
Some(&src[name + 1..end - 1])
|
||||
Some(&src[name + 1..end])
|
||||
},
|
||||
},
|
||||
end + 3,
|
||||
))
|
||||
}
|
||||
end + 4,
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse() {
|
||||
parse_succ!(Macros, "{{{poem(red,blue)}}}", name: "poem", args: Some("red,blue"));
|
||||
parse_succ!(Macros, "{{{poem())}}}", name: "poem", args: Some(")"));
|
||||
parse_succ!(Macros, "{{{author}}}", name: "author", args: None);
|
||||
parse_fail!(Macros, "{{author}}}");
|
||||
parse_fail!(Macros, "{{{0uthor}}}");
|
||||
parse_fail!(Macros, "{{{author}}");
|
||||
parse_fail!(Macros, "{{{poem(}}}");
|
||||
parse_fail!(Macros, "{{{poem)}}}");
|
||||
assert_eq!(
|
||||
Macros::parse("{{{poem(red,blue)}}}"),
|
||||
Some((
|
||||
Macros {
|
||||
name: "poem",
|
||||
args: Some("red,blue")
|
||||
},
|
||||
"{{{poem(red,blue)}}}".len()
|
||||
))
|
||||
);
|
||||
assert_eq!(
|
||||
Macros::parse("{{{poem())}}}"),
|
||||
Some((
|
||||
Macros {
|
||||
name: "poem",
|
||||
args: Some(")")
|
||||
},
|
||||
"{{{poem())}}}".len()
|
||||
))
|
||||
);
|
||||
assert_eq!(
|
||||
Macros::parse("{{{author}}}"),
|
||||
Some((
|
||||
Macros {
|
||||
name: "author",
|
||||
args: None
|
||||
},
|
||||
"{{{author}}}".len()
|
||||
))
|
||||
);
|
||||
|
||||
assert_eq!(Macros::parse("{{{0uthor}}}"), None);
|
||||
assert_eq!(Macros::parse("{{{author}}"), None);
|
||||
assert_eq!(Macros::parse("{{{poem(}}}"), None);
|
||||
assert_eq!(Macros::parse("{{{poem)}}}"), None);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue