refactor(elements): add Element::Empty variant
This commit is contained in:
parent
c7de340479
commit
74a19c2ff7
|
@ -76,16 +76,19 @@ pub enum Element<'a> {
|
||||||
ident: usize,
|
ident: usize,
|
||||||
ordered: bool,
|
ordered: bool,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Element::Empty actually means Option<Element>::None
|
||||||
|
Empty,
|
||||||
}
|
}
|
||||||
|
|
||||||
// return (element, off, next element, next offset)
|
// return (element, off, next element, next offset)
|
||||||
// the end of first element is relative to the offset
|
// the end of first element is relative to the offset
|
||||||
// next offset is relative to the end of the first element
|
// next offset is relative to the end of the first element
|
||||||
pub fn parse(src: &str) -> (Option<Element<'_>>, usize, Option<(Element<'_>, usize)>) {
|
pub fn parse(src: &str) -> (Element<'_>, usize, Option<(Element<'_>, usize)>) {
|
||||||
// skip empty lines
|
// skip empty lines
|
||||||
let mut pos = match src.chars().position(|c| c != '\n') {
|
let mut pos = match src.chars().position(|c| c != '\n') {
|
||||||
Some(pos) => pos,
|
Some(pos) => pos,
|
||||||
None => return (None, src.len(), None),
|
None => return (Element::Empty, src.len(), None),
|
||||||
};
|
};
|
||||||
let start = pos;
|
let start = pos;
|
||||||
let bytes = src.as_bytes();
|
let bytes = src.as_bytes();
|
||||||
|
@ -97,13 +100,13 @@ pub fn parse(src: &str) -> (Option<Element<'_>>, usize, Option<(Element<'_>, usi
|
||||||
macro_rules! brk {
|
macro_rules! brk {
|
||||||
($ele:expr, $off:expr) => {
|
($ele:expr, $off:expr) => {
|
||||||
break if line_beg == start || pos == start {
|
break if line_beg == start || pos == start {
|
||||||
(Some($ele), pos + $off, None)
|
($ele, pos + $off, None)
|
||||||
} else {
|
} else {
|
||||||
(
|
(
|
||||||
Some(Element::Paragraph {
|
Element::Paragraph {
|
||||||
cont_end: line_beg - start - 1,
|
cont_end: line_beg - start - 1,
|
||||||
end: line_beg - start,
|
end: line_beg - start,
|
||||||
}),
|
},
|
||||||
start,
|
start,
|
||||||
Some(($ele, $off)),
|
Some(($ele, $off)),
|
||||||
)
|
)
|
||||||
|
@ -120,10 +123,10 @@ pub fn parse(src: &str) -> (Option<Element<'_>>, usize, Option<(Element<'_>, usi
|
||||||
|
|
||||||
if bytes[pos] == b'\n' {
|
if bytes[pos] == b'\n' {
|
||||||
break (
|
break (
|
||||||
Some(Element::Paragraph {
|
Element::Paragraph {
|
||||||
cont_end: pos - start - 1,
|
cont_end: pos - start - 1,
|
||||||
end: pos - start + 1,
|
end: pos - start + 1,
|
||||||
}),
|
},
|
||||||
start,
|
start,
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
@ -138,13 +141,13 @@ pub fn parse(src: &str) -> (Option<Element<'_>>, usize, Option<(Element<'_>, usi
|
||||||
ordered,
|
ordered,
|
||||||
};
|
};
|
||||||
break if line_beg == start {
|
break if line_beg == start {
|
||||||
(Some(list), start, None)
|
(list, start, None)
|
||||||
} else {
|
} else {
|
||||||
(
|
(
|
||||||
Some(Element::Paragraph {
|
Element::Paragraph {
|
||||||
cont_end: line_beg - start - 1,
|
cont_end: line_beg - start - 1,
|
||||||
end: line_beg - start,
|
end: line_beg - start,
|
||||||
}),
|
},
|
||||||
start,
|
start,
|
||||||
Some((list, 0)),
|
Some((list, 0)),
|
||||||
)
|
)
|
||||||
|
@ -247,20 +250,20 @@ pub fn parse(src: &str) -> (Option<Element<'_>>, usize, Option<(Element<'_>, usi
|
||||||
// the last character
|
// the last character
|
||||||
if pos >= src.len() {
|
if pos >= src.len() {
|
||||||
break (
|
break (
|
||||||
Some(Element::Paragraph {
|
Element::Paragraph {
|
||||||
cont_end: src.len() - start - 1,
|
cont_end: src.len() - start - 1,
|
||||||
end: src.len() - start,
|
end: src.len() - start,
|
||||||
}),
|
},
|
||||||
start,
|
start,
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
break (
|
break (
|
||||||
Some(Element::Paragraph {
|
Element::Paragraph {
|
||||||
cont_end: src.len() - start,
|
cont_end: src.len() - start,
|
||||||
end: src.len() - start,
|
end: src.len() - start,
|
||||||
}),
|
},
|
||||||
start,
|
start,
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
@ -272,18 +275,20 @@ pub fn parse(src: &str) -> (Option<Element<'_>>, usize, Option<(Element<'_>, usi
|
||||||
mod tests {
|
mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn parse() {
|
fn parse() {
|
||||||
use super::{Element::*, *};
|
use super::keyword::Key;
|
||||||
|
use super::parse;
|
||||||
|
use super::Element::*;
|
||||||
|
|
||||||
assert_eq!(parse("\n\n\n"), (None, 3, None));
|
assert_eq!(parse("\n\n\n"), (Empty, 3, None));
|
||||||
|
|
||||||
let len = "Lorem ipsum dolor sit amet.".len();
|
let len = "Lorem ipsum dolor sit amet.".len();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse("\nLorem ipsum dolor sit amet.\n\n\n"),
|
parse("\nLorem ipsum dolor sit amet.\n\n\n"),
|
||||||
(
|
(
|
||||||
Some(Paragraph {
|
Paragraph {
|
||||||
cont_end: len,
|
cont_end: len,
|
||||||
end: len + 2,
|
end: len + 2,
|
||||||
}),
|
},
|
||||||
1,
|
1,
|
||||||
None
|
None
|
||||||
)
|
)
|
||||||
|
@ -291,10 +296,10 @@ mod tests {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse("\n\nLorem ipsum dolor sit amet.\n\n"),
|
parse("\n\nLorem ipsum dolor sit amet.\n\n"),
|
||||||
(
|
(
|
||||||
Some(Paragraph {
|
Paragraph {
|
||||||
cont_end: len,
|
cont_end: len,
|
||||||
end: len + 2,
|
end: len + 2,
|
||||||
}),
|
},
|
||||||
2,
|
2,
|
||||||
None
|
None
|
||||||
)
|
)
|
||||||
|
@ -302,10 +307,10 @@ mod tests {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse("\nLorem ipsum dolor sit amet.\n"),
|
parse("\nLorem ipsum dolor sit amet.\n"),
|
||||||
(
|
(
|
||||||
Some(Paragraph {
|
Paragraph {
|
||||||
cont_end: len,
|
cont_end: len,
|
||||||
end: len + 1,
|
end: len + 1,
|
||||||
}),
|
},
|
||||||
1,
|
1,
|
||||||
None
|
None
|
||||||
)
|
)
|
||||||
|
@ -313,10 +318,10 @@ mod tests {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse("\n\n\nLorem ipsum dolor sit amet."),
|
parse("\n\n\nLorem ipsum dolor sit amet."),
|
||||||
(
|
(
|
||||||
Some(Paragraph {
|
Paragraph {
|
||||||
cont_end: len,
|
cont_end: len,
|
||||||
end: len,
|
end: len,
|
||||||
}),
|
},
|
||||||
3,
|
3,
|
||||||
None
|
None
|
||||||
)
|
)
|
||||||
|
@ -325,7 +330,7 @@ mod tests {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse("\n\n\n: Lorem ipsum dolor sit amet.\n"),
|
parse("\n\n\n: Lorem ipsum dolor sit amet.\n"),
|
||||||
(
|
(
|
||||||
Some(FixedWidth("Lorem ipsum dolor sit amet.")),
|
FixedWidth("Lorem ipsum dolor sit amet."),
|
||||||
"\n\n\n: Lorem ipsum dolor sit amet.\n".len(),
|
"\n\n\n: Lorem ipsum dolor sit amet.\n".len(),
|
||||||
None
|
None
|
||||||
)
|
)
|
||||||
|
@ -333,7 +338,7 @@ mod tests {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse("\n\n\n: Lorem ipsum dolor sit amet."),
|
parse("\n\n\n: Lorem ipsum dolor sit amet."),
|
||||||
(
|
(
|
||||||
Some(FixedWidth("Lorem ipsum dolor sit amet.")),
|
FixedWidth("Lorem ipsum dolor sit amet."),
|
||||||
"\n\n\n: Lorem ipsum dolor sit amet.".len(),
|
"\n\n\n: Lorem ipsum dolor sit amet.".len(),
|
||||||
None
|
None
|
||||||
)
|
)
|
||||||
|
@ -342,10 +347,10 @@ mod tests {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse("\n\nLorem ipsum dolor sit amet.\n: Lorem ipsum dolor sit amet.\n"),
|
parse("\n\nLorem ipsum dolor sit amet.\n: Lorem ipsum dolor sit amet.\n"),
|
||||||
(
|
(
|
||||||
Some(Paragraph {
|
Paragraph {
|
||||||
cont_end: len,
|
cont_end: len,
|
||||||
end: len + 1,
|
end: len + 1,
|
||||||
}),
|
},
|
||||||
2,
|
2,
|
||||||
Some((FixedWidth("Lorem ipsum dolor sit amet."), 30))
|
Some((FixedWidth("Lorem ipsum dolor sit amet."), 30))
|
||||||
)
|
)
|
||||||
|
@ -354,10 +359,10 @@ mod tests {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse("\n\nLorem ipsum dolor sit amet.\n+ Lorem ipsum dolor sit amet.\n"),
|
parse("\n\nLorem ipsum dolor sit amet.\n+ Lorem ipsum dolor sit amet.\n"),
|
||||||
(
|
(
|
||||||
Some(Paragraph {
|
Paragraph {
|
||||||
cont_end: len,
|
cont_end: len,
|
||||||
end: len + 1,
|
end: len + 1,
|
||||||
}),
|
},
|
||||||
2,
|
2,
|
||||||
Some((
|
Some((
|
||||||
List {
|
List {
|
||||||
|
@ -372,10 +377,10 @@ mod tests {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse("\n\nLorem ipsum dolor sit amet.\n#+BEGIN_QUOTE\nLorem ipsum dolor sit amet.\n#+END_QUOTE\n"),
|
parse("\n\nLorem ipsum dolor sit amet.\n#+BEGIN_QUOTE\nLorem ipsum dolor sit amet.\n#+END_QUOTE\n"),
|
||||||
(
|
(
|
||||||
Some(Paragraph {
|
Paragraph {
|
||||||
cont_end: len,
|
cont_end: len,
|
||||||
end: len + 1,
|
end: len + 1,
|
||||||
}),
|
},
|
||||||
2,
|
2,
|
||||||
Some((
|
Some((
|
||||||
QteBlock {
|
QteBlock {
|
||||||
|
@ -390,10 +395,10 @@ mod tests {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse("\n #+ATTR_HTML: :width 200px"),
|
parse("\n #+ATTR_HTML: :width 200px"),
|
||||||
(
|
(
|
||||||
Some(Keyword {
|
Keyword {
|
||||||
key: keyword::Key::Attr { backend: "HTML" },
|
key: Key::Attr { backend: "HTML" },
|
||||||
value: ":width 200px"
|
value: ":width 200px"
|
||||||
}),
|
},
|
||||||
"\n #+ATTR_HTML: :width 200px".len(),
|
"\n #+ATTR_HTML: :width 200px".len(),
|
||||||
None
|
None
|
||||||
)
|
)
|
||||||
|
|
|
@ -261,11 +261,7 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
fn next_ele(&mut self, end: usize) -> Event<'a> {
|
fn next_ele(&mut self, end: usize) -> Event<'a> {
|
||||||
let text = &self.text[self.off..end];
|
let text = &self.text[self.off..end];
|
||||||
let (ele, off) = self
|
let (ele, off) = self.ele_buf.take().unwrap_or_else(|| {
|
||||||
.ele_buf
|
|
||||||
.take()
|
|
||||||
.map(|(ele, off)| (Some(ele), off))
|
|
||||||
.unwrap_or_else(|| {
|
|
||||||
let (ele, off, next_ele) = elements::parse(text);
|
let (ele, off, next_ele) = elements::parse(text);
|
||||||
self.ele_buf = next_ele;
|
self.ele_buf = next_ele;
|
||||||
(ele, off)
|
(ele, off)
|
||||||
|
@ -275,7 +271,7 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
self.off += off;
|
self.off += off;
|
||||||
|
|
||||||
ele.map(|x| match x {
|
match ele {
|
||||||
Element::Paragraph { cont_end, end } => {
|
Element::Paragraph { cont_end, end } => {
|
||||||
debug_assert!(cont_end <= text.len() && end <= text.len());
|
debug_assert!(cont_end <= text.len() && end <= text.len());
|
||||||
self.stack.push(Container::Paragraph {
|
self.stack.push(Container::Paragraph {
|
||||||
|
@ -346,8 +342,8 @@ impl<'a> Parser<'a> {
|
||||||
Element::Rule => Event::Rule,
|
Element::Rule => Event::Rule,
|
||||||
Element::SrcBlock { args, cont } => Event::SrcBlock { args, cont },
|
Element::SrcBlock { args, cont } => Event::SrcBlock { args, cont },
|
||||||
Element::VerseBlock { args, cont } => Event::VerseBlock { args, cont },
|
Element::VerseBlock { args, cont } => Event::VerseBlock { args, cont },
|
||||||
})
|
Element::Empty => self.end(),
|
||||||
.unwrap_or_else(|| self.end())
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_obj(&mut self, end: usize) -> Event<'a> {
|
fn next_obj(&mut self, end: usize) -> Event<'a> {
|
||||||
|
|
Loading…
Reference in a new issue