# HG changeset patch # User Simon Sapin # Date 2021-02-08 10:13:56 # Node ID baa8a9c5a6fe9c9594a888e98fc13a73872edd3a # Parent a788e4bbbd6ef287138e9fba5c7da99170d4f66b rust: Use the DisplayBytes trait in config printing This is similar to `std::fmt::Display`, but for arbitrary bytes instead of Unicode. Writing to an abstract output stream helps avoid allocating intermediate `Vec` buffers. Differential Revision: https://phab.mercurial-scm.org/D9966 diff --git a/rust/Cargo.lock b/rust/Cargo.lock --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -244,16 +244,16 @@ dependencies = [ [[package]] name = "format-bytes" -version = "0.1.3" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "format-bytes-macros 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "format-bytes-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro-hack 0.5.19 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "format-bytes-macros" -version = "0.1.2" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro-hack 0.5.19 (registry+https://github.com/rust-lang/crates.io-index)", @@ -305,7 +305,7 @@ dependencies = [ "crossbeam-channel 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.99.11 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", - "format-bytes 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "format-bytes 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "home 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "im-rc 15.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -718,7 +718,7 @@ dependencies = [ "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.99.11 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "format-bytes 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "format-bytes 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "hg-core 0.1.0", "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", "micro-timer 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -965,8 +965,8 @@ dependencies = [ "checksum either 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" "checksum env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" "checksum flate2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)" = "7411863d55df97a419aa64cb4d2f167103ea9d767e2c54a1868b7ac3f6b47129" -"checksum format-bytes 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1a7374eb574cd29ae45878554298091c554c3286a17b3afa440a3e2710ae0790" -"checksum format-bytes-macros 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4edcc04201cea17a0e6b937adebd46b93fba09924c7e6ed8c515a35ce8432cbc" +"checksum format-bytes 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc35f5e45d6b31053cea13078ffc6fa52fa8617aa54b7ac2011720d9c009e04f" +"checksum format-bytes-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b05089e341a0460449e2210c3bf7b61597860b07f0deae58da38dbed0a4c6b6d" "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" "checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" "checksum getrandom 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6" diff --git a/rust/hg-core/Cargo.toml b/rust/hg-core/Cargo.toml --- a/rust/hg-core/Cargo.toml +++ b/rust/hg-core/Cargo.toml @@ -29,7 +29,7 @@ log = "0.4.8" memmap = "0.7.0" zstd = "0.5.3" rust-crypto = "0.2.36" -format-bytes = "0.1.2" +format-bytes = "0.2.0" # We don't use the `miniz-oxide` backend to not change rhg benchmarks and until # we have a clearer view of which backend is the fastest. diff --git a/rust/hg-core/src/config/config.rs b/rust/hg-core/src/config/config.rs --- a/rust/hg-core/src/config/config.rs +++ b/rust/hg-core/src/config/config.rs @@ -12,6 +12,7 @@ use crate::config::layer::{ ConfigError, ConfigLayer, ConfigParseError, ConfigValue, }; use crate::utils::files::get_bytes_from_path; +use format_bytes::{write_bytes, DisplayBytes}; use std::env; use std::path::{Path, PathBuf}; @@ -23,13 +24,22 @@ pub struct Config { layers: Vec, } -impl std::fmt::Debug for Config { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl DisplayBytes for Config { + fn display_bytes( + &self, + out: &mut dyn std::io::Write, + ) -> std::io::Result<()> { for (index, layer) in self.layers.iter().rev().enumerate() { - write!( - f, - "==== Layer {} (trusted: {}) ====\n{:?}", - index, layer.trusted, layer + write_bytes!( + out, + b"==== Layer {} (trusted: {}) ====\n{}", + index, + if layer.trusted { + &b"yes"[..] + } else { + &b"no"[..] + }, + layer )?; } Ok(()) diff --git a/rust/hg-core/src/config/layer.rs b/rust/hg-core/src/config/layer.rs --- a/rust/hg-core/src/config/layer.rs +++ b/rust/hg-core/src/config/layer.rs @@ -9,7 +9,7 @@ use crate::errors::{HgError, IoResultExt}; use crate::utils::files::{get_bytes_from_path, get_path_from_bytes}; -use format_bytes::format_bytes; +use format_bytes::{write_bytes, DisplayBytes}; use lazy_static::lazy_static; use regex::bytes::Regex; use std::collections::HashMap; @@ -165,8 +165,11 @@ impl ConfigLayer { } } -impl std::fmt::Debug for ConfigLayer { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl DisplayBytes for ConfigLayer { + fn display_bytes( + &self, + out: &mut dyn std::io::Write, + ) -> std::io::Result<()> { let mut sections: Vec<_> = self.sections.iter().collect(); sections.sort_by(|e0, e1| e0.0.cmp(e1.0)); @@ -175,16 +178,13 @@ impl std::fmt::Debug for ConfigLayer { items.sort_by(|e0, e1| e0.0.cmp(e1.0)); for (item, config_entry) in items { - writeln!( - f, - "{}", - String::from_utf8_lossy(&format_bytes!( - b"{}.{}={} # {}", - section, - item, - &config_entry.bytes, - &self.origin.to_bytes(), - )) + write_bytes!( + out, + b"{}.{}={} # {}\n", + section, + item, + &config_entry.bytes, + &self.origin, )? } } @@ -224,13 +224,15 @@ pub enum ConfigOrigin { * Others? */ } -impl ConfigOrigin { - /// TODO use some kind of dedicated trait? - pub fn to_bytes(&self) -> Vec { +impl DisplayBytes for ConfigOrigin { + fn display_bytes( + &self, + out: &mut dyn std::io::Write, + ) -> std::io::Result<()> { match self { - ConfigOrigin::File(p) => get_bytes_from_path(p), - ConfigOrigin::CommandLine => b"--config".to_vec(), - ConfigOrigin::Environment(e) => format_bytes!(b"${}", e), + ConfigOrigin::File(p) => out.write_all(&get_bytes_from_path(p)), + ConfigOrigin::CommandLine => out.write_all(b"--config"), + ConfigOrigin::Environment(e) => write_bytes!(out, b"${}", e), } } } diff --git a/rust/rhg/Cargo.toml b/rust/rhg/Cargo.toml --- a/rust/rhg/Cargo.toml +++ b/rust/rhg/Cargo.toml @@ -14,4 +14,4 @@ derive_more = "0.99" log = "0.4.11" micro-timer = "0.3.1" env_logger = "0.7.1" -format-bytes = "0.1.3" +format-bytes = "0.2.0" diff --git a/rust/rhg/src/error.rs b/rust/rhg/src/error.rs --- a/rust/rhg/src/error.rs +++ b/rust/rhg/src/error.rs @@ -90,7 +90,7 @@ impl From for CommandE CommandError::Abort { message: format_bytes!( b"config parse error in {}{}: '{}'", - origin.to_bytes(), + origin, line_message, bytes ),