equal
deleted
inserted
replaced
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), |