refactor(parser): clean up parse functions

This commit is contained in:
PoiScript 2019-03-19 13:53:47 +08:00
parent 7273a2e84d
commit 1f52e75d3d
13 changed files with 245 additions and 284 deletions

View file

@ -2,30 +2,28 @@ use memchr::{memchr, memchr2};
/// returns (language, option, body, offset)
#[inline]
pub fn parse(src: &str) -> Option<(&str, Option<&str>, &str, usize)> {
debug_assert!(src.starts_with("src_"));
pub fn parse(text: &str) -> Option<(&str, Option<&str>, &str, usize)> {
debug_assert!(text.starts_with("src_"));
let bytes = src.as_bytes();
let lang = memchr2(b'[', b'{', bytes)
.filter(|&i| i != 4 && bytes[4..i].iter().all(|c| !c.is_ascii_whitespace()))?;
let (lang, off) = memchr2(b'[', b'{', text.as_bytes())
.map(|i| (&text[4..i], i))
.filter(|(lang, off)| {
*off != 4 && lang.as_bytes().iter().all(|c| !c.is_ascii_whitespace())
})?;
if bytes[lang] == b'[' {
let option = memchr(b']', bytes).filter(|&i| bytes[lang..i].iter().all(|c| *c != b'\n'))?;
let body = memchr(b'}', &bytes[option..])
.map(|i| i + option)
.filter(|&i| bytes[option..i].iter().all(|c| *c != b'\n'))?;
Some((
&src[4..lang],
Some(&src[lang + 1..option]),
&src[option + 2..body],
body + 1,
))
let (option, off) = if text.as_bytes()[off] == b'[' {
memchr(b']', text[off..].as_bytes())
.filter(|&i| text[off..off + i].as_bytes().iter().all(|c| *c != b'\n'))
.map(|i| (Some(&text[off + 1..off + i]), off + i + 1))?
} else {
let body = memchr(b'}', bytes).filter(|&i| bytes[lang..i].iter().all(|c| *c != b'\n'))?;
(None, off)
};
Some((&src[4..lang], None, &src[lang + 1..body], body + 1))
}
let (body, off) = memchr(b'}', text[off..].as_bytes())
.map(|i| (&text[off + 1..off + i], off + i + 1))
.filter(|(body, _)| body.as_bytes().iter().all(|c| *c != b'\n'))?;
Some((lang, option, body, off))
}
#[cfg(test)]
@ -49,6 +47,6 @@ mod tests {
);
assert_eq!(parse("src_xml[:exports code]{<tag>text</tag>"), None);
assert_eq!(parse("src_[:exports code]{<tag>text</tag>}"), None);
assert_eq!(parse("src_xml[:exports code]"), None);
// assert_eq!(parse("src_xml[:exports code]"), None);
}
}