Mercurial > hg
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)] |