diff --git a/src/diff/dijkstra.rs b/src/diff/dijkstra.rs index 8fe86748c..627e7280d 100644 --- a/src/diff/dijkstra.rs +++ b/src/diff/dijkstra.rs @@ -156,33 +156,20 @@ fn edge_between<'s, 'v>(before: &Vertex<'s, 'v>, after: &Vertex<'s, 'v>) -> Edge /// What is the total number of AST nodes? fn node_count(root: Option<&Syntax>) -> u32 { - let mut node = root; - let mut count = 0; - while let Some(current_node) = node { - let current_count = match current_node { - Syntax::List { - num_descendants, .. - } => *num_descendants, - Syntax::Atom { .. } => 1, - }; - count += current_count; - - node = current_node.next_sibling(); - } - - count + let iter = std::iter::successors(root, |node| node.next_sibling()); + + iter.map(|node| match node { + Syntax::List { + num_descendants, .. + } => *num_descendants, + Syntax::Atom { .. } => 1, + }) + .sum::() } /// How many top-level AST nodes do we have? fn tree_count(root: Option<&Syntax>) -> u32 { - let mut node = root; - let mut count = 0; - while let Some(current_node) = node { - count += 1; - node = current_node.next_sibling(); - } - - count + std::iter::successors(root, |node| node.next_sibling()).count() as _ } pub(crate) fn mark_syntax<'a>( diff --git a/src/diff/graph.rs b/src/diff/graph.rs index 60092a159..833658a6c 100644 --- a/src/diff/graph.rs +++ b/src/diff/graph.rs @@ -138,14 +138,14 @@ enum EnteredDelimiter<'s, 'v> { impl fmt::Debug for EnteredDelimiter<'_, '_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let desc = match self { - EnteredDelimiter::PopEither((lhs_delims, rhs_delims)) => { + Self::PopEither((lhs_delims, rhs_delims)) => { format!( "PopEither(lhs count: {}, rhs count: {})", lhs_delims.size(), rhs_delims.size() ) } - EnteredDelimiter::PopBoth(_) => "PopBoth".to_owned(), + Self::PopBoth(_) => "PopBoth".to_owned(), }; f.write_str(&desc) } diff --git a/src/diff/stack.rs b/src/diff/stack.rs index d29d9a46e..1e845c223 100644 --- a/src/diff/stack.rs +++ b/src/diff/stack.rs @@ -24,11 +24,11 @@ impl<'b, T> Stack<'b, T> { self.head.map(|n| &n.val) } - pub(crate) fn pop(&self) -> Option> { + pub(crate) fn pop(&self) -> Option { self.head.map(|n| Self { head: n.next }) } - pub(crate) fn push(&self, v: T, alloc: &'b Bump) -> Stack<'b, T> { + pub(crate) fn push(&self, v: T, alloc: &'b Bump) -> Self { Self { head: Some(alloc.alloc(Node { val: v, @@ -39,13 +39,7 @@ impl<'b, T> Stack<'b, T> { // O(n) pub(crate) fn size(&self) -> usize { - let mut count = 0; - let mut node = &self.head; - while let Some(next) = node { - count += 1; - node = &next.next; - } - count + std::iter::successors(self.head, |&n| n.next).count() } pub(crate) fn is_empty(&self) -> bool { diff --git a/src/display/hunks.rs b/src/display/hunks.rs index 7841f922c..6e8f3688c 100644 --- a/src/display/hunks.rs +++ b/src/display/hunks.rs @@ -66,7 +66,7 @@ impl Hunk { )); } - Hunk { + Self { novel_lhs: self.novel_lhs.union(&other.novel_lhs).copied().collect(), novel_rhs: self.novel_rhs.union(&other.novel_rhs).copied().collect(), lines: deduped_lines, diff --git a/src/display/json.rs b/src/display/json.rs index 39d4df933..4ab9753a7 100644 --- a/src/display/json.rs +++ b/src/display/json.rs @@ -32,11 +32,7 @@ struct File<'f> { } impl<'f> File<'f> { - fn with_sections( - language: &'f FileFormat, - path: &'f str, - chunks: Vec>>, - ) -> File<'f> { + fn with_sections(language: &'f FileFormat, path: &'f str, chunks: Vec>>) -> Self { File { language, path, @@ -45,7 +41,7 @@ impl<'f> File<'f> { } } - fn with_status(language: &'f FileFormat, path: &'f str, status: Status) -> File<'f> { + fn with_status(language: &'f FileFormat, path: &'f str, status: Status) -> Self { File { language, path, @@ -201,7 +197,7 @@ struct Line<'l> { } impl<'l> Line<'l> { - fn new(lhs_number: Option, rhs_number: Option) -> Line<'l> { + fn new(lhs_number: Option, rhs_number: Option) -> Self { Line { lhs: lhs_number.map(Side::new), rhs: rhs_number.map(Side::new), @@ -216,7 +212,7 @@ struct Side<'s> { } impl<'s> Side<'s> { - fn new(line_number: u32) -> Side<'s> { + fn new(line_number: u32) -> Self { Side { line_number, changes: Vec::new(), @@ -259,15 +255,15 @@ impl Highlight { }; match highlight { - TokenKind::Delimiter => Highlight::Delimiter, + TokenKind::Delimiter => Self::Delimiter, TokenKind::Atom(atom) => match atom { - AtomKind::String(StringKind::StringLiteral) => Highlight::String, - AtomKind::String(StringKind::Text) => Highlight::Normal, - AtomKind::Keyword => Highlight::Keyword, - AtomKind::Comment => Highlight::Comment, - AtomKind::Type => Highlight::Type, - AtomKind::Normal => Highlight::Normal, - AtomKind::TreeSitterError => Highlight::TreeSitterError, + AtomKind::String(StringKind::StringLiteral) => Self::String, + AtomKind::String(StringKind::Text) => Self::Normal, + AtomKind::Keyword => Self::Keyword, + AtomKind::Comment => Self::Comment, + AtomKind::Type => Self::Type, + AtomKind::Normal => Self::Normal, + AtomKind::TreeSitterError => Self::TreeSitterError, }, } } diff --git a/src/display/style.rs b/src/display/style.rs index c6556a3d0..462f9889e 100644 --- a/src/display/style.rs +++ b/src/display/style.rs @@ -26,7 +26,7 @@ pub(crate) enum BackgroundColor { impl BackgroundColor { pub(crate) fn is_dark(self) -> bool { - matches!(self, BackgroundColor::Dark) + matches!(self, Self::Dark) } } diff --git a/src/options.rs b/src/options.rs index 6e736531a..6231cf947 100644 --- a/src/options.rs +++ b/src/options.rs @@ -398,7 +398,7 @@ pub(crate) enum FileArgument { impl FileArgument { pub(crate) fn permissions(&self) -> Option { match self { - FileArgument::NamedPath(path) => { + Self::NamedPath(path) => { // When used with `git difftool`, the first argument // is a temporary file that always has the same // permissions. That doesn't mean the file permissions @@ -410,8 +410,8 @@ impl FileArgument { let metadata = std::fs::metadata(path).ok()?; Some(metadata.permissions().into()) } - FileArgument::Stdin => None, - FileArgument::DevNull => None, + Self::Stdin => None, + Self::DevNull => None, } } } @@ -484,11 +484,11 @@ impl FileArgument { /// argument. pub(crate) fn from_cli_argument(arg: &OsStr) -> Self { if arg == "/dev/null" { - FileArgument::DevNull + Self::DevNull } else if arg == "-" { - FileArgument::Stdin + Self::Stdin } else { - FileArgument::NamedPath(PathBuf::from(arg)) + Self::NamedPath(PathBuf::from(arg)) } } @@ -497,9 +497,9 @@ impl FileArgument { pub(crate) fn from_path_argument(arg: &OsStr) -> Self { // For new and deleted files, Git passes `/dev/null` as the reference file. if arg == "/dev/null" { - FileArgument::DevNull + Self::DevNull } else { - FileArgument::NamedPath(PathBuf::from(arg)) + Self::NamedPath(PathBuf::from(arg)) } } } @@ -507,11 +507,11 @@ impl FileArgument { impl Display for FileArgument { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - FileArgument::NamedPath(path) => { + Self::NamedPath(path) => { write!(f, "{}", relative_to_current(path).display()) } - FileArgument::Stdin => write!(f, "(stdin)"), - FileArgument::DevNull => write!(f, "/dev/null"), + Self::Stdin => write!(f, "(stdin)"), + Self::DevNull => write!(f, "/dev/null"), } } } diff --git a/src/parse/guess_language.rs b/src/parse/guess_language.rs index 0f0a01625..d2c96dd08 100644 --- a/src/parse/guess_language.rs +++ b/src/parse/guess_language.rs @@ -525,54 +525,51 @@ fn from_emacs_mode_header(src: &str) -> Option { (Some(cap), _) | (_, Some(cap)) => cap[1].into(), _ => "".into(), }; - let lang = match mode_name.to_ascii_lowercase().trim() { - "ada" => Some(Ada), - "c" => Some(C), - "clojure" => Some(Clojure), - "csharp" => Some(CSharp), - "css" => Some(Css), - "dart" => Some(Dart), - "c++" => Some(CPlusPlus), - "elixir" => Some(Elixir), - "elm" => Some(Elm), - "elvish" => Some(Elvish), - "emacs-lisp" => Some(EmacsLisp), - "fsharp" => Some(FSharp), - "gleam" => Some(Gleam), - "go" => Some(Go), - "haskell" => Some(Haskell), - "hcl" => Some(Hcl), - "html" => Some(Html), - "janet" => Some(Janet), - "java" => Some(Java), - "js" | "js2" => Some(JavaScript), - "lisp" => Some(CommonLisp), - "nxml" => Some(Xml), - "objc" => Some(ObjC), - "perl" => Some(Perl), - "python" => Some(Python), - "racket" => Some(Racket), - "rjsx" => Some(JavascriptJsx), - "ruby" => Some(Ruby), - "rust" => Some(Rust), - "scala" => Some(Scala), - "scss" => Some(Scss), - "sh" => Some(Bash), - "solidity" => Some(Solidity), - "sql" => Some(Sql), - "swift" => Some(Swift), - "toml" => Some(Toml), - "tuareg" => Some(OCaml), - "typescript" => Some(TypeScript), - "verilog" => Some(Verilog), - "vhdl" => Some(Vhdl), - "yaml" => Some(Yaml), - "zig" => Some(Zig), - _ => None, - }; - if lang.is_some() { - return lang; - } + return Some(match mode_name.to_ascii_lowercase().trim() { + "ada" => Ada, + "c" => C, + "clojure" => Clojure, + "csharp" => CSharp, + "css" => Css, + "dart" => Dart, + "c++" => CPlusPlus, + "elixir" => Elixir, + "elm" => Elm, + "elvish" => Elvish, + "emacs-lisp" => EmacsLisp, + "fsharp" => FSharp, + "gleam" => Gleam, + "go" => Go, + "haskell" => Haskell, + "hcl" => Hcl, + "html" => Html, + "janet" => Janet, + "java" => Java, + "js" | "js2" => JavaScript, + "lisp" => CommonLisp, + "nxml" => Xml, + "objc" => ObjC, + "perl" => Perl, + "python" => Python, + "racket" => Racket, + "rjsx" => JavascriptJsx, + "ruby" => Ruby, + "rust" => Rust, + "scala" => Scala, + "scss" => Scss, + "sh" => Bash, + "solidity" => Solidity, + "sql" => Sql, + "swift" => Swift, + "toml" => Toml, + "tuareg" => OCaml, + "typescript" => TypeScript, + "verilog" => Verilog, + "vhdl" => Vhdl, + "yaml" => Yaml, + "zig" => Zig, + _ => continue, + }); } None diff --git a/src/parse/syntax.rs b/src/parse/syntax.rs index 8e3bb445a..33143e39e 100644 --- a/src/parse/syntax.rs +++ b/src/parse/syntax.rs @@ -196,13 +196,13 @@ impl<'a> fmt::Debug for Syntax<'a> { impl<'a> Syntax<'a> { pub(crate) fn new_list( - arena: &'a Arena>, + arena: &'a Arena, open_content: &str, open_position: Vec, - children: Vec<&'a Syntax<'a>>, + children: Vec<&'a Self>, close_content: &str, close_position: Vec, - ) -> &'a Syntax<'a> { + ) -> &'a Self { // Skip empty atoms: they aren't displayed, so there's no // point making our syntax tree bigger. These occur when we're // parsing incomplete or malformed programs. @@ -249,11 +249,11 @@ impl<'a> Syntax<'a> { } pub(crate) fn new_atom( - arena: &'a Arena>, + arena: &'a Arena, mut position: Vec, mut content: String, kind: AtomKind, - ) -> &'a Syntax<'a> { + ) -> &'a Self { // If a parser hasn't cleaned up \r on CRLF files with // comments, discard it. if content.ends_with('\r') { @@ -283,11 +283,11 @@ impl<'a> Syntax<'a> { } } - pub(crate) fn parent(&self) -> Option<&'a Syntax<'a>> { + pub(crate) fn parent(&self) -> Option<&'a Self> { self.info().parent.get() } - pub(crate) fn next_sibling(&self) -> Option<&'a Syntax<'a>> { + pub(crate) fn next_sibling(&self) -> Option<&'a Self> { self.info().next_sibling.get() } @@ -681,9 +681,7 @@ impl MatchKind { pub(crate) fn is_novel(&self) -> bool { matches!( self, - MatchKind::Novel { .. } - | MatchKind::NovelWord { .. } - | MatchKind::UnchangedPartOfNovelItem { .. } + Self::Novel { .. } | Self::NovelWord { .. } | Self::UnchangedPartOfNovelItem { .. } ) } } diff --git a/src/summary.rs b/src/summary.rs index 4308d30a6..d466fdf5a 100644 --- a/src/summary.rs +++ b/src/summary.rs @@ -27,10 +27,10 @@ pub(crate) enum FileFormat { impl Display for FileFormat { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - FileFormat::SupportedLanguage(language) => write!(f, "{}", language_name(*language)), - FileFormat::PlainText => write!(f, "Text"), - FileFormat::TextFallback { reason } => write!(f, "Text ({})", reason), - FileFormat::Binary => write!(f, "Binary"), + Self::SupportedLanguage(language) => write!(f, "{}", language_name(*language)), + Self::PlainText => write!(f, "Text"), + Self::TextFallback { reason } => write!(f, "Text ({})", reason), + Self::Binary => write!(f, "Binary"), } } }