Apply more suggestions.

This commit is contained in:
Tom Alexander 2023-10-16 18:54:41 -04:00
parent 3069711447
commit 880b00ef3f
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
7 changed files with 66 additions and 92 deletions

View File

@ -227,7 +227,7 @@ impl<'b, 's> DiffResult<'b, 's> {
status_text = status_text, status_text = status_text,
name = self.name, name = self.name,
char_offset = preceding_text.chars().count() + 1, char_offset = preceding_text.chars().count() + 1,
message = self.message.as_ref().map(|m| m.as_str()).unwrap_or("") message = self.message.as_deref().unwrap_or("")
); );
for child in self.children.iter() { for child in self.children.iter() {
child.print_indented(indentation + 1, original_document)?; child.print_indented(indentation + 1, original_document)?;
@ -330,8 +330,8 @@ pub(crate) fn artificial_diff_scope<'b, 's>(
.into()) .into())
} }
pub(crate) fn artificial_owned_diff_scope<'b, 's, 'x>( pub(crate) fn artificial_owned_diff_scope<'b, 's>(
name: &'x str, name: &str,
children: Vec<DiffEntry<'b, 's>>, children: Vec<DiffEntry<'b, 's>>,
) -> Result<DiffEntry<'b, 's>, Box<dyn std::error::Error>> { ) -> Result<DiffEntry<'b, 's>, Box<dyn std::error::Error>> {
Ok(DiffLayer { Ok(DiffLayer {
@ -427,12 +427,9 @@ pub(crate) fn compare_ast_node<'b, 's>(
// PlainText is a special case because upstream Org-Mode uses relative values for the bounds in plaintext rather than absolute so the below checks do not account for that. // PlainText is a special case because upstream Org-Mode uses relative values for the bounds in plaintext rather than absolute so the below checks do not account for that.
if let AstNode::PlainText(_) = rust { if let AstNode::PlainText(_) = rust {
} else { } else {
match compare_standard_properties(source, emacs, &rust) { if let Err(err) = compare_standard_properties(source, emacs, &rust) {
Err(err) => { compare_result.status = DiffStatus::Bad;
compare_result.status = DiffStatus::Bad; compare_result.message = Some(err.to_string())
compare_result.message = Some(err.to_string())
}
Ok(_) => {}
} }
} }
@ -495,7 +492,7 @@ fn _compare_document<'b, 's>(
.map(EmacsField::Required), .map(EmacsField::Required),
( (
EmacsField::Required(":path"), EmacsField::Required(":path"),
|r| r.path.as_ref().map(|p| p.to_str()).flatten(), |r| r.path.as_ref().and_then(|p| p.to_str()),
compare_property_quoted_string compare_property_quoted_string
), ),
( (

View File

@ -113,24 +113,21 @@ fn is_slice_of(parent: &str, child: &str) -> bool {
/// Get a slice of the string that was consumed in a parser using the original input to the parser and the remaining input after the parser. /// Get a slice of the string that was consumed in a parser using the original input to the parser and the remaining input after the parser.
fn get_consumed<'s>(input: &'s str, remaining: &'s str) -> &'s str { fn get_consumed<'s>(input: &'s str, remaining: &'s str) -> &'s str {
debug_assert!(is_slice_of(input, remaining)); debug_assert!(is_slice_of(input, remaining));
let source = { let offset = remaining.as_ptr() as usize - input.as_ptr() as usize;
let offset = remaining.as_ptr() as usize - input.as_ptr() as usize; &input[..offset]
&input[..offset]
};
source.into()
} }
pub(crate) fn unquote(text: &str) -> Result<String, Box<dyn std::error::Error>> { pub(crate) fn unquote(text: &str) -> Result<String, Box<dyn std::error::Error>> {
let mut out: Vec<u8> = Vec::with_capacity(text.len()); let mut out: Vec<u8> = Vec::with_capacity(text.len());
if !text.starts_with(r#"""#) { if !text.starts_with('"') {
return Err("Quoted text does not start with quote.".into()); return Err("Quoted text does not start with quote.".into());
} }
if !text.ends_with(r#"""#) { if !text.ends_with('"') {
return Err("Quoted text does not end with quote.".into()); return Err("Quoted text does not end with quote.".into());
} }
let interior_text = &text[1..(text.len() - 1)]; let interior_text = &text[1..(text.len() - 1)];
let mut state = ParseState::Normal; let mut state = ParseState::Normal;
for current_char in interior_text.bytes().into_iter() { for current_char in interior_text.bytes() {
// Check to see if octal finished // Check to see if octal finished
state = match (state, current_char) { state = match (state, current_char) {
(ParseState::Octal(octal), b'0'..=b'7') if octal.len() < MAX_OCTAL_LENGTH => { (ParseState::Octal(octal), b'0'..=b'7') if octal.len() < MAX_OCTAL_LENGTH => {
@ -229,11 +226,9 @@ fn atom<'s>(input: &'s str) -> Res<&'s str, Token<'s>> {
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
fn unquoted_atom<'s>(input: &'s str) -> Res<&'s str, Token<'s>> { fn unquoted_atom<'s>(input: &'s str) -> Res<&'s str, Token<'s>> {
let (remaining, body) = take_till1(|c| match c { let (remaining, body) =
' ' | '\t' | '\r' | '\n' | ')' | ']' => true, take_till1(|c| matches!(c, ' ' | '\t' | '\r' | '\n' | ')' | ']'))(input)?;
_ => false, Ok((remaining, Token::Atom(body)))
})(input)?;
Ok((remaining, Token::Atom(body.into())))
} }
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
@ -264,22 +259,19 @@ fn quoted_atom<'s>(input: &'s str) -> Res<&'s str, Token<'s>> {
} }
let (remaining, _) = tag(r#"""#)(remaining)?; let (remaining, _) = tag(r#"""#)(remaining)?;
let source = get_consumed(input, remaining); let source = get_consumed(input, remaining);
Ok((remaining, Token::Atom(source.into()))) Ok((remaining, Token::Atom(source)))
} }
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
fn hash_notation<'s>(input: &'s str) -> Res<&'s str, Token<'s>> { fn hash_notation<'s>(input: &'s str) -> Res<&'s str, Token<'s>> {
let (remaining, _) = tag("#<")(input)?; let (remaining, _) = tag("#<")(input)?;
let (remaining, _body) = take_till1(|c| match c { let (remaining, _body) = take_till1(|c| matches!(c, '>'))(remaining)?;
'>' => true,
_ => false,
})(remaining)?;
let (remaining, _) = tag(">")(remaining)?; let (remaining, _) = tag(">")(remaining)?;
let source = get_consumed(input, remaining); let source = get_consumed(input, remaining);
Ok((remaining, Token::Atom(source.into()))) Ok((remaining, Token::Atom(source)))
} }
fn text_with_properties<'s>(input: &'s str) -> Res<&'s str, Token<'s>> { fn text_with_properties(input: &str) -> Res<&str, Token<'_>> {
let (remaining, _) = tag("#(")(input)?; let (remaining, _) = tag("#(")(input)?;
let (remaining, (text, props)) = delimited( let (remaining, (text, props)) = delimited(
multispace0, multispace0,

View File

@ -54,8 +54,8 @@ pub(crate) fn compare_standard_properties<
Ok(()) Ok(())
} }
pub(crate) fn assert_name<'b, 's, S: AsRef<str>>( pub(crate) fn assert_name<S: AsRef<str>>(
emacs: &'b Token<'s>, emacs: &Token<'_>,
name: S, name: S,
) -> Result<(), Box<dyn std::error::Error>> { ) -> Result<(), Box<dyn std::error::Error>> {
let name = name.as_ref(); let name = name.as_ref();
@ -90,9 +90,9 @@ pub(crate) fn assert_bounds<'b, 's, S: StandardProperties<'s> + ?Sized>(
standard_properties.end.ok_or("Token should have an end.")?, standard_properties.end.ok_or("Token should have an end.")?,
); );
let (rust_begin, rust_end) = get_rust_byte_offsets(original_document, rust); // 0-based let (rust_begin, rust_end) = get_rust_byte_offsets(original_document, rust); // 0-based
let rust_begin_char_offset = (&original_document[..rust_begin]).chars().count() + 1; // 1-based let rust_begin_char_offset = original_document[..rust_begin].chars().count() + 1; // 1-based
let rust_end_char_offset = let rust_end_char_offset =
rust_begin_char_offset + (&original_document[rust_begin..rust_end]).chars().count(); // 1-based rust_begin_char_offset + original_document[rust_begin..rust_end].chars().count(); // 1-based
if rust_begin_char_offset != begin || rust_end_char_offset != end { if rust_begin_char_offset != begin || rust_end_char_offset != end {
Err(format!("Rust bounds (in chars) ({rust_begin}, {rust_end}) do not match emacs bounds ({emacs_begin}, {emacs_end})", rust_begin = rust_begin_char_offset, rust_end = rust_end_char_offset, emacs_begin=begin, emacs_end=end))?; Err(format!("Rust bounds (in chars) ({rust_begin}, {rust_end}) do not match emacs bounds ({emacs_begin}, {emacs_end})", rust_begin = rust_begin_char_offset, rust_end = rust_end_char_offset, emacs_begin=begin, emacs_end=end))?;
} }
@ -113,8 +113,8 @@ struct EmacsStandardProperties {
post_blank: Option<usize>, post_blank: Option<usize>,
} }
fn get_emacs_standard_properties<'b, 's>( fn get_emacs_standard_properties(
emacs: &'b Token<'s>, emacs: &Token<'_>,
) -> Result<EmacsStandardProperties, Box<dyn std::error::Error>> { ) -> Result<EmacsStandardProperties, Box<dyn std::error::Error>> {
let children = emacs.as_list()?; let children = emacs.as_list()?;
let attributes_child = children.get(1).ok_or("Should have an attributes child.")?; let attributes_child = children.get(1).ok_or("Should have an attributes child.")?;
@ -124,7 +124,7 @@ fn get_emacs_standard_properties<'b, 's>(
let mut std_props = standard_properties let mut std_props = standard_properties
.expect("if statement proves its Some") .expect("if statement proves its Some")
.as_vector()? .as_vector()?
.into_iter(); .iter();
let begin = maybe_token_to_usize(std_props.next())?; let begin = maybe_token_to_usize(std_props.next())?;
let post_affiliated = maybe_token_to_usize(std_props.next())?; let post_affiliated = maybe_token_to_usize(std_props.next())?;
let contents_begin = maybe_token_to_usize(std_props.next())?; let contents_begin = maybe_token_to_usize(std_props.next())?;
@ -140,16 +140,13 @@ fn get_emacs_standard_properties<'b, 's>(
post_blank, post_blank,
} }
} else { } else {
let begin = maybe_token_to_usize(attributes_map.get(":begin").map(|token| *token))?; let begin = maybe_token_to_usize(attributes_map.get(":begin").copied())?;
let end = maybe_token_to_usize(attributes_map.get(":end").map(|token| *token))?; let end = maybe_token_to_usize(attributes_map.get(":end").copied())?;
let contents_begin = let contents_begin = maybe_token_to_usize(attributes_map.get(":contents-begin").copied())?;
maybe_token_to_usize(attributes_map.get(":contents-begin").map(|token| *token))?; let contents_end = maybe_token_to_usize(attributes_map.get(":contents-end").copied())?;
let contents_end = let post_blank = maybe_token_to_usize(attributes_map.get(":post-blank").copied())?;
maybe_token_to_usize(attributes_map.get(":contents-end").map(|token| *token))?;
let post_blank =
maybe_token_to_usize(attributes_map.get(":post-blank").map(|token| *token))?;
let post_affiliated = let post_affiliated =
maybe_token_to_usize(attributes_map.get(":post-affiliated").map(|token| *token))?; maybe_token_to_usize(attributes_map.get(":post-affiliated").copied())?;
EmacsStandardProperties { EmacsStandardProperties {
begin, begin,
post_affiliated, post_affiliated,
@ -167,62 +164,57 @@ fn maybe_token_to_usize(
Ok(token Ok(token
.map(|token| token.as_atom()) .map(|token| token.as_atom())
.map_or(Ok(None), |r| r.map(Some))? .map_or(Ok(None), |r| r.map(Some))?
.map(|val| { .and_then(|val| {
if val == "nil" { if val == "nil" {
None None
} else { } else {
Some(val.parse::<usize>()) Some(val.parse::<usize>())
} }
}) })
.flatten() // Outer option is whether or not the param exists, inner option is whether or not it is nil
.map_or(Ok(None), |r| r.map(Some))?) .map_or(Ok(None), |r| r.map(Some))?)
} }
/// Get a named property from the emacs token. /// Get a named property from the emacs token.
/// ///
/// Returns Ok(None) if value is nil or absent. /// Returns Ok(None) if value is nil or absent.
pub(crate) fn get_property<'b, 's, 'x>( pub(crate) fn get_property<'b, 's>(
emacs: &'b Token<'s>, emacs: &'b Token<'s>,
key: &'x str, key: &str,
) -> Result<Option<&'b Token<'s>>, Box<dyn std::error::Error>> { ) -> Result<Option<&'b Token<'s>>, Box<dyn std::error::Error>> {
let children = emacs.as_list()?; let children = emacs.as_list()?;
let attributes_child = children let attributes_child = children.get(1).ok_or("Should have an attributes child.")?;
.iter()
.nth(1)
.ok_or("Should have an attributes child.")?;
let attributes_map = attributes_child.as_map()?; let attributes_map = attributes_child.as_map()?;
let prop = attributes_map.get(key).map(|token| *token); let prop = attributes_map.get(key).copied();
match prop.map(|token| token.as_atom()) { if let Some(Ok("nil")) = prop.map(Token::as_atom) {
Some(Ok("nil")) => return Ok(None), return Ok(None);
_ => {} }
};
Ok(prop) Ok(prop)
} }
/// Get a named property containing an unquoted atom from the emacs token. /// Get a named property containing an unquoted atom from the emacs token.
/// ///
/// Returns None if key is not found. /// Returns None if key is not found.
pub(crate) fn get_property_unquoted_atom<'b, 's, 'x>( pub(crate) fn get_property_unquoted_atom<'s>(
emacs: &'b Token<'s>, emacs: &Token<'s>,
key: &'x str, key: &str,
) -> Result<Option<&'s str>, Box<dyn std::error::Error>> { ) -> Result<Option<&'s str>, Box<dyn std::error::Error>> {
Ok(get_property(emacs, key)? get_property(emacs, key)?
.map(Token::as_atom) .map(Token::as_atom)
.map_or(Ok(None), |r| r.map(Some))?) .map_or(Ok(None), |r| r.map(Some))
} }
/// Get a named property containing an quoted string from the emacs token. /// Get a named property containing an quoted string from the emacs token.
/// ///
/// Returns None if key is not found. /// Returns None if key is not found.
pub(crate) fn get_property_quoted_string<'b, 's, 'x>( pub(crate) fn get_property_quoted_string(
emacs: &'b Token<'s>, emacs: &Token<'_>,
key: &'x str, key: &str,
) -> Result<Option<String>, Box<dyn std::error::Error>> { ) -> Result<Option<String>, Box<dyn std::error::Error>> {
Ok(get_property(emacs, key)? get_property(emacs, key)?
.map(Token::as_atom) .map(Token::as_atom)
.map_or(Ok(None), |r| r.map(Some))? .map_or(Ok(None), |r| r.map(Some))?
.map(unquote) .map(unquote)
.map_or(Ok(None), |r| r.map(Some))?) .map_or(Ok(None), |r| r.map(Some))
} }
/// Get a named property containing an unquoted numeric value. /// Get a named property containing an unquoted numeric value.
@ -299,8 +291,8 @@ where
Ok(()) Ok(())
} }
pub(crate) fn assert_no_children<'b, 's>( pub(crate) fn assert_no_children(
emacs: &'b Token<'s>, emacs: &Token<'_>,
this_status: &mut DiffStatus, this_status: &mut DiffStatus,
message: &mut Option<String>, message: &mut Option<String>,
) -> Result<(), Box<dyn std::error::Error>> { ) -> Result<(), Box<dyn std::error::Error>> {
@ -329,7 +321,7 @@ where
let rust_key = rust_key.as_ref(); let rust_key = rust_key.as_ref();
let rust_value = rust_value.as_ref(); let rust_value = rust_value.as_ref();
let emacs_value = get_property_quoted_string(emacs, rust_key)?; let emacs_value = get_property_quoted_string(emacs, rust_key)?;
if Some(rust_value) != emacs_value.as_ref().map(String::as_str) { if Some(rust_value) != emacs_value.as_deref() {
let this_status = DiffStatus::Bad; let this_status = DiffStatus::Bad;
let message = Some(format!( let message = Some(format!(
"{} mismatch (emacs != rust) {:?} != {:?}", "{} mismatch (emacs != rust) {:?} != {:?}",

View File

@ -112,23 +112,18 @@ impl<'g, 'r, 's> Context<'g, 'r, 's> {
let mut current_class_filter = ExitClass::Gamma; let mut current_class_filter = ExitClass::Gamma;
for current_node in self.iter_context() { for current_node in self.iter_context() {
let context_element = current_node.get_data(); let context_element = current_node.get_data();
match context_element { if let ContextElement::ExitMatcherNode(exit_matcher) = context_element {
ContextElement::ExitMatcherNode(exit_matcher) => { if exit_matcher.class as u32 <= current_class_filter as u32 {
if exit_matcher.class as u32 <= current_class_filter as u32 { current_class_filter = exit_matcher.class;
current_class_filter = exit_matcher.class; let local_result = (exit_matcher.exit_matcher)(&current_node, i);
let local_result = (exit_matcher.exit_matcher)(&current_node, i); if local_result.is_ok() {
if local_result.is_ok() { return local_result;
return local_result;
}
} }
} }
_ => {} }
};
} }
// TODO: Make this a specific error instead of just a generic MyError // TODO: Make this a specific error instead of just a generic MyError
return Err(nom::Err::Error(CustomError::MyError(MyError( return Err(nom::Err::Error(CustomError::MyError(MyError("NoExit"))));
"NoExit".into(),
))));
} }
/// Indicates if elements should consume the whitespace after them. /// Indicates if elements should consume the whitespace after them.
@ -140,11 +135,8 @@ impl<'g, 'r, 's> Context<'g, 'r, 's> {
fn _should_consume_trailing_whitespace(&self) -> Option<bool> { fn _should_consume_trailing_whitespace(&self) -> Option<bool> {
for current_node in self.iter() { for current_node in self.iter() {
match current_node { if let ContextElement::ConsumeTrailingWhitespace(should) = current_node {
ContextElement::ConsumeTrailingWhitespace(should) => { return Some(*should);
return Some(*should);
}
_ => {}
} }
} }
None None

View File

@ -23,6 +23,6 @@ impl FileAccessInterface for LocalFileAccessInterface {
.as_deref() .as_deref()
.map(|pb| pb.join(path)) .map(|pb| pb.join(path))
.unwrap_or_else(|| PathBuf::from(path)); .unwrap_or_else(|| PathBuf::from(path));
Ok(std::fs::read_to_string(final_path)?) std::fs::read_to_string(final_path)
} }
} }

View File

@ -50,7 +50,7 @@ impl<'a, T> Iterator for Iter<'a, T> {
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
let ret = self.next.map(|link| link.get_data()); let ret = self.next.map(|link| link.get_data());
self.next = self.next.map(|link| link.get_parent()).flatten(); self.next = self.next.and_then(|link| link.get_parent());
ret ret
} }
} }

View File

@ -2,6 +2,7 @@ use crate::error::Res;
use crate::parser::OrgSource; use crate::parser::OrgSource;
mod constants; mod constants;
#[allow(clippy::module_inception)]
mod context; mod context;
mod exiting; mod exiting;
mod file_access_interface; mod file_access_interface;