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),