Patchwork D9904: rust: replace ToString impls with Display

login
register
mail settings
Submitter phabricator
Date Jan. 28, 2021, 7:40 p.m.
Message ID <differential-rev-PHID-DREV-zp5mgrfq3v3nj52sh2lo-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/48215/
State Superseded
Headers show

Comments

phabricator - Jan. 28, 2021, 7:40 p.m.
SimonSapin created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  ToString is automatically implementing for everything that implements
  Display, and Display can avoid allocating intermediate strings.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D9904

AFFECTED FILES
  rust/hg-core/src/dirstate/status.rs
  rust/hg-core/src/lib.rs
  rust/hg-core/src/utils/hg_path.rs

CHANGE DETAILS




To: SimonSapin, #hg-reviewers
Cc: mercurial-patches, mercurial-devel

Patch

diff --git a/rust/hg-core/src/utils/hg_path.rs b/rust/hg-core/src/utils/hg_path.rs
--- a/rust/hg-core/src/utils/hg_path.rs
+++ b/rust/hg-core/src/utils/hg_path.rs
@@ -47,57 +47,68 @@ 
     },
 }
 
-impl ToString for HgPathError {
-    fn to_string(&self) -> String {
+impl fmt::Display for HgPathError {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self {
             HgPathError::LeadingSlash(bytes) => {
-                format!("Invalid HgPath '{:?}': has a leading slash.", bytes)
+                write!(f, "Invalid HgPath '{:?}': has a leading slash.", bytes)
             }
             HgPathError::ConsecutiveSlashes {
                 bytes,
                 second_slash_index: pos,
-            } => format!(
+            } => write!(
+                f,
                 "Invalid HgPath '{:?}': consecutive slashes at pos {}.",
                 bytes, pos
             ),
             HgPathError::ContainsNullByte {
                 bytes,
                 null_byte_index: pos,
-            } => format!(
+            } => write!(
+                f,
                 "Invalid HgPath '{:?}': contains null byte at pos {}.",
                 bytes, pos
             ),
-            HgPathError::DecodeError(bytes) => {
-                format!("Invalid HgPath '{:?}': could not be decoded.", bytes)
-            }
+            HgPathError::DecodeError(bytes) => write!(
+                f,
+                "Invalid HgPath '{:?}': could not be decoded.",
+                bytes
+            ),
             HgPathError::EndsWithSlash(path) => {
-                format!("Audit failed for '{}': ends with a slash.", path)
+                write!(f, "Audit failed for '{}': ends with a slash.", path)
             }
-            HgPathError::ContainsIllegalComponent(path) => format!(
+            HgPathError::ContainsIllegalComponent(path) => write!(
+                f,
                 "Audit failed for '{}': contains an illegal component.",
                 path
             ),
-            HgPathError::InsideDotHg(path) => format!(
+            HgPathError::InsideDotHg(path) => write!(
+                f,
                 "Audit failed for '{}': is inside the '.hg' folder.",
                 path
             ),
             HgPathError::IsInsideNestedRepo {
                 path,
                 nested_repo: nested,
-            } => format!(
+            } => {
+                write!(f,
                 "Audit failed for '{}': is inside a nested repository '{}'.",
                 path, nested
-            ),
-            HgPathError::TraversesSymbolicLink { path, symlink } => format!(
+            )
+            }
+            HgPathError::TraversesSymbolicLink { path, symlink } => write!(
+                f,
                 "Audit failed for '{}': traverses symbolic link '{}'.",
                 path, symlink
             ),
-            HgPathError::NotFsCompliant(path) => format!(
+            HgPathError::NotFsCompliant(path) => write!(
+                f,
                 "Audit failed for '{}': cannot be turned into a \
                  filesystem path.",
                 path
             ),
-            HgPathError::NotUnderRoot { path, root } => format!(
+            HgPathError::NotUnderRoot { path, root } => write!(
+                f,
                 "Audit failed for '{}': not under root {}.",
                 path.display(),
                 root.display()
diff --git a/rust/hg-core/src/lib.rs b/rust/hg-core/src/lib.rs
--- a/rust/hg-core/src/lib.rs
+++ b/rust/hg-core/src/lib.rs
@@ -39,6 +39,7 @@ 
     PatternFileWarning, PatternSyntax,
 };
 use std::collections::HashMap;
+use std::fmt;
 use twox_hash::RandomXxHashBuilder64;
 
 /// This is a contract between the `micro-timer` crate and us, to expose
@@ -59,14 +60,16 @@ 
     InvalidPath(HgPathError),
 }
 
-impl ToString for DirstateMapError {
-    fn to_string(&self) -> String {
+impl fmt::Display for DirstateMapError {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self {
             DirstateMapError::PathNotFound(_) => {
-                "expected a value, found none".to_string()
+                f.write_str("expected a value, found none")
             }
-            DirstateMapError::EmptyPath => "Overflow in dirstate.".to_string(),
-            DirstateMapError::InvalidPath(e) => e.to_string(),
+            DirstateMapError::EmptyPath => {
+                f.write_str("Overflow in dirstate.")
+            }
+            DirstateMapError::InvalidPath(path_error) => path_error.fmt(f),
         }
     }
 }
@@ -91,25 +94,26 @@ 
     NonRegexPattern(IgnorePattern),
 }
 
-impl ToString for PatternError {
-    fn to_string(&self) -> String {
+impl fmt::Display for PatternError {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self {
             PatternError::UnsupportedSyntax(syntax) => {
-                format!("Unsupported syntax {}", syntax)
+                write!(f, "Unsupported syntax {}", syntax)
             }
             PatternError::UnsupportedSyntaxInFile(syntax, file_path, line) => {
-                format!(
+                write!(
+                    f,
                     "{}:{}: unsupported syntax {}",
                     file_path, line, syntax
                 )
             }
             PatternError::TooLong(size) => {
-                format!("matcher pattern is too long ({} bytes)", size)
+                write!(f, "matcher pattern is too long ({} bytes)", size)
             }
-            PatternError::IO(e) => e.to_string(),
-            PatternError::Path(e) => e.to_string(),
+            PatternError::IO(error) => error.fmt(f),
+            PatternError::Path(error) => error.fmt(f),
             PatternError::NonRegexPattern(pattern) => {
-                format!("'{:?}' cannot be turned into a regex", pattern)
+                write!(f, "'{:?}' cannot be turned into a regex", pattern)
             }
         }
     }
diff --git a/rust/hg-core/src/dirstate/status.rs b/rust/hg-core/src/dirstate/status.rs
--- a/rust/hg-core/src/dirstate/status.rs
+++ b/rust/hg-core/src/dirstate/status.rs
@@ -33,6 +33,7 @@ 
 use std::{
     borrow::Cow,
     collections::HashSet,
+    fmt,
     fs::{read_dir, DirEntry},
     io::ErrorKind,
     ops::Deref,
@@ -51,17 +52,16 @@ 
     Unknown,
 }
 
-impl ToString for BadType {
-    fn to_string(&self) -> String {
-        match self {
+impl fmt::Display for BadType {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.write_str(match self {
             BadType::CharacterDevice => "character device",
             BadType::BlockDevice => "block device",
             BadType::FIFO => "fifo",
             BadType::Socket => "socket",
             BadType::Directory => "directory",
             BadType::Unknown => "unknown",
-        }
-        .to_string()
+        })
     }
 }
 
@@ -277,12 +277,12 @@ 
 
 pub type StatusResult<T> = Result<T, StatusError>;
 
-impl ToString for StatusError {
-    fn to_string(&self) -> String {
+impl fmt::Display for StatusError {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self {
-            StatusError::IO(e) => e.to_string(),
-            StatusError::Path(e) => e.to_string(),
-            StatusError::Pattern(e) => e.to_string(),
+            StatusError::IO(error) => error.fmt(f),
+            StatusError::Path(error) => error.fmt(f),
+            StatusError::Pattern(error) => error.fmt(f),
         }
     }
 }