Mercurial > hg
comparison rust/hg-core/src/revlog/node.rs @ 46427:6380efb82191
rust: replace Node::encode_hex with std::fmt::LowerHex
This avoids allocating intermediate strings.
Differential Revision: https://phab.mercurial-scm.org/D9860
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Mon, 25 Jan 2021 12:00:23 +0100 |
parents | cfb6c10c08c2 |
children | 5893706af3de |
comparison
equal
deleted
inserted
replaced
46426:0da465780bba | 46427:6380efb82191 |
---|---|
9 //! of a revision. | 9 //! of a revision. |
10 | 10 |
11 use bytes_cast::BytesCast; | 11 use bytes_cast::BytesCast; |
12 use hex::{self, FromHex, FromHexError}; | 12 use hex::{self, FromHex, FromHexError}; |
13 use std::convert::TryFrom; | 13 use std::convert::TryFrom; |
14 use std::fmt; | |
14 | 15 |
15 /// The length in bytes of a `Node` | 16 /// The length in bytes of a `Node` |
16 /// | 17 /// |
17 /// This constant is meant to ease refactors of this module, and | 18 /// This constant is meant to ease refactors of this module, and |
18 /// are private so that calling code does not expect all nodes have | 19 /// are private so that calling code does not expect all nodes have |
78 _ => Err(()), | 79 _ => Err(()), |
79 } | 80 } |
80 } | 81 } |
81 } | 82 } |
82 | 83 |
84 impl fmt::LowerHex for Node { | |
85 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
86 for &byte in &self.data { | |
87 write!(f, "{:02x}", byte)? | |
88 } | |
89 Ok(()) | |
90 } | |
91 } | |
92 | |
83 #[derive(Debug, PartialEq)] | 93 #[derive(Debug, PartialEq)] |
84 pub enum NodeError { | 94 pub enum NodeError { |
85 ExactLengthRequired(usize, String), | 95 ExactLengthRequired(usize, String), |
86 PrefixTooLong(String), | 96 PrefixTooLong(String), |
87 HexError(FromHexError, String), | 97 HexError(FromHexError, String), |
120 /// changes of hash format. | 130 /// changes of hash format. |
121 pub fn from_hex(hex: impl AsRef<[u8]>) -> Result<Node, NodeError> { | 131 pub fn from_hex(hex: impl AsRef<[u8]>) -> Result<Node, NodeError> { |
122 Ok(NodeData::from_hex(hex.as_ref()) | 132 Ok(NodeData::from_hex(hex.as_ref()) |
123 .map_err(|e| NodeError::from((e, hex)))? | 133 .map_err(|e| NodeError::from((e, hex)))? |
124 .into()) | 134 .into()) |
125 } | |
126 | |
127 /// Convert to hexadecimal string representation | |
128 /// | |
129 /// To be used in FFI and I/O only, in order to facilitate future | |
130 /// changes of hash format. | |
131 pub fn encode_hex(&self) -> String { | |
132 hex::encode(self.data) | |
133 } | 135 } |
134 | 136 |
135 /// Provide access to binary data | 137 /// Provide access to binary data |
136 /// | 138 /// |
137 /// This is needed by FFI layers, for instance to return expected | 139 /// This is needed by FFI layers, for instance to return expected |
347 ); | 349 ); |
348 } | 350 } |
349 | 351 |
350 #[test] | 352 #[test] |
351 fn test_node_encode_hex() { | 353 fn test_node_encode_hex() { |
352 assert_eq!(sample_node().encode_hex(), sample_node_hex()); | 354 assert_eq!(format!("{:x}", sample_node()), sample_node_hex()); |
353 } | 355 } |
354 | 356 |
355 #[test] | 357 #[test] |
356 fn test_prefix_from_hex() -> Result<(), NodeError> { | 358 fn test_prefix_from_hex() -> Result<(), NodeError> { |
357 assert_eq!( | 359 assert_eq!( |
389 Err(NodeError::HexError( | 391 Err(NodeError::HexError( |
390 FromHexError::InvalidHexCharacter { c: 't', index: 0 }, | 392 FromHexError::InvalidHexCharacter { c: 't', index: 0 }, |
391 "testgr".to_string() | 393 "testgr".to_string() |
392 )) | 394 )) |
393 ); | 395 ); |
394 let mut long = NULL_NODE.encode_hex(); | 396 let mut long = format!("{:x}", NULL_NODE); |
395 long.push('c'); | 397 long.push('c'); |
396 match NodePrefix::from_hex(&long) | 398 match NodePrefix::from_hex(&long) |
397 .expect_err("should be refused as too long") | 399 .expect_err("should be refused as too long") |
398 { | 400 { |
399 NodeError::PrefixTooLong(s) => assert_eq!(s, long), | 401 NodeError::PrefixTooLong(s) => assert_eq!(s, long), |