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 = Result; -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), } } } 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/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()