refactor: utils macros
This commit is contained in:
parent
93ed18602a
commit
75362bd2a8
|
@ -11,7 +11,7 @@ impl Block {
|
|||
|
||||
let args = eol!(src);
|
||||
let name = until_while!(src, 8, |c| c == b' ' || c == b'\n', |c: u8| c
|
||||
.is_ascii_alphabetic());
|
||||
.is_ascii_alphabetic())?;
|
||||
// TODO: ignore case match
|
||||
let content = src.find(&format!("\n#+END_{}", &src[8..name]))?;
|
||||
let end = eol!(src, content + 1);
|
||||
|
|
|
@ -11,7 +11,7 @@ impl DynBlock {
|
|||
|
||||
let args = eol!(src);
|
||||
let name = until_while!(src, 9, |c| c == b' ' || c == b'\n', |c: u8| c
|
||||
.is_ascii_alphabetic());
|
||||
.is_ascii_alphabetic())?;
|
||||
// TODO: ignore case matching
|
||||
let content = src.find("\n#+END:")?;
|
||||
let end = eol!(src, content + 1);
|
||||
|
|
|
@ -11,7 +11,7 @@ impl FnDef {
|
|||
pub fn parse(src: &str) -> Option<(&str, &str, usize)> {
|
||||
starts_with!(src, "[fn:");
|
||||
|
||||
let label = until_while!(src, 4, b']', valid_label);
|
||||
let label = until_while!(src, 4, b']', valid_label)?;
|
||||
|
||||
if label == 4 {
|
||||
return None;
|
||||
|
|
|
@ -9,7 +9,7 @@ impl Keyword {
|
|||
starts_with!(src, "#+");
|
||||
}
|
||||
|
||||
let key = until_while!(src, 2, b':', |c: u8| c.is_ascii_uppercase() || c == b'_');
|
||||
let key = until_while!(src, 2, b':', |c: u8| c.is_ascii_uppercase() || c == b'_')?;
|
||||
|
||||
// includes the eol character
|
||||
let end = src.find('\n').map(|i| i + 1).unwrap_or_else(|| src.len());
|
||||
|
|
|
@ -5,7 +5,7 @@ pub struct Rule;
|
|||
impl Rule {
|
||||
pub fn parse(src: &str) -> Option<usize> {
|
||||
let end = eol!(src);
|
||||
let leading = until_while!(src, 0, b'-', |c| c == b' ' || c == b'\t');
|
||||
let leading = until_while!(src, 0, b'-', |c| c == b' ' || c == b'\t')?;
|
||||
if src[leading..end].chars().all(|c| c == '-') && end - leading > 4 {
|
||||
Some(end)
|
||||
} else {
|
||||
|
|
|
@ -11,7 +11,7 @@ impl<'a> Cookie<'a> {
|
|||
}
|
||||
|
||||
let num1 = until_while!(src, 1, |c| c == b'%' || c == b'/', |c: u8| c
|
||||
.is_ascii_digit());
|
||||
.is_ascii_digit())?;
|
||||
|
||||
if src.as_bytes()[num1] == b'%' && *src.as_bytes().get(num1 + 1)? == b']' {
|
||||
Some((
|
||||
|
@ -21,7 +21,7 @@ impl<'a> Cookie<'a> {
|
|||
num1 + 2,
|
||||
))
|
||||
} else {
|
||||
let num2 = until_while!(src, num1 + 1, b']', |c: u8| c.is_ascii_digit());
|
||||
let num2 = until_while!(src, num1 + 1, b']', |c: u8| c.is_ascii_digit())?;
|
||||
Some((
|
||||
Cookie {
|
||||
value: &src[0..=num2],
|
||||
|
|
|
@ -3,7 +3,7 @@ pub struct Emphasis;
|
|||
impl Emphasis {
|
||||
// TODO: return usize instead of Option<usize>
|
||||
pub fn parse(src: &str, marker: u8) -> Option<usize> {
|
||||
expect!(src, 1, |c: u8| !c.is_ascii_whitespace());
|
||||
expect!(src, 1, |c: u8| !c.is_ascii_whitespace())?;
|
||||
|
||||
let mut lines = 0;
|
||||
let end = until_while!(src, 1, marker, |c| {
|
||||
|
@ -11,9 +11,9 @@ impl Emphasis {
|
|||
lines += 1;
|
||||
}
|
||||
lines < 2
|
||||
});
|
||||
})?;
|
||||
|
||||
expect!(src, end - 1, |c: u8| !c.is_ascii_whitespace());
|
||||
expect!(src, end - 1, |c: u8| !c.is_ascii_whitespace())?;
|
||||
|
||||
if end < src.len() - 1 {
|
||||
expect!(src, end + 1, |ch| ch == b' '
|
||||
|
@ -26,7 +26,7 @@ impl Emphasis {
|
|||
|| ch == b'\''
|
||||
|| ch == b'\n'
|
||||
|| ch == b')'
|
||||
|| ch == b'}');
|
||||
|| ch == b'}')?;
|
||||
}
|
||||
|
||||
Some(end)
|
||||
|
|
|
@ -7,7 +7,7 @@ impl<'a> Entity<'a> {
|
|||
pub fn parse(src: &'a str) -> Option<(Entity<'a>, usize)> {
|
||||
expect!(src, 0, b'\\')?;
|
||||
|
||||
let name = position!(src, 1, |c| !c.is_ascii_alphabetic());
|
||||
let name = 0;
|
||||
|
||||
if src.as_bytes()[name] == b'[' {
|
||||
Some((
|
||||
|
|
|
@ -13,7 +13,7 @@ impl<'a> FnRef<'a> {
|
|||
pub fn parse(src: &'a str) -> Option<(FnRef<'a>, usize)> {
|
||||
starts_with!(src, "[fn:");
|
||||
|
||||
let label = until_while!(src, 4, |c| c == b']' || c == b':', valid_label);
|
||||
let label = until_while!(src, 4, |c| c == b']' || c == b':', valid_label)?;
|
||||
|
||||
if src.as_bytes()[label] == b':' {
|
||||
let mut pairs = 1;
|
||||
|
|
|
@ -14,28 +14,28 @@ impl<'a> InlineCall<'a> {
|
|||
starts_with!(src, "call_");
|
||||
|
||||
let mut pos = until_while!(src, 5, |c| c == b'[' || c == b'(', |c: u8| c
|
||||
.is_ascii_graphic());
|
||||
.is_ascii_graphic())?;
|
||||
let mut pos_;
|
||||
|
||||
let name = &src[5..pos];
|
||||
|
||||
let inside_header = if src.as_bytes()[pos] == b'[' {
|
||||
pos_ = pos;
|
||||
pos = until_while!(src, pos, b']', |c: u8| c != b'\n') + 1;
|
||||
expect!(src, pos, b'(');
|
||||
pos = until_while!(src, pos, b']', |c: u8| c != b'\n')? + 1;
|
||||
expect!(src, pos, b'(')?;
|
||||
Some(&src[pos_ + 1..pos - 1])
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
pos_ = pos;
|
||||
pos = until_while!(src, pos, b')', |c| c != b'\n');
|
||||
pos = until_while!(src, pos, b')', |c| c != b'\n')?;
|
||||
let args = &src[pos_ + 1..pos];
|
||||
|
||||
let end_header = if src.len() > pos + 1 && src.as_bytes()[pos + 1] == b'[' {
|
||||
pos_ = pos;
|
||||
pos = until_while!(src, pos_ + 1, |c| c == b']', |c: u8| c != b'\n'
|
||||
&& c != b')');
|
||||
&& c != b')')?;
|
||||
Some(&src[pos_ + 2..pos])
|
||||
} else {
|
||||
None
|
||||
|
|
|
@ -11,15 +11,15 @@ impl<'a> InlineSrc<'a> {
|
|||
starts_with!(src, "src_");
|
||||
|
||||
let lang = until_while!(src, 4, |c| c == b'[' || c == b'{', |c: u8| !c
|
||||
.is_ascii_whitespace());
|
||||
.is_ascii_whitespace())?;
|
||||
|
||||
if lang == 4 {
|
||||
return None;
|
||||
}
|
||||
|
||||
if src.as_bytes()[lang] == b'[' {
|
||||
let option = until_while!(src, lang, b']', |c| c != b'\n');
|
||||
let body = until_while!(src, option, b'}', |c| c != b'\n');
|
||||
let option = until_while!(src, lang, b']', |c| c != b'\n')?;
|
||||
let body = until_while!(src, option, b'}', |c| c != b'\n')?;
|
||||
|
||||
Some((
|
||||
InlineSrc {
|
||||
|
@ -30,7 +30,7 @@ impl<'a> InlineSrc<'a> {
|
|||
body + 1,
|
||||
))
|
||||
} else {
|
||||
let body = until_while!(src, lang, b'}', |c| c != b'\n');
|
||||
let body = until_while!(src, lang, b'}', |c| c != b'\n')?;
|
||||
|
||||
Some((
|
||||
InlineSrc {
|
||||
|
|
|
@ -11,7 +11,7 @@ impl<'a> Link<'a> {
|
|||
starts_with!(src, "[[");
|
||||
}
|
||||
|
||||
let path = until_while!(src, 2, b']', |c| c != b'<' && c != b'>' && c != b'\n');
|
||||
let path = until_while!(src, 2, b']', |c| c != b'<' && c != b'>' && c != b'\n')?;
|
||||
|
||||
if cond_eq!(src, path + 1, b']') {
|
||||
Some((
|
||||
|
@ -22,7 +22,7 @@ impl<'a> Link<'a> {
|
|||
path + 2,
|
||||
))
|
||||
} else if src.as_bytes()[path + 1] == b'[' {
|
||||
let desc = until_while!(src, path + 2, b']', |c| c != b'[');
|
||||
let desc = until_while!(src, path + 2, b']', |c| c != b'[')?;
|
||||
expect!(src, desc + 1, b']')?;
|
||||
|
||||
Some((
|
||||
|
|
|
@ -15,9 +15,9 @@ impl<'a> Macros<'a> {
|
|||
pub fn parse(src: &'a str) -> Option<(Macros<'a>, usize)> {
|
||||
starts_with!(src, "{{{");
|
||||
|
||||
expect!(src, 3, |c: u8| c.is_ascii_alphabetic());
|
||||
expect!(src, 3, |c: u8| c.is_ascii_alphabetic())?;
|
||||
|
||||
let name = until_while!(src, 3, |c| c == b'}' || c == b'(', valid_name);
|
||||
let name = until_while!(src, 3, |c| c == b'}' || c == b'(', valid_name)?;
|
||||
|
||||
if src.as_bytes()[name] == b'}' {
|
||||
expect!(src, name + 1, b'}')?;
|
||||
|
|
|
@ -13,7 +13,7 @@ impl<'a> Snippet<'a> {
|
|||
starts_with!(src, "@@");
|
||||
}
|
||||
|
||||
let name = until_while!(src, 2, b':', |c: u8| c.is_ascii_alphanumeric() || c == b'-');
|
||||
let name = until_while!(src, 2, b':', |c: u8| c.is_ascii_alphanumeric() || c == b'-')?;
|
||||
|
||||
if name == 2 {
|
||||
return None;
|
||||
|
|
|
@ -9,11 +9,11 @@ impl<'a> RadioTarget<'a> {
|
|||
starts_with!(src, "<<<");
|
||||
}
|
||||
|
||||
expect!(src, 3, |c| c != b' ');
|
||||
expect!(src, 3, |c| c != b' ')?;
|
||||
|
||||
let end = until_while!(src, 3, b'>', |c| c != b'<' && c != b'\n');
|
||||
let end = until_while!(src, 3, b'>', |c| c != b'<' && c != b'\n')?;
|
||||
|
||||
expect!(src, end - 1, |c| c != b' ');
|
||||
expect!(src, end - 1, |c| c != b' ')?;
|
||||
expect!(src, end + 1, b'>')?;
|
||||
expect!(src, end + 2, b'>')?;
|
||||
|
||||
|
@ -31,11 +31,11 @@ impl<'a> Target<'a> {
|
|||
starts_with!(src, "<<");
|
||||
}
|
||||
|
||||
expect!(src, 2, |c| c != b' ');
|
||||
expect!(src, 2, |c| c != b' ')?;
|
||||
|
||||
let end = until_while!(src, 2, b'>', |c| c != b'<' && c != b'\n');
|
||||
let end = until_while!(src, 2, b'>', |c| c != b'<' && c != b'\n')?;
|
||||
|
||||
expect!(src, end - 1, |c| c != b' ');
|
||||
expect!(src, end - 1, |c| c != b' ')?;
|
||||
expect!(src, end + 1, b'>')?;
|
||||
|
||||
Some((Target(&src[2..end]), end + 2))
|
||||
|
|
87
src/utils.rs
87
src/utils.rs
|
@ -3,13 +3,10 @@
|
|||
#[macro_export]
|
||||
macro_rules! expect {
|
||||
($src:ident, $index:expr, $expect:tt) => {
|
||||
$src.as_bytes().get($index).filter(|&b| b == &$expect)
|
||||
$src.as_bytes().get($index).filter(|&&b| b == $expect)
|
||||
};
|
||||
($src:ident, $index:expr, $expect:expr) => {
|
||||
// $src.as_bytes().get($index).filter($expect)
|
||||
if $index >= $src.len() || !$expect($src.as_bytes()[$index]) {
|
||||
return None;
|
||||
}
|
||||
$src.as_bytes().get($index).filter(|&&b| $expect(b))
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -30,30 +27,30 @@ macro_rules! eol {
|
|||
macro_rules! until {
|
||||
($src:expr, $until:tt) => {{
|
||||
let mut pos = 0;
|
||||
while pos < $src.len() {
|
||||
if $until == $src.as_bytes()[pos] {
|
||||
break;
|
||||
loop {
|
||||
if pos >= $src.len() {
|
||||
break None;
|
||||
}
|
||||
|
||||
if $until == $src.as_bytes()[pos] {
|
||||
break Some(pos);
|
||||
} else {
|
||||
pos += 1;
|
||||
}
|
||||
if pos == $src.len() {
|
||||
None
|
||||
} else {
|
||||
Some(pos)
|
||||
}
|
||||
}};
|
||||
($src:expr, $until:expr) => {{
|
||||
let mut pos = 0;
|
||||
while pos < $src.len() {
|
||||
if $until($src.as_bytes()[pos]) {
|
||||
break;
|
||||
loop {
|
||||
if pos >= $src.len() {
|
||||
break None;
|
||||
}
|
||||
|
||||
if $until($src.as_bytes()[pos]) {
|
||||
break Some(pos);
|
||||
} else {
|
||||
pos += 1;
|
||||
}
|
||||
if pos == $src.len() {
|
||||
None
|
||||
} else {
|
||||
Some(pos)
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
@ -62,41 +59,33 @@ macro_rules! until {
|
|||
macro_rules! until_while {
|
||||
($src:expr, $start:expr, $until:tt, $while:expr) => {{
|
||||
let mut pos = $start;
|
||||
while pos < $src.len() {
|
||||
// println!("pos {} char {} ", pos, $src.as_bytes()[pos] as char,);
|
||||
if $until == $src.as_bytes()[pos] {
|
||||
break;
|
||||
loop {
|
||||
if pos >= $src.len() {
|
||||
break None;
|
||||
} else if $until == $src.as_bytes()[pos] {
|
||||
break Some(pos);
|
||||
} else if $while($src.as_bytes()[pos]) {
|
||||
pos += 1;
|
||||
continue;
|
||||
} else {
|
||||
return None;
|
||||
break None;
|
||||
}
|
||||
}
|
||||
if pos == $src.len() {
|
||||
return None;
|
||||
} else {
|
||||
pos
|
||||
}
|
||||
}};
|
||||
($src:expr, $start:expr, $until:expr, $while:expr) => {{
|
||||
let mut pos = $start;
|
||||
while pos < $src.len() {
|
||||
// println!("pos {} char {}", pos, $src.as_bytes()[pos] as char);
|
||||
if $until($src.as_bytes()[pos]) {
|
||||
break;
|
||||
loop {
|
||||
if pos >= $src.len() {
|
||||
break None;
|
||||
} else if $until($src.as_bytes()[pos]) {
|
||||
break Some(pos);
|
||||
} else if $while($src.as_bytes()[pos]) {
|
||||
pos += 1;
|
||||
continue;
|
||||
} else {
|
||||
return None;
|
||||
break None;
|
||||
}
|
||||
}
|
||||
if pos == $src.len() {
|
||||
return None;
|
||||
} else {
|
||||
pos
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
|
@ -111,16 +100,6 @@ macro_rules! cond_eq {
|
|||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! position {
|
||||
($s:ident, $i:expr, $p:expr) => {
|
||||
match $s[$i..].chars().position($p) {
|
||||
Some(x) => x + $i,
|
||||
None => return None,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! starts_with {
|
||||
($s:ident, $p:expr) => {
|
||||
|
@ -144,13 +123,13 @@ macro_rules! skip_space {
|
|||
macro_rules! skip_empty_line {
|
||||
($src:ident, $from:expr) => {{
|
||||
let mut pos = $from;
|
||||
while pos < $src.len() {
|
||||
if $src.as_bytes()[pos] != b'\n' {
|
||||
break;
|
||||
}
|
||||
loop {
|
||||
if pos >= $src.len() || $src.as_bytes()[pos] != b'\n' {
|
||||
break pos;
|
||||
} else {
|
||||
pos += 1;
|
||||
}
|
||||
pos
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue