diff --git a/Cargo.toml b/Cargo.toml index 634dc23..7ca15fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,13 +17,30 @@ license = "MIT" [lints.clippy] all = "deny" -suspicious = "deny" -style = "deny" +clone_on_ref_ptr = "deny" complexity = "deny" -perf = "deny" -must_use_candidate = "deny" +dbg_macro = "deny" doc_markdown = "deny" +exhaustive_structs = "deny" +indexing_slicing = "deny" +let_underscore_must_use = "deny" +map_err_ignore = "deny" missing_const_for_fn = "deny" +must_use_candidate = "deny" +perf = "deny" +print_stderr = "deny" +print_stdout = "deny" +rc_buffer = "deny" +rc_mutex = "deny" +redundant_type_annotations = "deny" +string_to_string = "deny" +style = "deny" +suspicious = "deny" +tests_outside_test_module = "deny" +todo = "deny" +try_err = "deny" +undocumented_unsafe_blocks = "deny" +use_debug = "deny" [dependencies] tracing = { version = "0.1.37", optional = true } diff --git a/benches/criterion.rs b/benches/criterion.rs index 6543877..e7cbce0 100644 --- a/benches/criterion.rs +++ b/benches/criterion.rs @@ -36,7 +36,8 @@ fn examples(c: &mut Criterion) { c.bench_function("parse polish calculator", |b| { b.iter(|| { let input = random_walks.choose(&mut rng).unwrap(); - let _: Vec<_> = polish_calc_grammar.parse_input(input).collect(); + let parses: Vec<_> = polish_calc_grammar.parse_input(input).collect(); + assert!(!parses.is_empty()); }) }); @@ -55,10 +56,11 @@ fn examples(c: &mut Criterion) { &parse_count, |b, &parse_count| { b.iter(|| { - let _: Vec<_> = infinite_grammar + let parses: Vec<_> = infinite_grammar .parse_input(input) .take(parse_count) .collect(); + assert_eq!(parses.len(), parse_count); }) }, ); diff --git a/benches/divan.rs b/benches/divan.rs index ab6c48e..37729ce 100644 --- a/benches/divan.rs +++ b/benches/divan.rs @@ -61,7 +61,7 @@ mod examples { bencher.bench_local(|| { let index = index.next().unwrap(); - let input = &random_walks[index]; + let input = random_walks.get(index).unwrap(); polish_calc_grammar .parse_input(input) .for_each(divan::black_box_drop); diff --git a/src/earley/input_range.rs b/src/earley/input_range.rs index 58be2f5..243ebf6 100644 --- a/src/earley/input_range.rs +++ b/src/earley/input_range.rs @@ -26,7 +26,7 @@ impl<'gram> InputRange<'gram> { } pub fn next(&self) -> &'gram str { let next_idx = self.offset.start + self.offset.len; - &self.input[next_idx..] + self.input.get(next_idx..).unwrap_or("") } pub const fn after(&self) -> Self { Self { @@ -56,9 +56,13 @@ impl<'gram> InputRange<'gram> { impl<'gram> std::fmt::Debug for InputRange<'gram> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let InputRangeOffset { start, len, .. } = self.offset; - let before = &self.input[..start]; - let scanned = &self.input[start..][..len]; - let after = &self.input[start..][len..]; + let before = self.input.get(..start).unwrap_or(""); + let scanned = self + .input + .get(start..) + .and_then(|s| s.get(..len)) + .unwrap_or(""); + let after = self.input.get(start + len..).unwrap_or(""); write!(f, "InputRange(\"{before}|{scanned}|{after}\")",) } } diff --git a/src/earley/mod.rs b/src/earley/mod.rs index e077ee4..1e5e5bf 100644 --- a/src/earley/mod.rs +++ b/src/earley/mod.rs @@ -288,7 +288,8 @@ mod tests { let expr_indexes: Vec = (0..expressions.len()).collect(); let expr_choice_index = g.choose(&expr_indexes).unwrap(); - let expr_choice: &mut crate::Expression = expressions[*expr_choice_index]; + let expr_choice: &mut crate::Expression = + expressions.get_mut(*expr_choice_index).unwrap(); let term_choice_indexes: Vec = (0..expr_choice.terms.len()).collect(); let term_choice_index = g.choose(&term_choice_indexes).unwrap(); diff --git a/src/earley/traversal.rs b/src/earley/traversal.rs index adfa515..0c491a0 100644 --- a/src/earley/traversal.rs +++ b/src/earley/traversal.rs @@ -222,7 +222,10 @@ impl<'gram> TraversalTree<'gram> { let parent_id = parent.id; let production_id = parent.production_id; - let unmatched = &parent.unmatched[1..]; + let unmatched = parent + .unmatched + .get(1..) + .expect("parent traversal has at least one unmatched term"); let is_starting = parent.is_starting; let from = TraversalEdge { term, parent_id }; @@ -306,7 +309,7 @@ mod tests { let scanned = tree.match_term(prediction, term_match); - assert_eq!(scanned.unmatched, &production.rhs.terms[1..]); + assert_eq!(scanned.unmatched, production.rhs.terms.get(1..).unwrap()); } #[test] diff --git a/src/error.rs b/src/error.rs index fd657a3..807d360 100644 --- a/src/error.rs +++ b/src/error.rs @@ -86,14 +86,17 @@ mod tests { #[test] fn from_nom_verbose_error() { let error = nom::error::VerboseError { errors: vec![] }; - let _ = Error::from(error); + assert!(matches!(Error::from(error), Error::ParseError(_))); } #[test] fn from_str_and_nom_verbose_error_kind() { let description = "anything"; let verbose_kind = nom::error::VerboseErrorKind::Char('z'); - let _ = Error::from((description, verbose_kind)); + assert!(matches!( + Error::from((description, verbose_kind)), + Error::ParseError(_) + )); } #[test] diff --git a/src/expression.rs b/src/expression.rs index ad7556c..762cc4b 100644 --- a/src/expression.rs +++ b/src/expression.rs @@ -195,13 +195,13 @@ mod tests { #[test] fn new_expressions() { - let t1: Term = Term::Terminal(String::from("terminal")); - let nt1: Term = Term::Nonterminal(String::from("nonterminal")); - let t2: Term = Term::Terminal(String::from("terminal")); - let nt2: Term = Term::Nonterminal(String::from("nonterminal")); + let t1 = Term::Terminal(String::from("terminal")); + let nt1 = Term::Nonterminal(String::from("nonterminal")); + let t2 = Term::Terminal(String::from("terminal")); + let nt2 = Term::Nonterminal(String::from("nonterminal")); - let e1: Expression = Expression::from_parts(vec![nt1, t1]); - let mut e2: Expression = Expression::new(); + let e1 = Expression::from_parts(vec![nt1, t1]); + let mut e2 = Expression::new(); e2.add_term(nt2); e2.add_term(t2); diff --git a/src/grammar.rs b/src/grammar.rs index e60a8ea..2239ff9 100644 --- a/src/grammar.rs +++ b/src/grammar.rs @@ -539,24 +539,24 @@ mod tests { #[test] fn new_grammars() { - let lhs1: Term = Term::Nonterminal(String::from("STRING A")); - let rhs1: Expression = Expression::from_parts(vec![ + let lhs1 = Term::Nonterminal(String::from("STRING A")); + let rhs1 = Expression::from_parts(vec![ Term::Terminal(String::from("STRING B")), Term::Nonterminal(String::from("STRING C")), ]); - let p1: Production = Production::from_parts(lhs1, vec![rhs1]); + let p1 = Production::from_parts(lhs1, vec![rhs1]); - let lhs2: Term = Term::Nonterminal(String::from("STRING A")); - let rhs2: Expression = Expression::from_parts(vec![ + let lhs2 = Term::Nonterminal(String::from("STRING A")); + let rhs2 = Expression::from_parts(vec![ Term::Terminal(String::from("STRING B")), Term::Nonterminal(String::from("STRING C")), ]); - let p2: Production = Production::from_parts(lhs2, vec![rhs2]); + let p2 = Production::from_parts(lhs2, vec![rhs2]); - let mut g1: Grammar = Grammar::new(); + let mut g1 = Grammar::new(); g1.add_production(p1.clone()); g1.add_production(p2.clone()); - let g2: Grammar = Grammar::from_parts(vec![p1, p2]); + let g2 = Grammar::from_parts(vec![p1, p2]); assert_eq!(g1, g2); } @@ -722,7 +722,7 @@ mod tests { let rhs_iterated = parse_tree.rhs_iter().next().unwrap(); - assert_eq!(&parse_tree.rhs[0], rhs_iterated); + assert_eq!(parse_tree.rhs.first().unwrap(), rhs_iterated); } #[test] @@ -740,14 +740,15 @@ mod tests { *rhs_iterated = ParseTreeNode::Terminal("Z"); - assert_eq!(parse_tree.rhs[0], ParseTreeNode::Terminal("Z")); + assert_eq!( + parse_tree.rhs.first().unwrap(), + &ParseTreeNode::Terminal("Z") + ); } #[test] fn does_not_terminate() { - let mut grammar: Grammar; - - grammar = " ::= ".parse().unwrap(); + let mut grammar: Grammar = " ::= ".parse().unwrap(); assert!(!grammar.terminates()); grammar = " diff --git a/src/production.rs b/src/production.rs index fe35272..4cc897d 100644 --- a/src/production.rs +++ b/src/production.rs @@ -154,19 +154,19 @@ mod tests { #[test] fn new_productions() { - let lhs1: Term = Term::Nonterminal(String::from("STRING A")); - let rhs1: Expression = Expression::from_parts(vec![ + let lhs1 = Term::Nonterminal(String::from("STRING A")); + let rhs1 = Expression::from_parts(vec![ Term::Terminal(String::from("STRING B")), Term::Nonterminal(String::from("STRING C")), ]); - let p1: Production = Production::from_parts(lhs1, vec![rhs1]); + let p1 = Production::from_parts(lhs1, vec![rhs1]); - let lhs2: Term = Term::Nonterminal(String::from("STRING A")); - let rhs2: Expression = Expression::from_parts(vec![ + let lhs2 = Term::Nonterminal(String::from("STRING A")); + let rhs2 = Expression::from_parts(vec![ Term::Terminal(String::from("STRING B")), Term::Nonterminal(String::from("STRING C")), ]); - let mut p2: Production = Production::new(); + let mut p2 = Production::new(); p2.lhs = lhs2; p2.add_to_rhs(rhs2); diff --git a/tests/display.rs b/tests/display.rs index 93f308e..096ea0a 100644 --- a/tests/display.rs +++ b/tests/display.rs @@ -1,3 +1,5 @@ +#![cfg(test)] + use bnf::Grammar; #[test] diff --git a/tests/from_str.rs b/tests/from_str.rs index c9105a8..b35c8cc 100644 --- a/tests/from_str.rs +++ b/tests/from_str.rs @@ -1,3 +1,5 @@ +#![cfg(test)] + mod std_trait { use std::str::FromStr; diff --git a/tests/grammar.rs b/tests/grammar.rs index c7fc1fe..0f69cbc 100644 --- a/tests/grammar.rs +++ b/tests/grammar.rs @@ -1,3 +1,5 @@ +#![cfg(test)] + use bnf::Grammar; use quickcheck::{Arbitrary, Gen, QuickCheck, TestResult}; use rand::{rngs::StdRng, SeedableRng}; diff --git a/tests/iterate.rs b/tests/iterate.rs index 1826417..9a19622 100644 --- a/tests/iterate.rs +++ b/tests/iterate.rs @@ -1,3 +1,5 @@ +#![cfg(test)] + use bnf::{Grammar, Term}; #[test] diff --git a/tests/parse_input.rs b/tests/parse_input.rs index 62176aa..1ce92bd 100644 --- a/tests/parse_input.rs +++ b/tests/parse_input.rs @@ -1,3 +1,5 @@ +#![cfg(test)] + use bnf::Grammar; use insta::assert_snapshot; @@ -75,7 +77,7 @@ fn recursive_nested_infinite() { .map(|a| a.to_string()) .collect(); assert_eq!(parses.len(), parse_count); - assert_snapshot!(parses[0..=3].join("\n")); + assert_snapshot!(parses.get(0..=3).unwrap().join("\n")); } #[test] @@ -215,7 +217,7 @@ fn empty_first_nested() { .map(|a| a.to_string()) .collect(); assert_eq!(parses.len(), parse_count); - assert_snapshot!(parses[0..=3].join("\n")); + assert_snapshot!(parses.get(0..=3).unwrap().join("\n")); } #[test] @@ -278,7 +280,7 @@ fn empty_noop_infinite() { .map(|a| a.to_string()) .collect(); assert_eq!(parses.len(), parse_count); - assert_snapshot!(parses[0..=3].join("\n")); + assert_snapshot!(parses.get(0..=3).unwrap().join("\n")); } // (source: ) @@ -350,7 +352,7 @@ fn shared_nonterminal_failure() { fn swap_left_right_recursion() { let input = "aa a"; - let left_recursive: &str = " + let left_recursive = " ::= | ::= | '.' ::= @@ -388,7 +390,7 @@ fn swap_left_right_recursion() { #[test] fn shared_nullable_nonterminal() { - let grammar: &str = " + let grammar = " ::= | ::= | '.'