diff --git a/src/lib.rs b/src/lib.rs index c4d2e83..bd81614 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,6 +4,7 @@ #![feature(is_sorted)] #![feature(test)] // TODO: #![warn(missing_docs)] +#![allow(clippy::bool_assert_comparison)] // Sometimes you want the long form because its easier to see at a glance. extern crate test; diff --git a/src/parser/inline_babel_call.rs b/src/parser/inline_babel_call.rs index 001333f..63308f8 100644 --- a/src/parser/inline_babel_call.rs +++ b/src/parser/inline_babel_call.rs @@ -184,7 +184,7 @@ fn _argument_end<'b, 'g, 'r, 's>( if current_depth > 0 { // Its impossible for the next character to end the argument if we're any amount of parenthesis deep return Err(nom::Err::Error(CustomError::MyError(MyError( - "NoArgumentEnd".into(), + "NoArgumentEnd", )))); } if current_depth < 0 { diff --git a/src/parser/inline_source_block.rs b/src/parser/inline_source_block.rs index 07969c3..3379b5b 100644 --- a/src/parser/inline_source_block.rs +++ b/src/parser/inline_source_block.rs @@ -126,7 +126,7 @@ fn _header_end<'b, 'g, 'r, 's>( if current_depth > 0 { // Its impossible for the next character to end the header if we're any amount of bracket deep return Err(nom::Err::Error(CustomError::MyError(MyError( - "NoHeaderEnd".into(), + "NoHeaderEnd", )))); } if current_depth < 0 { @@ -187,9 +187,7 @@ fn _body_end<'b, 'g, 'r, 's>( let current_depth = input.get_brace_depth() - starting_brace_depth; if current_depth > 0 { // Its impossible for the next character to end the body if we're any amount of brace deep - return Err(nom::Err::Error(CustomError::MyError(MyError( - "NoBodyEnd".into(), - )))); + return Err(nom::Err::Error(CustomError::MyError(MyError("NoBodyEnd")))); } if current_depth < 0 { // This shouldn't be possible because if depth is 0 then a closing brace should end the body. diff --git a/src/parser/keyword.rs b/src/parser/keyword.rs index a7ac6ae..4789b2e 100644 --- a/src/parser/keyword.rs +++ b/src/parser/keyword.rs @@ -50,24 +50,21 @@ fn _filtered_keyword<'s, F: Fn(OrgSource<'s>) -> Res, OrgSource<'s // TODO: When key is a member of org-element-parsed-keywords, value can contain the standard set objects, excluding footnote references. let (remaining, (consumed_input, (_, _, parsed_key, _))) = consumed(tuple((space0, tag("#+"), key_parser, tag(":"))))(input)?; - match tuple(( + if let Ok((remaining, _)) = tuple(( space0::, CustomError>>, alt((line_ending, eof)), ))(remaining) { - Ok((remaining, _)) => { - return Ok(( - remaining, - Keyword { - source: consumed_input.into(), - affiliated_keywords: AffiliatedKeywords::default(), // To be populated by the caller if this keyword is in a context to support affiliated keywords. - key: parsed_key.into(), - value: "".into(), - }, - )); - } - Err(_) => {} - }; + return Ok(( + remaining, + Keyword { + source: consumed_input.into(), + affiliated_keywords: AffiliatedKeywords::default(), // To be populated by the caller if this keyword is in a context to support affiliated keywords. + key: parsed_key.into(), + value: "", + }, + )); + } let (remaining, _ws) = space0(remaining)?; let (remaining, parsed_value) = recognize(many_till( anychar, @@ -173,16 +170,13 @@ fn plain_affiliated_key<'b, 'g, 'r, 's>( )), |(key, _)| key, )(input); - match result { - Ok((remaining, ent)) => { - return Ok((remaining, ent)); - } - Err(_) => {} + if let Ok((remaining, ent)) = result { + return Ok((remaining, ent)); } } Err(nom::Err::Error(CustomError::MyError(MyError( - "NoKeywordKey".into(), + "NoKeywordKey", )))) } @@ -199,16 +193,13 @@ fn dual_affiliated_key<'b, 'g, 'r, 's>( tag("]"), peek(tag(":")), )))(input); - match result { - Ok((remaining, ent)) => { - return Ok((remaining, ent)); - } - Err(_) => {} + if let Ok((remaining, ent)) = result { + return Ok((remaining, ent)); } } Err(nom::Err::Error(CustomError::MyError(MyError( - "NoKeywordKey".into(), + "NoKeywordKey", )))) } diff --git a/src/parser/keyword_todo.rs b/src/parser/keyword_todo.rs index 821f974..acd728f 100644 --- a/src/parser/keyword_todo.rs +++ b/src/parser/keyword_todo.rs @@ -19,7 +19,7 @@ use crate::error::Res; /// Parses the text in the value of a #+TODO keyword. /// /// Example input: "foo bar baz | lorem ipsum" -pub(crate) fn todo_keywords<'s>(input: &'s str) -> Res<&'s str, (Vec<&'s str>, Vec<&'s str>)> { +pub(crate) fn todo_keywords(input: &str) -> Res<&str, (Vec<&str>, Vec<&str>)> { let (remaining, mut before_pipe_words) = separated_list0(space1, todo_keyword_word)(input)?; let (remaining, after_pipe_words) = opt(tuple(( tuple((space0, tag("|"), space0)), @@ -30,12 +30,9 @@ pub(crate) fn todo_keywords<'s>(input: &'s str) -> Res<&'s str, (Vec<&'s str>, V Ok((remaining, (before_pipe_words, after_pipe_words))) } else if !before_pipe_words.is_empty() { // If there was no pipe, then the last word becomes a completion state instead. - let mut after_pipe_words = Vec::with_capacity(1); - after_pipe_words.push( - before_pipe_words - .pop() - .expect("If-statement proves this is Some."), - ); + let after_pipe_words = vec![before_pipe_words + .pop() + .expect("If-statement proves this is Some.")]; Ok((remaining, (before_pipe_words, after_pipe_words))) } else { // No words founds @@ -43,7 +40,7 @@ pub(crate) fn todo_keywords<'s>(input: &'s str) -> Res<&'s str, (Vec<&'s str>, V } } -fn todo_keyword_word<'s>(input: &'s str) -> Res<&'s str, &'s str> { +fn todo_keyword_word(input: &str) -> Res<&str, &str> { let (remaining, keyword) = verify(take_till(|c| "( \t\r\n|".contains(c)), |result: &str| { !result.is_empty() })(input)?; diff --git a/src/parser/latex_fragment.rs b/src/parser/latex_fragment.rs index 9b1c679..9e217e5 100644 --- a/src/parser/latex_fragment.rs +++ b/src/parser/latex_fragment.rs @@ -210,7 +210,7 @@ fn pre<'b, 'g, 'r, 's>( let preceding_character = input.get_preceding_character(); if let Some('$') = preceding_character { return Err(nom::Err::Error(CustomError::MyError(MyError( - "Not a valid pre character for dollar char fragment.".into(), + "Not a valid pre character for dollar char fragment.", )))); } Ok((input, ())) @@ -284,7 +284,7 @@ fn close_border<'b, 'g, 'r, 's>( Some(c) if !c.is_whitespace() && !".,;$".contains(c) => Ok((input, ())), _ => { return Err(nom::Err::Error(CustomError::MyError(MyError( - "Not a valid pre character for dollar char fragment.".into(), + "Not a valid pre character for dollar char fragment.", )))); } } diff --git a/src/parser/lesser_block.rs b/src/parser/lesser_block.rs index b53d622..8fe26e1 100644 --- a/src/parser/lesser_block.rs +++ b/src/parser/lesser_block.rs @@ -76,10 +76,7 @@ where let parser_context = context.with_additional_node(&contexts[0]); let parser_context = parser_context.with_additional_node(&contexts[1]); let parser_context = parser_context.with_additional_node(&contexts[2]); - let parameters = match parameters { - Some((_ws, parameters)) => Some(parameters), - None => None, - }; + let parameters = parameters.map(|(_ws, parameters)| parameters); let object_matcher = parser_with_context!(standard_set_object)(&parser_context); let exit_matcher = parser_with_context!(exit_matcher_parser)(&parser_context); @@ -110,7 +107,7 @@ where context.get_global_settings(), affiliated_keywords, ), - data: parameters.map(|parameters| Into::<&str>::into(parameters)), + data: parameters.map(Into::<&str>::into), children, }, )) @@ -295,7 +292,7 @@ where affiliated_keywords, ), export_type: export_type.map(Into::<&str>::into), - data: parameters.map(|parameters| Into::<&str>::into(parameters)), + data: parameters.map(Into::<&str>::into), contents, }, )) @@ -344,7 +341,7 @@ where let (switches, number_lines, preserve_indent, retain_labels, use_labels, label_format) = { if let Some(switches) = switches { ( - if switches.source.len() == 0 { + if switches.source.is_empty() { None } else { Some(switches.source) @@ -390,7 +387,7 @@ fn data<'s>(input: OrgSource<'s>) -> Res, OrgSource<'s>> { is_not("\r\n")(input) } -fn lesser_block_end<'c>(current_name: &'c str) -> impl ContextMatcher + 'c { +fn lesser_block_end(current_name: &str) -> impl ContextMatcher + '_ { // Since the lesser block names are statically defined in code, we can simply assert that the name is lowercase instead of causing an allocation by converting to lowercase. debug_assert!(current_name == current_name.to_lowercase()); move |context, input: OrgSource<'_>| _lesser_block_end(context, input, current_name) @@ -420,7 +417,7 @@ fn _lesser_block_end<'b, 'g, 'r, 's, 'c>( /// Parser for the beginning of a lesser block /// /// current_name MUST be lowercase. We do not do the conversion ourselves because it is not allowed in a const fn. -const fn lesser_block_begin<'c>(current_name: &'c str) -> impl ContextMatcher + 'c { +const fn lesser_block_begin(current_name: &str) -> impl ContextMatcher + '_ { // TODO: Since this is a const fn, is there ANY way to "generate" functions at compile time? move |context, input: OrgSource<'_>| _lesser_block_begin(context, input, current_name) } @@ -531,11 +528,8 @@ fn _example_src_switches<'s>( (SwitchState::Normal, "-r") => { saw_r = true; use_labels = false; - match retain_labels { - RetainLabels::Yes => { - retain_labels = RetainLabels::No; - } - _ => {} + if let RetainLabels::Yes = retain_labels { + retain_labels = RetainLabels::No; } } (SwitchState::Normal, "-l") => { @@ -675,7 +669,9 @@ pub(crate) fn content<'b, 'g, 'r, 's>( } let (remain, (pre_escape_whitespace, line)) = content_line(remaining)?; - pre_escape_whitespace.map(|val| ret.push_str(Into::<&str>::into(val))); + if let Some(val) = pre_escape_whitespace { + ret.push_str(Into::<&str>::into(val)); + } ret.push_str(line.into()); remaining = remain; } diff --git a/src/parser/line_break.rs b/src/parser/line_break.rs index b93c3c7..1d460f3 100644 --- a/src/parser/line_break.rs +++ b/src/parser/line_break.rs @@ -46,7 +46,7 @@ fn pre<'b, 'g, 'r, 's>( // If None, we are at the start of the file None | Some('\\') => { return Err(nom::Err::Error(CustomError::MyError(MyError( - "Not a valid pre character for line break.".into(), + "Not a valid pre character for line break.", )))); } _ => {} @@ -56,7 +56,7 @@ fn pre<'b, 'g, 'r, 's>( let is_non_empty_line = current_line.chars().any(|c| !c.is_whitespace()); if !is_non_empty_line { return Err(nom::Err::Error(CustomError::MyError(MyError( - "Not a valid pre line for line break.".into(), + "Not a valid pre line for line break.", )))); } diff --git a/src/parser/object_parser.rs b/src/parser/object_parser.rs index 164c346..7298451 100644 --- a/src/parser/object_parser.rs +++ b/src/parser/object_parser.rs @@ -138,7 +138,7 @@ pub(crate) fn detect_standard_set_object_sans_plain_text<'b, 'g, 'r, 's>( } return Err(nom::Err::Error(CustomError::MyError(MyError( - "No object detected.".into(), + "No object detected.", )))); } @@ -158,7 +158,7 @@ fn detect_minimal_set_object_sans_plain_text<'b, 'g, 'r, 's>( } return Err(nom::Err::Error(CustomError::MyError(MyError( - "No object detected.".into(), + "No object detected.", )))); } @@ -223,9 +223,9 @@ fn detect_regular_link_description_set_object_sans_plain_text<'b, 'g, 'r, 's>( return Ok((input, ())); } - return Err(nom::Err::Error(CustomError::MyError(MyError( - "No object detected.".into(), - )))); + Err(nom::Err::Error(CustomError::MyError(MyError( + "No object detected.", + )))) } #[cfg_attr( @@ -290,6 +290,6 @@ fn detect_table_cell_set_object_sans_plain_text<'b, 'g, 'r, 's>( } return Err(nom::Err::Error(CustomError::MyError(MyError( - "No object detected.".into(), + "No object detected.", )))); } diff --git a/src/parser/org_source.rs b/src/parser/org_source.rs index b530b34..3e72829 100644 --- a/src/parser/org_source.rs +++ b/src/parser/org_source.rs @@ -219,7 +219,7 @@ where panic!("Attempted to extend past the end of the WrappedInput.") } if new_start == self.start && new_end == self.end { - return self.clone(); + return *self; } let skipped_text = &self.full_source[self.start..new_start]; @@ -337,7 +337,7 @@ impl<'s> InputTakeAtPosition for OrgSource<'s> { P: Fn(Self::Item) -> bool, { match Into::<&str>::into(self).position(predicate) { - Some(0) => Err(nom::Err::Error(E::from_error_kind(self.clone(), e))), + Some(0) => Err(nom::Err::Error(E::from_error_kind(*self, e))), Some(idx) => Ok(self.take_split(idx)), None => Err(nom::Err::Incomplete(nom::Needed::new(1))), } @@ -366,11 +366,11 @@ impl<'s> InputTakeAtPosition for OrgSource<'s> { { let window = Into::<&str>::into(self); match window.position(predicate) { - Some(0) => Err(nom::Err::Error(E::from_error_kind(self.clone(), e))), + Some(0) => Err(nom::Err::Error(E::from_error_kind(*self, e))), Some(n) => Ok(self.take_split(n)), None => { if window.input_len() == 0 { - Err(nom::Err::Error(E::from_error_kind(self.clone(), e))) + Err(nom::Err::Error(E::from_error_kind(*self, e))) } else { Ok(self.take_split(self.input_len())) } @@ -398,7 +398,7 @@ pub(crate) fn convert_error<'a, I: Into>>( impl<'s> From>> for CustomError<&'s str> { fn from(value: CustomError>) -> Self { match value { - CustomError::MyError(err) => CustomError::MyError(err.into()), + CustomError::MyError(err) => CustomError::MyError(err), CustomError::Nom(input, error_kind) => CustomError::Nom(input.into(), error_kind), CustomError::IO(err) => CustomError::IO(err), CustomError::BoxedError(err) => CustomError::BoxedError(err), diff --git a/src/parser/paragraph.rs b/src/parser/paragraph.rs index 9299601..077e54b 100644 --- a/src/parser/paragraph.rs +++ b/src/parser/paragraph.rs @@ -89,7 +89,7 @@ fn paragraph_end<'b, 'g, 'r, 's>( #[cfg(test)] mod tests { - use crate::context::parser_with_context; + use crate::context::bind_context; use crate::context::Context; use crate::context::ContextElement; use crate::context::GlobalSettings; @@ -104,7 +104,7 @@ mod tests { let global_settings = GlobalSettings::default(); let initial_context = ContextElement::document_context(); let initial_context = Context::new(&global_settings, List::new(&initial_context)); - let paragraph_matcher = parser_with_context!(element(true))(&initial_context); + let paragraph_matcher = bind_context!(element(true), &initial_context); let (remaining, first_paragraph) = paragraph_matcher(input).expect("Parse first paragraph"); let (remaining, second_paragraph) = paragraph_matcher(remaining).expect("Parse second paragraph."); diff --git a/src/parser/plain_link.rs b/src/parser/plain_link.rs index eebf8ad..f8b0cb3 100644 --- a/src/parser/plain_link.rs +++ b/src/parser/plain_link.rs @@ -96,7 +96,7 @@ fn pre<'b, 'g, 'r, 's>( Some(_) => { // Not at start of line, cannot be a heading return Err(nom::Err::Error(CustomError::MyError(MyError( - "Not a valid pre character for plain link.".into(), + "Not a valid pre character for plain link.", )))); } }; @@ -263,16 +263,13 @@ pub(crate) fn protocol<'b, 'g, 'r, 's>( ) -> Res, OrgSource<'s>> { for link_parameter in context.get_global_settings().link_parameters { let result = tag_no_case::<_, _, CustomError<_>>(*link_parameter)(input); - match result { - Ok((remaining, ent)) => { - return Ok((remaining, ent)); - } - Err(_) => {} + if let Ok((remaining, ent)) = result { + return Ok((remaining, ent)); } } Err(nom::Err::Error(CustomError::MyError(MyError( - "NoLinkProtocol".into(), + "NoLinkProtocol", )))) } @@ -346,7 +343,7 @@ fn impl_path_plain_end<'b, 'g, 'r, 's>( } Err(nom::Err::Error(CustomError::MyError(MyError( - "No path plain end".into(), + "No path plain end", )))) } @@ -435,6 +432,6 @@ fn _path_plain_parenthesis_end<'s>( } } Err(nom::Err::Error(CustomError::MyError(MyError( - "No closing parenthesis".into(), + "No closing parenthesis", )))) } diff --git a/src/parser/plain_list.rs b/src/parser/plain_list.rs index dcf65e7..7fffd18 100644 --- a/src/parser/plain_list.rs +++ b/src/parser/plain_list.rs @@ -71,7 +71,7 @@ where alt((space1, line_ending, eof)), )), |(_start, (indent_level, _), (_bullet_type, bull), _after_whitespace)| { - !Into::<&str>::into(bull).starts_with("*") || *indent_level > 0 + !Into::<&str>::into(bull).starts_with('*') || *indent_level > 0 }, )(remaining) .is_ok() @@ -79,7 +79,7 @@ where return Ok((input, ())); } return Err(nom::Err::Error(CustomError::MyError(MyError( - "No element detected.".into(), + "No element detected.", )))); } @@ -153,7 +153,7 @@ where Some(final_child) => final_child, None => { return Err(nom::Err::Error(CustomError::MyError(MyError( - "Plain lists require at least one element.".into(), + "Plain lists require at least one element.", )))); } }; @@ -192,7 +192,7 @@ fn plain_list_item<'b, 'g, 'r, 's>( let (remaining, (indent_level, _leading_whitespace)) = indentation_level(context, input)?; let (remaining, (bullet_type, bull)) = verify( parser_with_context!(bullet)(context), - |(_bullet_type, bull)| !Into::<&str>::into(bull).starts_with("*") || indent_level > 0, + |(_bullet_type, bull)| !Into::<&str>::into(bull).starts_with('*') || indent_level > 0, )(remaining)?; let (remaining, maybe_counter_set) = @@ -227,35 +227,32 @@ fn plain_list_item<'b, 'g, 'r, 's>( let maybe_contentless_item: Res, ()> = peek(parser_with_context!( detect_contentless_item_contents )(&parser_context))(remaining); - match maybe_contentless_item { - Ok((_rem, _ws)) => { - let (remaining, _trailing_ws) = if context.should_consume_trailing_whitespace() { - recognize(alt((recognize(many1(blank_line)), eof)))(remaining)? - } else { - recognize(alt((blank_line, eof)))(remaining)? - }; - let source = get_consumed(input, remaining); - return Ok(( - remaining, - ( - list_type, - PlainListItem { - source: source.into(), - indentation: indent_level, - bullet: bull.into(), - counter: maybe_counter_set, - checkbox: None, - tag: maybe_tag - .map(|(_ws, item_tag)| item_tag) - .unwrap_or(Vec::new()), - pre_blank: 0, - children: Vec::new(), - }, - ), - )); - } - Err(_) => {} - }; + if let Ok((_rem, _ws)) = maybe_contentless_item { + let (remaining, _trailing_ws) = if context.should_consume_trailing_whitespace() { + recognize(alt((recognize(many1(blank_line)), eof)))(remaining)? + } else { + recognize(alt((blank_line, eof)))(remaining)? + }; + let source = get_consumed(input, remaining); + return Ok(( + remaining, + ( + list_type, + PlainListItem { + source: source.into(), + indentation: indent_level, + bullet: bull.into(), + counter: maybe_counter_set, + checkbox: None, + tag: maybe_tag + .map(|(_ws, item_tag)| item_tag) + .unwrap_or(Vec::new()), + pre_blank: 0, + children: Vec::new(), + }, + ), + )); + } let (remaining, pre_blank) = item_tag_post_gap(&parser_context, remaining)?; let pre_blank = Into::<&str>::into(pre_blank) .bytes() diff --git a/src/parser/plain_text.rs b/src/parser/plain_text.rs index 7cfdd4f..0af1c67 100644 --- a/src/parser/plain_text.rs +++ b/src/parser/plain_text.rs @@ -93,22 +93,19 @@ impl<'x> RematchObject<'x> for PlainText<'x> { } let is_not_whitespace = is_not::<&str, &str, CustomError<_>>(" \t\r\n")(goal); - match is_not_whitespace { - Ok((new_goal, payload)) => { - let (new_remaining, _) = tuple(( - tag_no_case(payload), - // TODO: Test to see what the REAL condition is. Checking for not-alphabetic works fine for now, but the real criteria might be something like the plain text exit matcher. - peek(alt(( - recognize(verify(anychar, |c| !c.is_alphanumeric())), - eof, - ))), - ))(remaining)?; - remaining = new_remaining; - goal = new_goal; - continue; - } - Err(_) => {} - }; + if let Ok((new_goal, payload)) = is_not_whitespace { + let (new_remaining, _) = tuple(( + tag_no_case(payload), + // TODO: Test to see what the REAL condition is. Checking for not-alphabetic works fine for now, but the real criteria might be something like the plain text exit matcher. + peek(alt(( + recognize(verify(anychar, |c| !c.is_alphanumeric())), + eof, + ))), + ))(remaining)?; + remaining = new_remaining; + goal = new_goal; + continue; + } let is_whitespace = recognize(many1(alt(( recognize(one_of::<&str, &str, CustomError<_>>(" \t")),