Skip to content

Commit d73c686

Browse files
committed
Rename error types to convey their semantics
If a downstream library decodes a hex string into a particular type using a function in this library the returned error type would "leak" which type the library used internally. The specific type shouldn't really concern the callers since it can change anyway. What is relevant though is whether the length is known at compile time or not. We might also add more functions in the future decoding to different types and it'd be better to share error types in such case. This change renames `HexToBytesError` to `DecodeDynSizedBytesError` and `HexToArrayError` to `DecodeFixedSizedBytesError` so that types are not mentioned.
1 parent 8386dc6 commit d73c686

File tree

6 files changed

+50
-44
lines changed

6 files changed

+50
-44
lines changed

examples/hexy.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
use std::fmt;
99
use std::str::FromStr;
1010

11-
use hex_conservative::{fmt_hex_exact, Case, DisplayHex as _, FromHex as _, HexToArrayError};
11+
use hex_conservative::{
12+
fmt_hex_exact, Case, DecodeFixedSizedBytesError, DisplayHex as _, FromHex as _,
13+
};
1214

1315
fn main() {
1416
let s = "deadbeefcafebabedeadbeefcafebabedeadbeefcafebabedeadbeefcafebabe";
@@ -46,7 +48,7 @@ impl fmt::Display for Hexy {
4648
}
4749

4850
impl FromStr for Hexy {
49-
type Err = HexToArrayError;
51+
type Err = DecodeFixedSizedBytesError;
5052

5153
fn from_str(s: &str) -> Result<Self, Self::Err> {
5254
// Errors if the input is invalid

examples/wrap_array.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
use core::fmt;
88
use core::str::FromStr;
99

10-
use hex_conservative::{DisplayHex as _, FromHex as _, HexToArrayError};
10+
use hex_conservative::{DecodeFixedSizedBytesError, DisplayHex as _, FromHex as _};
1111

1212
fn main() {
1313
let hex = "deadbeefcafebabedeadbeefcafebabedeadbeefcafebabedeadbeefcafebabe";
@@ -72,6 +72,6 @@ impl fmt::UpperHex for Wrap {
7272
}
7373

7474
impl FromStr for Wrap {
75-
type Err = HexToArrayError;
75+
type Err = DecodeFixedSizedBytesError;
7676
fn from_str(s: &str) -> Result<Self, Self::Err> { Ok(Self(<[u8; 32]>::from_hex(s)?)) }
7777
}

src/error.rs

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -70,17 +70,17 @@ pub(crate) use write_err;
7070
/// This represents the first error encountered during decoding, however we may add other remaining
7171
/// ones in the future.
7272
///
73-
/// This error differs from [`HexToArrayError`] in that the number of bytes is only known at
74-
/// run time - e.g. when decoding `Vec<u8>`.
73+
/// This error differs from [`DecodeFixedSizedBytesError`] in that the number of bytes is only known
74+
/// at run time - e.g. when decoding `Vec<u8>`.
7575
#[derive(Debug, Clone, PartialEq, Eq)]
76-
pub enum HexToBytesError {
76+
pub enum DecodeDynSizedBytesError {
7777
/// Non-hexadecimal character.
7878
InvalidChar(InvalidCharError),
7979
/// Purported hex string had odd (not even) length.
8080
OddLengthString(OddLengthStringError),
8181
}
8282

83-
impl HexToBytesError {
83+
impl DecodeDynSizedBytesError {
8484
/// Adds `by_bytes` to all character positions stored inside.
8585
///
8686
/// If you're parsing a larger string that consists of multiple hex sub-strings and want to
@@ -97,7 +97,7 @@ impl HexToBytesError {
9797
#[must_use]
9898
#[inline]
9999
pub fn offset(self, by_bytes: usize) -> Self {
100-
use HexToBytesError as E;
100+
use DecodeDynSizedBytesError as E;
101101

102102
match self {
103103
E::InvalidChar(e) => E::InvalidChar(e.offset(by_bytes)),
@@ -106,15 +106,15 @@ impl HexToBytesError {
106106
}
107107
}
108108

109-
impl From<Infallible> for HexToBytesError {
109+
impl From<Infallible> for DecodeDynSizedBytesError {
110110
#[inline]
111111
fn from(never: Infallible) -> Self { match never {} }
112112
}
113113

114-
impl fmt::Display for HexToBytesError {
114+
impl fmt::Display for DecodeDynSizedBytesError {
115115
#[inline]
116116
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
117-
use HexToBytesError as E;
117+
use DecodeDynSizedBytesError as E;
118118

119119
match *self {
120120
E::InvalidChar(ref e) => write_err!(f, "failed to decode hex"; e),
@@ -124,10 +124,10 @@ impl fmt::Display for HexToBytesError {
124124
}
125125

126126
if_std_error! {{
127-
impl StdError for HexToBytesError {
127+
impl StdError for DecodeDynSizedBytesError {
128128
#[inline]
129129
fn source(&self) -> Option<&(dyn StdError + 'static)> {
130-
use HexToBytesError as E;
130+
use DecodeDynSizedBytesError as E;
131131

132132
match *self {
133133
E::InvalidChar(ref e) => Some(e),
@@ -137,12 +137,12 @@ if_std_error! {{
137137
}
138138
}}
139139

140-
impl From<InvalidCharError> for HexToBytesError {
140+
impl From<InvalidCharError> for DecodeDynSizedBytesError {
141141
#[inline]
142142
fn from(e: InvalidCharError) -> Self { Self::InvalidChar(e) }
143143
}
144144

145-
impl From<OddLengthStringError> for HexToBytesError {
145+
impl From<OddLengthStringError> for DecodeDynSizedBytesError {
146146
#[inline]
147147
fn from(e: OddLengthStringError) -> Self { Self::OddLengthString(e) }
148148
}
@@ -169,7 +169,7 @@ impl InvalidCharError {
169169

170170
/// Adds `by_bytes` to all character positions stored inside.
171171
///
172-
/// **Important**: if you have `HexToBytesError` or `HexToArrayError` you
172+
/// **Important**: if you have `DecodeDynSizedBytesError` or `DecodeFixedSizedBytesError` you
173173
/// should call the method *on them* - do not match them and manually call this method. Doing
174174
/// so may lead to broken behavior in the future.
175175
///
@@ -280,17 +280,17 @@ if_std_error! {{
280280

281281
/// Error returned when hex decoding bytes whose length is known at compile time.
282282
///
283-
/// This error differs from [`HexToBytesError`] in that the number of bytes is known at
283+
/// This error differs from [`DecodeDynSizedBytesError`] in that the number of bytes is known at
284284
/// compile time - e.g. when decoding to an array of bytes.
285285
#[derive(Debug, Clone, PartialEq, Eq)]
286-
pub enum HexToArrayError {
286+
pub enum DecodeFixedSizedBytesError {
287287
/// Non-hexadecimal character.
288288
InvalidChar(InvalidCharError),
289289
/// Tried to parse fixed-length hash from a string with the wrong length.
290290
InvalidLength(InvalidLengthError),
291291
}
292292

293-
impl HexToArrayError {
293+
impl DecodeFixedSizedBytesError {
294294
/// Adds `by_bytes` to all character positions stored inside.
295295
///
296296
/// If you're parsing a larger string that consists of multiple hex sub-strings and want to
@@ -307,7 +307,7 @@ impl HexToArrayError {
307307
#[must_use]
308308
#[inline]
309309
pub fn offset(self, by_bytes: usize) -> Self {
310-
use HexToArrayError as E;
310+
use DecodeFixedSizedBytesError as E;
311311

312312
match self {
313313
E::InvalidChar(e) => E::InvalidChar(e.offset(by_bytes)),
@@ -316,15 +316,15 @@ impl HexToArrayError {
316316
}
317317
}
318318

319-
impl From<Infallible> for HexToArrayError {
319+
impl From<Infallible> for DecodeFixedSizedBytesError {
320320
#[inline]
321321
fn from(never: Infallible) -> Self { match never {} }
322322
}
323323

324-
impl fmt::Display for HexToArrayError {
324+
impl fmt::Display for DecodeFixedSizedBytesError {
325325
#[inline]
326326
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
327-
use HexToArrayError as E;
327+
use DecodeFixedSizedBytesError as E;
328328

329329
match *self {
330330
E::InvalidChar(ref e) => write_err!(f, "failed to parse hex"; e),
@@ -334,10 +334,10 @@ impl fmt::Display for HexToArrayError {
334334
}
335335

336336
if_std_error! {{
337-
impl StdError for HexToArrayError {
337+
impl StdError for DecodeFixedSizedBytesError {
338338
#[inline]
339339
fn source(&self) -> Option<&(dyn StdError + 'static)> {
340-
use HexToArrayError as E;
340+
use DecodeFixedSizedBytesError as E;
341341

342342
match *self {
343343
E::InvalidChar(ref e) => Some(e),
@@ -347,12 +347,12 @@ if_std_error! {{
347347
}
348348
}}
349349

350-
impl From<InvalidCharError> for HexToArrayError {
350+
impl From<InvalidCharError> for DecodeFixedSizedBytesError {
351351
#[inline]
352352
fn from(e: InvalidCharError) -> Self { Self::InvalidChar(e) }
353353
}
354354

355-
impl From<InvalidLengthError> for HexToArrayError {
355+
impl From<InvalidLengthError> for DecodeFixedSizedBytesError {
356356
#[inline]
357357
fn from(e: InvalidLengthError) -> Self { Self::InvalidLength(e) }
358358
}
@@ -421,7 +421,7 @@ mod tests {
421421
fn invalid_char_error() {
422422
let result = <Vec<u8> as FromHex>::from_hex("12G4");
423423
let error = result.unwrap_err();
424-
if let HexToBytesError::InvalidChar(e) = error {
424+
if let DecodeDynSizedBytesError::InvalidChar(e) = error {
425425
assert!(!format!("{}", e).is_empty());
426426
assert_eq!(e.invalid_char(), b'G');
427427
assert_eq!(e.pos(), 2);
@@ -437,7 +437,7 @@ mod tests {
437437
let error = result.unwrap_err();
438438
assert!(!format!("{}", error).is_empty());
439439
check_source(&error);
440-
if let HexToBytesError::OddLengthString(e) = error {
440+
if let DecodeDynSizedBytesError::OddLengthString(e) = error {
441441
assert!(!format!("{}", e).is_empty());
442442
assert_eq!(e.length(), 3);
443443
} else {
@@ -451,7 +451,7 @@ mod tests {
451451
let error = result.unwrap_err();
452452
assert!(!format!("{}", error).is_empty());
453453
check_source(&error);
454-
if let HexToArrayError::InvalidLength(e) = error {
454+
if let DecodeFixedSizedBytesError::InvalidLength(e) = error {
455455
assert!(!format!("{}", e).is_empty());
456456
assert_eq!(e.expected_length(), 8);
457457
assert_eq!(e.invalid_length(), 3);
@@ -462,14 +462,17 @@ mod tests {
462462

463463
#[test]
464464
fn to_bytes_error() {
465-
let error = HexToBytesError::OddLengthString(OddLengthStringError { len: 7 });
465+
let error = DecodeDynSizedBytesError::OddLengthString(OddLengthStringError { len: 7 });
466466
assert!(!format!("{}", error).is_empty());
467467
check_source(&error);
468468
}
469469

470470
#[test]
471471
fn to_array_error() {
472-
let error = HexToArrayError::InvalidLength(InvalidLengthError { expected: 8, invalid: 7 });
472+
let error = DecodeFixedSizedBytesError::InvalidLength(InvalidLengthError {
473+
expected: 8,
474+
invalid: 7,
475+
});
473476
assert!(!format!("{}", error).is_empty());
474477
check_source(&error);
475478
}

src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ pub(crate) use table::Table;
113113
pub use self::{
114114
display::DisplayHex,
115115
error::{
116-
HexToArrayError, HexToBytesError, InvalidCharError, InvalidLengthError,
116+
DecodeFixedSizedBytesError, DecodeDynSizedBytesError, InvalidCharError, InvalidLengthError,
117117
OddLengthStringError,
118118
},
119119
iter::{BytesToHexIter, HexToBytesIter, HexSliceToBytesIter},
@@ -130,11 +130,11 @@ pub use self::{
130130
///
131131
/// Returns an error if `hex` contains invalid characters or doesn't have even length.
132132
#[cfg(feature = "alloc")]
133-
pub fn decode_to_vec(hex: &str) -> Result<Vec<u8>, HexToBytesError> {
133+
pub fn decode_to_vec(hex: &str) -> Result<Vec<u8>, DecodeDynSizedBytesError> {
134134
Ok(HexToBytesIter::new(hex)?.drain_to_vec()?)
135135
}
136136

137-
/// Decodes a hex string with an expected length kown at compile time.
137+
/// Decodes a hex string with an expected length known at compile time.
138138
///
139139
/// If you don't know the required length at compile time you need to use [`decode_to_vec`]
140140
/// instead.
@@ -143,7 +143,7 @@ pub fn decode_to_vec(hex: &str) -> Result<Vec<u8>, HexToBytesError> {
143143
///
144144
/// Returns an error if `hex` contains invalid characters or has incorrect length. (Should be
145145
/// `N * 2`.)
146-
pub fn decode_to_array<const N: usize>(hex: &str) -> Result<[u8; N], HexToArrayError> {
146+
pub fn decode_to_array<const N: usize>(hex: &str) -> Result<[u8; N], DecodeFixedSizedBytesError> {
147147
if hex.len() == N * 2 {
148148
let mut ret = [0u8; N];
149149
// checked above

src/parse.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use core::{fmt, str};
88
use crate::alloc::vec::Vec;
99

1010
#[rustfmt::skip] // Keep public re-exports separate.
11-
pub use crate::error::{HexToBytesError, HexToArrayError};
11+
pub use crate::error::{DecodeDynSizedBytesError, DecodeFixedSizedBytesError};
1212

1313
/// Trait for objects that can be deserialized from hex strings.
1414
pub trait FromHex: Sized + sealed::Sealed {
@@ -25,14 +25,14 @@ pub trait FromHex: Sized + sealed::Sealed {
2525

2626
#[cfg(feature = "alloc")]
2727
impl FromHex for Vec<u8> {
28-
type Error = HexToBytesError;
28+
type Error = DecodeDynSizedBytesError;
2929

3030
#[inline]
3131
fn from_hex(s: &str) -> Result<Self, Self::Error> { crate::decode_to_vec(s) }
3232
}
3333

3434
impl<const LEN: usize> FromHex for [u8; LEN] {
35-
type Error = HexToArrayError;
35+
type Error = DecodeFixedSizedBytesError;
3636

3737
fn from_hex(s: &str) -> Result<Self, Self::Error> { crate::decode_to_array(s) }
3838
}

tests/api.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ use core::{fmt, slice};
1717
use hex_conservative::serde;
1818
// These imports test "typical" usage by user code.
1919
use hex_conservative::{
20-
buf_encoder, display, BytesToHexIter, Case, DisplayHex as _, HexToArrayError, HexToBytesError,
21-
InvalidCharError, InvalidLengthError, OddLengthStringError,
20+
buf_encoder, display, BytesToHexIter, Case, DecodeDynSizedBytesError,
21+
DecodeFixedSizedBytesError, DisplayHex as _, InvalidCharError, InvalidLengthError,
22+
OddLengthStringError,
2223
};
2324

2425
/// A struct that includes all public non-error enums.
@@ -86,8 +87,8 @@ impl Structs<'_, slice::Iter<'_, u8>, String> {
8687
// These derives are the policy of `rust-bitcoin` not Rust API guidelines.
8788
#[derive(Debug, Clone, PartialEq, Eq)] // All public types implement Debug (C-DEBUG).
8889
struct Errors {
89-
c: HexToArrayError,
90-
d: HexToBytesError,
90+
c: DecodeFixedSizedBytesError,
91+
d: DecodeDynSizedBytesError,
9192
e: InvalidCharError,
9293
f: InvalidLengthError,
9394
g: OddLengthStringError,

0 commit comments

Comments
 (0)