Skip to content

Commit

Permalink
fix: Empty input parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
vldm committed Oct 11, 2023
1 parent de04b27 commit ef9a484
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 31 deletions.
34 changes: 16 additions & 18 deletions benches/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,29 +22,27 @@ fn criterion_benchmark(c: &mut Criterion) {

c.bench_function("rstml::parse2(simple)", |b| {
b.iter(|| {
let config: rstml::ParserConfig = rstml::ParserConfig::new()
.always_self_closed_elements(
vec![
"area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta",
"param", "source", "track", "wbr",
]
.into_iter()
.collect(),
);
let config = rstml::ParserConfig::new().always_self_closed_elements(
vec![
"area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta",
"param", "source", "track", "wbr",
]
.into_iter()
.collect(),
);
rstml::Parser::new(config).parse_simple(tokens.clone())
})
});
c.bench_function("rstml::parse2(rust_site)", |b| {
b.iter(|| {
let config: rstml::ParserConfig = rstml::ParserConfig::new()
.always_self_closed_elements(
vec![
"area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta",
"param", "source", "track", "wbr",
]
.into_iter()
.collect(),
);
let config = rstml::ParserConfig::new().always_self_closed_elements(
vec![
"area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta",
"param", "source", "track", "wbr",
]
.into_iter()
.collect(),
);
rstml::Parser::new(config).parse_simple(tokens.clone())
})
});
Expand Down
8 changes: 6 additions & 2 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ impl<C: CustomNode> Parser<C> {
let mut top_level_nodes = 0;

let mut parser = RecoverableContext::new(self.config.clone().into());
while !input.cursor().eof() {
while !input.is_empty() {
let Some(parsed_node) = Node::parse_recoverable(&mut parser, input) else {
parser.push_diagnostic(input.error("Node parse failed".to_string()));
break;
Expand Down Expand Up @@ -101,7 +101,11 @@ impl<C: CustomNode> Parser<C> {

let errors = parser.diagnostics;

let nodes = if nodes.is_empty() { None } else { Some(nodes) };
let nodes = if nodes.is_empty() {
Some(vec![])
} else {
Some(nodes)
};
ParsingResult::from_parts(nodes, errors)
}
}
12 changes: 4 additions & 8 deletions src/parser/recoverable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,14 +160,10 @@ pub enum ParsingResult<T> {
impl<T> ParsingResult<T> {
/// Create new ParsingResult from optional value and accumulated errors.
pub fn from_parts(value: Option<T>, errors: Vec<Diagnostic>) -> Self {
if let Some(token) = value {
if errors.is_empty() {
Self::Ok(token)
} else {
Self::Partial(token, errors)
}
} else {
Self::Failed(errors)
match (value, errors) {
(Some(v), err) if err.is_empty() => Self::Ok(v),
(Some(v), err) => Self::Partial(v, err),
(None, err) => Self::Failed(err),
}
}

Expand Down
16 changes: 13 additions & 3 deletions tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ fn test_block_node() -> Result<()> {

#[test]
fn test_flat_tree() -> Result<()> {
let config: ParserConfig = ParserConfig::new().flat_tree();
let config = ParserConfig::new().flat_tree();

let tokens = quote! {
<div>
Expand Down Expand Up @@ -527,7 +527,7 @@ fn test_transform_block_none() -> Result<()> {
<div>{"foo"}</div>
};

let config: ParserConfig = ParserConfig::new().transform_block(|_| Ok(None));
let config = ParserConfig::new().transform_block(|_| Ok(None));
let nodes = Parser::new(config).parse_simple(tokens);

assert!(nodes.is_ok());
Expand Down Expand Up @@ -788,7 +788,7 @@ fn test_default_wildcard_failed_to_parse_block() {
<Foo> </ _>
};

let config: ParserConfig = ParserConfig::new().element_close_use_default_wildcard_ident(true);
let config = ParserConfig::new().element_close_use_default_wildcard_ident(true);
let _ = Parser::new(config).parse_simple(tokens).unwrap();
}

Expand Down Expand Up @@ -875,6 +875,16 @@ fn test_single_element_with_different_attributes() -> Result<()> {
Ok(())
}

#[test]
fn test_empty_input() -> Result<()> {
let tokens = quote! {};
let nodes = parse2(tokens)?;

assert!(nodes.is_empty());

Ok(())
}

fn get_element(nodes: &[Node], element_index: usize) -> &NodeElement {
let Some(Node::Element(element)) = nodes.get(element_index) else {
panic!("expected element")
Expand Down

0 comments on commit ef9a484

Please sign in to comment.