Show More
@@ -9,7 +9,7 b' pub mod node;' | |||
|
9 | 9 | pub mod nodemap; |
|
10 | 10 | mod nodemap_docket; |
|
11 | 11 | pub mod path_encode; |
|
12 |
pub use node::{ |
|
|
12 | pub use node::{FromHexError, Node, NodePrefix, NodePrefixRef}; | |
|
13 | 13 | pub mod changelog; |
|
14 | 14 | pub mod index; |
|
15 | 15 | pub mod manifest; |
@@ -9,7 +9,7 b'' | |||
|
9 | 9 | //! of a revision. |
|
10 | 10 | |
|
11 | 11 | use bytes_cast::BytesCast; |
|
12 |
use hex::{self, FromHex |
|
|
12 | use hex::{self, FromHex}; | |
|
13 | 13 | use std::convert::TryFrom; |
|
14 | 14 | use std::fmt; |
|
15 | 15 | |
@@ -47,10 +47,9 b' type NodeData = [u8; NODE_BYTES_LENGTH];' | |||
|
47 | 47 | /// if they need a loop boundary. |
|
48 | 48 | /// |
|
49 | 49 | /// All methods that create a `Node` either take a type that enforces |
|
50 | /// the size or fail immediately at runtime with [`ExactLengthRequired`]. | |
|
50 | /// the size or return an error at runtime. | |
|
51 | 51 | /// |
|
52 | 52 | /// [`nybbles_len`]: #method.nybbles_len |
|
53 | /// [`ExactLengthRequired`]: struct.NodeError#variant.ExactLengthRequired | |
|
54 | 53 | #[derive(Clone, Debug, PartialEq, BytesCast)] |
|
55 | 54 | #[repr(transparent)] |
|
56 | 55 | pub struct Node { |
@@ -90,12 +89,8 b' impl fmt::LowerHex for Node {' | |||
|
90 | 89 | } |
|
91 | 90 | } |
|
92 | 91 | |
|
93 |
#[derive(Debug |
|
|
94 | pub enum NodeError { | |
|
95 | ExactLengthRequired(usize, String), | |
|
96 | PrefixTooLong(String), | |
|
97 | HexError(FromHexError, String), | |
|
98 | } | |
|
92 | #[derive(Debug)] | |
|
93 | pub struct FromHexError; | |
|
99 | 94 | |
|
100 | 95 | /// Low level utility function, also for prefixes |
|
101 | 96 | fn get_nybble(s: &[u8], i: usize) -> u8 { |
@@ -128,9 +123,9 b' impl Node {' | |||
|
128 | 123 | /// |
|
129 | 124 | /// To be used in FFI and I/O only, in order to facilitate future |
|
130 | 125 | /// changes of hash format. |
|
131 |
pub fn from_hex(hex: impl AsRef<[u8]>) -> Result<Node, |
|
|
126 | pub fn from_hex(hex: impl AsRef<[u8]>) -> Result<Node, FromHexError> { | |
|
132 | 127 | Ok(NodeData::from_hex(hex.as_ref()) |
|
133 |
.map_err(| |
|
|
128 | .map_err(|_| FromHexError)? | |
|
134 | 129 | .into()) |
|
135 | 130 | } |
|
136 | 131 | |
@@ -143,19 +138,6 b' impl Node {' | |||
|
143 | 138 | } |
|
144 | 139 | } |
|
145 | 140 | |
|
146 | impl<T: AsRef<[u8]>> From<(FromHexError, T)> for NodeError { | |
|
147 | fn from(err_offender: (FromHexError, T)) -> Self { | |
|
148 | let (err, offender) = err_offender; | |
|
149 | let offender = String::from_utf8_lossy(offender.as_ref()).into_owned(); | |
|
150 | match err { | |
|
151 | FromHexError::InvalidStringLength => { | |
|
152 | NodeError::ExactLengthRequired(NODE_NYBBLES_LENGTH, offender) | |
|
153 | } | |
|
154 | _ => NodeError::HexError(err, offender), | |
|
155 | } | |
|
156 | } | |
|
157 | } | |
|
158 | ||
|
159 | 141 | /// The beginning of a binary revision SHA. |
|
160 | 142 | /// |
|
161 | 143 | /// Since it can potentially come from an hexadecimal representation with |
@@ -175,31 +157,22 b' impl NodePrefix {' | |||
|
175 | 157 | /// |
|
176 | 158 | /// To be used in FFI and I/O only, in order to facilitate future |
|
177 | 159 | /// changes of hash format. |
|
178 |
pub fn from_hex(hex: impl AsRef<[u8]>) -> Result<Self, |
|
|
160 | pub fn from_hex(hex: impl AsRef<[u8]>) -> Result<Self, FromHexError> { | |
|
179 | 161 | let hex = hex.as_ref(); |
|
180 | 162 | let len = hex.len(); |
|
181 | 163 | if len > NODE_NYBBLES_LENGTH { |
|
182 |
return Err( |
|
|
183 | String::from_utf8_lossy(hex).to_owned().to_string(), | |
|
184 | )); | |
|
164 | return Err(FromHexError); | |
|
185 | 165 | } |
|
186 | 166 | |
|
187 | 167 | let is_odd = len % 2 == 1; |
|
188 | 168 | let even_part = if is_odd { &hex[..len - 1] } else { hex }; |
|
189 | 169 | let mut buf: Vec<u8> = |
|
190 |
Vec::from_hex(&even_part).map_err(| |
|
|
170 | Vec::from_hex(&even_part).map_err(|_| FromHexError)?; | |
|
191 | 171 | |
|
192 | 172 | if is_odd { |
|
193 | 173 | let latest_char = char::from(hex[len - 1]); |
|
194 |
let latest_nybble = |
|
|
195 | ( | |
|
196 | FromHexError::InvalidHexCharacter { | |
|
197 | c: latest_char, | |
|
198 | index: len - 1, | |
|
199 | }, | |
|
200 | hex, | |
|
201 | ) | |
|
202 | })? as u8; | |
|
174 | let latest_nybble = | |
|
175 | latest_char.to_digit(16).ok_or_else(|| FromHexError)? as u8; | |
|
203 | 176 | buf.push(latest_nybble << 4); |
|
204 | 177 | } |
|
205 | 178 | Ok(NodePrefix { buf, is_odd }) |
@@ -329,24 +302,15 b' mod tests {' | |||
|
329 | 302 | |
|
330 | 303 | #[test] |
|
331 | 304 | fn test_node_from_hex() { |
|
332 |
assert_eq!(Node::from_hex(&sample_node_hex()), |
|
|
305 | assert_eq!(Node::from_hex(&sample_node_hex()).unwrap(), sample_node()); | |
|
333 | 306 | |
|
334 | 307 | let mut short = hex_pad_right("0123"); |
|
335 | 308 | short.pop(); |
|
336 | 309 | short.pop(); |
|
337 | assert_eq!( | |
|
338 | Node::from_hex(&short), | |
|
339 | Err(NodeError::ExactLengthRequired(NODE_NYBBLES_LENGTH, short)), | |
|
340 | ); | |
|
310 | assert!(Node::from_hex(&short).is_err()); | |
|
341 | 311 | |
|
342 | 312 | let not_hex = hex_pad_right("012... oops"); |
|
343 | assert_eq!( | |
|
344 | Node::from_hex(¬_hex), | |
|
345 | Err(NodeError::HexError( | |
|
346 | FromHexError::InvalidHexCharacter { c: '.', index: 3 }, | |
|
347 | not_hex, | |
|
348 | )), | |
|
349 | ); | |
|
313 | assert!(Node::from_hex(¬_hex).is_err(),); | |
|
350 | 314 | } |
|
351 | 315 | |
|
352 | 316 | #[test] |
@@ -355,7 +319,7 b' mod tests {' | |||
|
355 | 319 | } |
|
356 | 320 | |
|
357 | 321 | #[test] |
|
358 |
fn test_prefix_from_hex() -> Result<(), |
|
|
322 | fn test_prefix_from_hex() -> Result<(), FromHexError> { | |
|
359 | 323 | assert_eq!( |
|
360 | 324 | NodePrefix::from_hex("0e1")?, |
|
361 | 325 | NodePrefix { |
@@ -386,25 +350,14 b' mod tests {' | |||
|
386 | 350 | |
|
387 | 351 | #[test] |
|
388 | 352 | fn test_prefix_from_hex_errors() { |
|
389 | assert_eq!( | |
|
390 | NodePrefix::from_hex("testgr"), | |
|
391 | Err(NodeError::HexError( | |
|
392 | FromHexError::InvalidHexCharacter { c: 't', index: 0 }, | |
|
393 | "testgr".to_string() | |
|
394 | )) | |
|
395 | ); | |
|
353 | assert!(NodePrefix::from_hex("testgr").is_err()); | |
|
396 | 354 | let mut long = format!("{:x}", NULL_NODE); |
|
397 | 355 | long.push('c'); |
|
398 |
|
|
|
399 | .expect_err("should be refused as too long") | |
|
400 | { | |
|
401 | NodeError::PrefixTooLong(s) => assert_eq!(s, long), | |
|
402 | err => panic!(format!("Should have been TooLong, got {:?}", err)), | |
|
403 | } | |
|
356 | assert!(NodePrefix::from_hex(&long).is_err()) | |
|
404 | 357 | } |
|
405 | 358 | |
|
406 | 359 | #[test] |
|
407 |
fn test_is_prefix_of() -> Result<(), |
|
|
360 | fn test_is_prefix_of() -> Result<(), FromHexError> { | |
|
408 | 361 | let mut node_data = [0; NODE_BYTES_LENGTH]; |
|
409 | 362 | node_data[0] = 0x12; |
|
410 | 363 | node_data[1] = 0xca; |
@@ -417,7 +370,7 b' mod tests {' | |||
|
417 | 370 | } |
|
418 | 371 | |
|
419 | 372 | #[test] |
|
420 |
fn test_get_nybble() -> Result<(), |
|
|
373 | fn test_get_nybble() -> Result<(), FromHexError> { | |
|
421 | 374 | let prefix = NodePrefix::from_hex("dead6789cafe")?; |
|
422 | 375 | assert_eq!(prefix.borrow().get_nybble(0), 13); |
|
423 | 376 | assert_eq!(prefix.borrow().get_nybble(7), 9); |
@@ -13,7 +13,7 b'' | |||
|
13 | 13 | //! is used in a more abstract context. |
|
14 | 14 | |
|
15 | 15 | use super::{ |
|
16 |
node::NULL_NODE, |
|
|
16 | node::NULL_NODE, FromHexError, Node, NodePrefix, NodePrefixRef, Revision, | |
|
17 | 17 | RevlogIndex, NULL_REVISION, |
|
18 | 18 | }; |
|
19 | 19 | |
@@ -27,14 +27,14 b' use std::ops::Index;' | |||
|
27 | 27 | #[derive(Debug, PartialEq)] |
|
28 | 28 | pub enum NodeMapError { |
|
29 | 29 | MultipleResults, |
|
30 |
InvalidNodePrefix |
|
|
30 | InvalidNodePrefix, | |
|
31 | 31 | /// A `Revision` stored in the nodemap could not be found in the index |
|
32 | 32 | RevisionNotInIndex(Revision), |
|
33 | 33 | } |
|
34 | 34 | |
|
35 |
impl From< |
|
|
36 |
fn from( |
|
|
37 |
NodeMapError::InvalidNodePrefix |
|
|
35 | impl From<FromHexError> for NodeMapError { | |
|
36 | fn from(_: FromHexError) -> Self { | |
|
37 | NodeMapError::InvalidNodePrefix | |
|
38 | 38 | } |
|
39 | 39 | } |
|
40 | 40 |
@@ -18,7 +18,7 b' use cpython::{' | |||
|
18 | 18 | use hg::{ |
|
19 | 19 | nodemap::{Block, NodeMapError, NodeTree}, |
|
20 | 20 | revlog::{nodemap::NodeMap, RevlogIndex}, |
|
21 |
|
|
|
21 | Revision, | |
|
22 | 22 | }; |
|
23 | 23 | use std::cell::RefCell; |
|
24 | 24 | |
@@ -468,15 +468,10 b' fn nodemap_error(py: Python, err: NodeMa' | |||
|
468 | 468 | match err { |
|
469 | 469 | NodeMapError::MultipleResults => revlog_error(py), |
|
470 | 470 | NodeMapError::RevisionNotInIndex(r) => rev_not_in_index(py, r), |
|
471 |
NodeMapError::InvalidNodePrefix |
|
|
471 | NodeMapError::InvalidNodePrefix => { | |
|
472 | PyErr::new::<ValueError, _>(py, "Invalid node or prefix") | |
|
472 | 473 | } |
|
473 | 474 | } |
|
474 | ||
|
475 | fn invalid_node_prefix(py: Python, ne: &NodeError) -> PyErr { | |
|
476 | PyErr::new::<ValueError, _>( | |
|
477 | py, | |
|
478 | format!("Invalid node or prefix: {:?}", ne), | |
|
479 | ) | |
|
480 | 475 | } |
|
481 | 476 | |
|
482 | 477 | /// Create the module, with __package__ given from parent |
General Comments 0
You need to be logged in to leave comments.
Login now