refactor: cleanup parse function
This commit is contained in:
parent
c1154a1853
commit
c5b14256f0
25 changed files with 1299 additions and 1234 deletions
|
|
@ -1,90 +1,62 @@
|
|||
use jetscii::Substring;
|
||||
use memchr::memchr2;
|
||||
|
||||
#[cfg_attr(test, derive(PartialEq))]
|
||||
#[derive(Debug)]
|
||||
pub struct Macros<'a> {
|
||||
pub name: &'a str,
|
||||
pub args: Option<&'a str>,
|
||||
/// returns (macros name, macros arguments, offset)
|
||||
#[inline]
|
||||
pub fn parse(src: &str) -> Option<(&str, Option<&str>, usize)> {
|
||||
debug_assert!(src.starts_with("{{{"));
|
||||
|
||||
expect!(src, 3, |c: u8| c.is_ascii_alphabetic())?;
|
||||
|
||||
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'_')
|
||||
})?;
|
||||
|
||||
Some(if bytes[name] == b'}' {
|
||||
expect!(src, name + 1, b'}')?;
|
||||
expect!(src, name + 2, b'}')?;
|
||||
(&src[3..name], None, name + 3)
|
||||
} else {
|
||||
let end = Substring::new(")}}}")
|
||||
.find(&src[name..])
|
||||
.map(|i| i + name)?;
|
||||
(
|
||||
&src[3..name],
|
||||
if name == end {
|
||||
None
|
||||
} else {
|
||||
Some(&src[name + 1..end])
|
||||
},
|
||||
end + 4,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
impl<'a> Macros<'a> {
|
||||
pub fn parse(src: &'a str) -> Option<(Macros<'a>, usize)> {
|
||||
debug_assert!(src.starts_with("{{{"));
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn parse() {
|
||||
use super::parse;
|
||||
|
||||
expect!(src, 3, |c: u8| c.is_ascii_alphabetic())?;
|
||||
assert_eq!(
|
||||
parse("{{{poem(red,blue)}}}"),
|
||||
Some(("poem", Some("red,blue"), "{{{poem(red,blue)}}}".len()))
|
||||
);
|
||||
assert_eq!(
|
||||
parse("{{{poem())}}}"),
|
||||
Some(("poem", Some(")"), "{{{poem())}}}".len()))
|
||||
);
|
||||
assert_eq!(
|
||||
parse("{{{author}}}"),
|
||||
Some(("author", None, "{{{author}}}".len()))
|
||||
);
|
||||
|
||||
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'_')
|
||||
})?;
|
||||
|
||||
Some(if bytes[name] == b'}' {
|
||||
expect!(src, name + 1, b'}')?;
|
||||
expect!(src, name + 2, b'}')?;
|
||||
(
|
||||
Macros {
|
||||
name: &src[3..name],
|
||||
args: None,
|
||||
},
|
||||
name + 3,
|
||||
)
|
||||
} else {
|
||||
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])
|
||||
},
|
||||
},
|
||||
end + 4,
|
||||
)
|
||||
})
|
||||
assert_eq!(parse("{{{0uthor}}}"), None);
|
||||
assert_eq!(parse("{{{author}}"), None);
|
||||
assert_eq!(parse("{{{poem(}}}"), None);
|
||||
assert_eq!(parse("{{{poem)}}}"), None);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse() {
|
||||
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