Skip to content

Commit 6d489a7

Browse files
committed
Merge #164: Make from_char_unchecked public
ca2f840 Make from_char_unchecked public (Tobin C. Harding) b7767ee Split gf32::Error (Tobin C. Harding) Pull request description: - Patch 1 is an error type clean up, part of this PR because it improves the error type returned by `from_char`. - Patch 2 documents the error return of `from_char` and makes `from_char_unchecked` public. Fix: #161 ACKs for top commit: apoelstra: ACK ca2f840 Tree-SHA512: 758c7d9bdb5f5ac1e24b379376f87caf0a0ee2af32409ac4c7e1e009b822c7ee400d69c2cf991472e06acf4bd27e7d93521d08565f319fc125b48fe386f7b3f8
2 parents c5c028e + ca2f840 commit 6d489a7

File tree

1 file changed

+60
-19
lines changed

1 file changed

+60
-19
lines changed

src/primitives/gf32.rs

Lines changed: 60 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -177,18 +177,30 @@ impl Fe32 {
177177
}
178178

179179
/// Creates a field element from a single bech32 character.
180+
///
181+
/// # Errors
182+
///
183+
/// If the input char is not part of the bech32 alphabet.
180184
#[inline]
181-
pub fn from_char(c: char) -> Result<Fe32, Error> {
185+
pub fn from_char(c: char) -> Result<Fe32, FromCharError> {
186+
use FromCharError::*;
187+
182188
// 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))?;
189+
let byte = i8::try_from(u32::from(c)).map_err(|_| NotAscii(c))?;
184190
// Now we have a valid ASCII value cast is safe.
185191
let ascii = byte as usize;
186192
// 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))?;
193+
let u5 = u8::try_from(CHARS_INV[ascii]).map_err(|_| Invalid(c))?;
194+
188195
Ok(Fe32(u5))
189196
}
190197

191-
pub(crate) fn from_char_unchecked(c: u8) -> Fe32 { Fe32(CHARS_INV[usize::from(c)] as u8) }
198+
/// Creates a field element from a single bech32 character.
199+
///
200+
/// # Panics
201+
///
202+
/// If the input character is not part of the bech32 alphabet.
203+
pub fn from_char_unchecked(c: u8) -> Fe32 { Fe32(CHARS_INV[usize::from(c)] as u8) }
192204

193205
/// Converts the field element to a lowercase bech32 character.
194206
#[inline]
@@ -245,7 +257,7 @@ macro_rules! impl_try_from {
245257
($($ty:ident)+) => {
246258
$(
247259
impl TryFrom<$ty> for Fe32 {
248-
type Error = Error;
260+
type Error = TryFromError;
249261

250262
/// Tries to create an [`Fe32`] type from a signed source number type.
251263
///
@@ -256,7 +268,7 @@ macro_rules! impl_try_from {
256268
fn try_from(value: $ty) -> Result<Self, Self::Error> {
257269
let byte = u8::try_from(value)?;
258270
if byte > 31 {
259-
Err(Error::InvalidByte(byte))?;
271+
Err(TryFromError::InvalidByte(byte))?;
260272
}
261273
Ok(Fe32(byte))
262274
}
@@ -324,48 +336,77 @@ impl ops::DivAssign for Fe32 {
324336
fn div_assign(&mut self, other: Fe32) { *self = *self / other; }
325337
}
326338

327-
/// A galois field related error.
339+
/// A galois field error when converting from a character.
340+
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
341+
#[non_exhaustive]
342+
pub enum FromCharError {
343+
/// Tried to interpret a character as a GF32 element but it is not an ASCII character.
344+
NotAscii(char),
345+
/// Tried to interpret a character as a GF32 element but it is not part of the bech32 character set.
346+
Invalid(char),
347+
}
348+
349+
impl fmt::Display for FromCharError {
350+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
351+
use FromCharError::*;
352+
353+
match *self {
354+
NotAscii(c) => write!(f, "non-ascii char in field element: {}", c),
355+
Invalid(c) => write!(f, "invalid char in field element: {}", c),
356+
}
357+
}
358+
}
359+
360+
#[cfg(feature = "std")]
361+
impl std::error::Error for FromCharError {
362+
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
363+
use FromCharError::*;
364+
365+
match *self {
366+
NotAscii(_) | Invalid(_) => None,
367+
}
368+
}
369+
}
370+
371+
/// A galois field error when converting from an integer.
328372
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
329373
#[non_exhaustive]
330-
pub enum Error {
374+
pub enum TryFromError {
331375
/// Tried to interpret an integer as a GF32 element but it could not be converted to an u8.
332376
NotAByte(num::TryFromIntError),
333377
/// Tried to interpret a byte as a GF32 element but its numeric value was outside of [0, 32).
334378
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),
337379
}
338380

339-
impl fmt::Display for Error {
381+
impl fmt::Display for TryFromError {
340382
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
341-
use Error::*;
383+
use TryFromError::*;
342384

343385
match *self {
344386
NotAByte(ref e) => write_err!(f, "invalid field element"; e),
345387
InvalidByte(ref b) => write!(f, "invalid byte in field element: {:#04x}", b),
346-
InvalidChar(ref c) => write!(f, "invalid char in field element: {}", c),
347388
}
348389
}
349390
}
350391

351392
#[cfg(feature = "std")]
352-
impl std::error::Error for Error {
393+
impl std::error::Error for TryFromError {
353394
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
354-
use Error::*;
395+
use TryFromError::*;
355396

356397
match *self {
357398
NotAByte(ref e) => Some(e),
358-
InvalidByte(_) | InvalidChar(_) => None,
399+
InvalidByte(_) => None,
359400
}
360401
}
361402
}
362403

363-
impl From<num::TryFromIntError> for Error {
404+
impl From<num::TryFromIntError> for TryFromError {
364405
#[inline]
365-
fn from(e: num::TryFromIntError) -> Self { Error::NotAByte(e) }
406+
fn from(e: num::TryFromIntError) -> Self { Self::NotAByte(e) }
366407
}
367408

368-
impl From<Infallible> for Error {
409+
impl From<Infallible> for TryFromError {
369410
#[inline]
370411
fn from(i: Infallible) -> Self { match i {} }
371412
}

0 commit comments

Comments
 (0)