From f086bb0353645ddf9d4b6247af45e67be95139a5 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 26 Mar 2018 22:28:55 -0700 Subject: [PATCH] Change ParseBigIntError to an opaque struct --- src/biguint.rs | 14 +++----------- src/lib.rs | 49 +++++++++++++++++++++++++++++++++---------------- 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/src/biguint.rs b/src/biguint.rs index c3c391bb..0866a02b 100644 --- a/src/biguint.rs +++ b/src/biguint.rs @@ -230,16 +230,12 @@ impl Num for BigUint { } if s.is_empty() { - // create ParseIntError::Empty - let e = u64::from_str_radix(s, radix).unwrap_err(); - return Err(e.into()); + return Err(ParseBigIntError::empty()); } if s.starts_with('_') { // Must lead with a real digit! - // create ParseIntError::InvalidDigit - let e = u64::from_str_radix(s, radix).unwrap_err(); - return Err(e.into()); + return Err(ParseBigIntError::invalid()); } // First normalize all characters to plain digit values @@ -255,11 +251,7 @@ impl Num for BigUint { if d < radix as u8 { v.push(d); } else { - // create ParseIntError::InvalidDigit - // Include the previous character for context. - let i = cmp::max(v.len(), 1) - 1; - let e = u64::from_str_radix(&s[i..], radix).unwrap_err(); - return Err(e.into()); + return Err(ParseBigIntError::invalid()); } } diff --git a/src/lib.rs b/src/lib.rs index 57bbf10f..13f53871 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -87,7 +87,6 @@ extern crate num_integer as integer; extern crate num_traits as traits; use std::error::Error; -use std::num::ParseIntError; use std::fmt; #[cfg(target_pointer_width = "32")] @@ -100,30 +99,48 @@ type IsizePromotion = i32; #[cfg(target_pointer_width = "64")] type IsizePromotion = i64; -#[derive(Debug, PartialEq)] -pub enum ParseBigIntError { - ParseInt(ParseIntError), - Other, +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ParseBigIntError { + kind: BigIntErrorKind, } -impl fmt::Display for ParseBigIntError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - &ParseBigIntError::ParseInt(ref e) => e.fmt(f), - &ParseBigIntError::Other => "failed to parse provided string".fmt(f), +#[derive(Debug, Clone, PartialEq, Eq)] +enum BigIntErrorKind { + Empty, + InvalidDigit, +} + +impl ParseBigIntError { + fn __description(&self) -> &str { + use BigIntErrorKind::*; + match self.kind { + Empty => "cannot parse integer from empty string", + InvalidDigit => "invalid digit found in string", + } + } + + fn empty() -> Self { + ParseBigIntError { + kind: BigIntErrorKind::Empty, + } + } + + fn invalid() -> Self { + ParseBigIntError { + kind: BigIntErrorKind::InvalidDigit, } } } -impl Error for ParseBigIntError { - fn description(&self) -> &str { - "failed to parse bigint/biguint" +impl fmt::Display for ParseBigIntError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.__description().fmt(f) } } -impl From for ParseBigIntError { - fn from(err: ParseIntError) -> ParseBigIntError { - ParseBigIntError::ParseInt(err) +impl Error for ParseBigIntError { + fn description(&self) -> &str { + self.__description() } }