Skip to content

Commit b7767ee

Browse files
committed
Split gf32::Error
The `gf32::Error` type is too general. Split the error into two separate error types so that `from_char` and `try_from` each return an error type in which all variants are used.
1 parent c5c028e commit b7767ee

File tree

1 file changed

+50
-18
lines changed

1 file changed

+50
-18
lines changed

src/primitives/gf32.rs

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -178,13 +178,16 @@ impl Fe32 {
178178

179179
/// Creates a field element from a single bech32 character.
180180
#[inline]
181-
pub fn from_char(c: char) -> Result<Fe32, Error> {
181+
pub fn from_char(c: char) -> Result<Fe32, FromCharError> {
182+
use FromCharError::*;
183+
182184
// i8::try_from gets a value in the range 0..=127 since char is unsigned.
183-
let byte = i8::try_from(u32::from(c)).map_err(|_| Error::InvalidChar(c))?;
185+
let byte = i8::try_from(u32::from(c)).map_err(|_| NotAscii(c))?;
184186
// Now we have a valid ASCII value cast is safe.
185187
let ascii = byte as usize;
186188
// We use -1 for any array element that is an invalid char to trigger error from u8::try_from
187-
let u5 = u8::try_from(CHARS_INV[ascii]).map_err(|_| Error::InvalidChar(c))?;
189+
let u5 = u8::try_from(CHARS_INV[ascii]).map_err(|_| Invalid(c))?;
190+
188191
Ok(Fe32(u5))
189192
}
190193

@@ -245,7 +248,7 @@ macro_rules! impl_try_from {
245248
($($ty:ident)+) => {
246249
$(
247250
impl TryFrom<$ty> for Fe32 {
248-
type Error = Error;
251+
type Error = TryFromError;
249252

250253
/// Tries to create an [`Fe32`] type from a signed source number type.
251254
///
@@ -256,7 +259,7 @@ macro_rules! impl_try_from {
256259
fn try_from(value: $ty) -> Result<Self, Self::Error> {
257260
let byte = u8::try_from(value)?;
258261
if byte > 31 {
259-
Err(Error::InvalidByte(byte))?;
262+
Err(TryFromError::InvalidByte(byte))?;
260263
}
261264
Ok(Fe32(byte))
262265
}
@@ -324,48 +327,77 @@ impl ops::DivAssign for Fe32 {
324327
fn div_assign(&mut self, other: Fe32) { *self = *self / other; }
325328
}
326329

327-
/// A galois field related error.
330+
/// A galois field error when converting from a character.
328331
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
329332
#[non_exhaustive]
330-
pub enum Error {
333+
pub enum FromCharError {
334+
/// Tried to interpret a character as a GF32 element but it is not an ASCII character.
335+
NotAscii(char),
336+
/// Tried to interpret a character as a GF32 element but it is not part of the bech32 character set.
337+
Invalid(char),
338+
}
339+
340+
impl fmt::Display for FromCharError {
341+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
342+
use FromCharError::*;
343+
344+
match *self {
345+
NotAscii(c) => write!(f, "non-ascii char in field element: {}", c),
346+
Invalid(c) => write!(f, "invalid char in field element: {}", c),
347+
}
348+
}
349+
}
350+
351+
#[cfg(feature = "std")]
352+
impl std::error::Error for FromCharError {
353+
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
354+
use FromCharError::*;
355+
356+
match *self {
357+
NotAscii(_) | Invalid(_) => None,
358+
}
359+
}
360+
}
361+
362+
/// A galois field error when converting from an integer.
363+
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
364+
#[non_exhaustive]
365+
pub enum TryFromError {
331366
/// Tried to interpret an integer as a GF32 element but it could not be converted to an u8.
332367
NotAByte(num::TryFromIntError),
333368
/// Tried to interpret a byte as a GF32 element but its numeric value was outside of [0, 32).
334369
InvalidByte(u8),
335-
/// Tried to interpret a character as a GF32 element but it is not part of the bech32 character set.
336-
InvalidChar(char),
337370
}
338371

339-
impl fmt::Display for Error {
372+
impl fmt::Display for TryFromError {
340373
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
341-
use Error::*;
374+
use TryFromError::*;
342375

343376
match *self {
344377
NotAByte(ref e) => write_err!(f, "invalid field element"; e),
345378
InvalidByte(ref b) => write!(f, "invalid byte in field element: {:#04x}", b),
346-
InvalidChar(ref c) => write!(f, "invalid char in field element: {}", c),
347379
}
348380
}
349381
}
350382

351383
#[cfg(feature = "std")]
352-
impl std::error::Error for Error {
384+
impl std::error::Error for TryFromError {
353385
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
354-
use Error::*;
386+
use TryFromError::*;
355387

356388
match *self {
357389
NotAByte(ref e) => Some(e),
358-
InvalidByte(_) | InvalidChar(_) => None,
390+
InvalidByte(_) => None,
359391
}
360392
}
361393
}
362394

363-
impl From<num::TryFromIntError> for Error {
395+
impl From<num::TryFromIntError> for TryFromError {
364396
#[inline]
365-
fn from(e: num::TryFromIntError) -> Self { Error::NotAByte(e) }
397+
fn from(e: num::TryFromIntError) -> Self { Self::NotAByte(e) }
366398
}
367399

368-
impl From<Infallible> for Error {
400+
impl From<Infallible> for TryFromError {
369401
#[inline]
370402
fn from(i: Infallible) -> Self { match i {} }
371403
}

0 commit comments

Comments
 (0)