comparison rust/hg-core/src/config/layer.rs @ 46499:eace48b4a786

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<u8>` buffers. Differential Revision: https://phab.mercurial-scm.org/D9966
author Simon Sapin <simon.sapin@octobus.net>
date Mon, 08 Feb 2021 11:13:56 +0100
parents d7685105e504
children 2e5dd18d6dc3
comparison
equal deleted inserted replaced
46498:3caa3698335e 46499:eace48b4a786
7 // This software may be used and distributed according to the terms of the 7 // This software may be used and distributed according to the terms of the
8 // GNU General Public License version 2 or any later version. 8 // GNU General Public License version 2 or any later version.
9 9
10 use crate::errors::{HgError, IoResultExt}; 10 use crate::errors::{HgError, IoResultExt};
11 use crate::utils::files::{get_bytes_from_path, get_path_from_bytes}; 11 use crate::utils::files::{get_bytes_from_path, get_path_from_bytes};
12 use format_bytes::format_bytes; 12 use format_bytes::{write_bytes, DisplayBytes};
13 use lazy_static::lazy_static; 13 use lazy_static::lazy_static;
14 use regex::bytes::Regex; 14 use regex::bytes::Regex;
15 use std::collections::HashMap; 15 use std::collections::HashMap;
16 use std::path::{Path, PathBuf}; 16 use std::path::{Path, PathBuf};
17 17
163 } 163 }
164 Ok(layers) 164 Ok(layers)
165 } 165 }
166 } 166 }
167 167
168 impl std::fmt::Debug for ConfigLayer { 168 impl DisplayBytes for ConfigLayer {
169 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 169 fn display_bytes(
170 &self,
171 out: &mut dyn std::io::Write,
172 ) -> std::io::Result<()> {
170 let mut sections: Vec<_> = self.sections.iter().collect(); 173 let mut sections: Vec<_> = self.sections.iter().collect();
171 sections.sort_by(|e0, e1| e0.0.cmp(e1.0)); 174 sections.sort_by(|e0, e1| e0.0.cmp(e1.0));
172 175
173 for (section, items) in sections.into_iter() { 176 for (section, items) in sections.into_iter() {
174 let mut items: Vec<_> = items.into_iter().collect(); 177 let mut items: Vec<_> = items.into_iter().collect();
175 items.sort_by(|e0, e1| e0.0.cmp(e1.0)); 178 items.sort_by(|e0, e1| e0.0.cmp(e1.0));
176 179
177 for (item, config_entry) in items { 180 for (item, config_entry) in items {
178 writeln!( 181 write_bytes!(
179 f, 182 out,
180 "{}", 183 b"{}.{}={} # {}\n",
181 String::from_utf8_lossy(&format_bytes!( 184 section,
182 b"{}.{}={} # {}", 185 item,
183 section, 186 &config_entry.bytes,
184 item, 187 &self.origin,
185 &config_entry.bytes,
186 &self.origin.to_bytes(),
187 ))
188 )? 188 )?
189 } 189 }
190 } 190 }
191 Ok(()) 191 Ok(())
192 } 192 }
222 * TODO extensions 222 * TODO extensions
223 * TODO Python resources? 223 * TODO Python resources?
224 * Others? */ 224 * Others? */
225 } 225 }
226 226
227 impl ConfigOrigin { 227 impl DisplayBytes for ConfigOrigin {
228 /// TODO use some kind of dedicated trait? 228 fn display_bytes(
229 pub fn to_bytes(&self) -> Vec<u8> { 229 &self,
230 out: &mut dyn std::io::Write,
231 ) -> std::io::Result<()> {
230 match self { 232 match self {
231 ConfigOrigin::File(p) => get_bytes_from_path(p), 233 ConfigOrigin::File(p) => out.write_all(&get_bytes_from_path(p)),
232 ConfigOrigin::CommandLine => b"--config".to_vec(), 234 ConfigOrigin::CommandLine => out.write_all(b"--config"),
233 ConfigOrigin::Environment(e) => format_bytes!(b"${}", e), 235 ConfigOrigin::Environment(e) => write_bytes!(out, b"${}", e),
234 } 236 }
235 } 237 }
236 } 238 }
237 239
238 #[derive(Debug)] 240 #[derive(Debug)]