diff --git a/const-oid/src/checked.rs b/const-oid/src/checked.rs index c5941bdc..d8dacf3c 100644 --- a/const-oid/src/checked.rs +++ b/const-oid/src/checked.rs @@ -10,7 +10,7 @@ macro_rules! checked_add { }; } -/// `const fn`-friendly checked addition helper. +/// `const fn`-friendly checked subtraction helper. macro_rules! checked_sub { ($a:expr, $b:expr) => { match $a.checked_sub($b) { @@ -19,3 +19,13 @@ macro_rules! checked_sub { } }; } + +/// `const fn`-friendly checked multiplication helper. +macro_rules! checked_mul { + ($a:expr, $b:expr) => { + match $a.checked_mul($b) { + Some(n) => n, + None => return Err(Error::Overflow), + } + }; +} diff --git a/const-oid/src/encoder.rs b/const-oid/src/encoder.rs index 75a6dd2d..c901e492 100644 --- a/const-oid/src/encoder.rs +++ b/const-oid/src/encoder.rs @@ -51,7 +51,6 @@ impl Encoder { } /// Encode an [`Arc`] as base 128 into the internal buffer. - #[allow(clippy::panic_in_result_fn)] pub(crate) const fn arc(mut self, arc: Arc) -> Result { match self.state { State::Initial => { @@ -68,18 +67,10 @@ impl Encoder { } self.state = State::Body; - self.bytes[0] = match (ARC_MAX_SECOND + 1).checked_mul(first_arc) { - // TODO(tarcieri): use `and_then` when const traits are stable - Some(n) => match n.checked_add(arc) { - Some(byte) => byte as u8, - None => { - // TODO(tarcieri): use `unreachable!` - panic!("overflow prevented by ARC_MAX_SECOND check") - } - }, - // TODO(tarcieri): use `unreachable!` - None => panic!("overflow prevented by ARC_MAX_SECOND check"), - }; + self.bytes[0] = checked_add!( + checked_mul!(checked_add!(ARC_MAX_SECOND, 1), first_arc), + arc + ) as u8; self.cursor = 1; Ok(self) } diff --git a/const-oid/src/error.rs b/const-oid/src/error.rs index 9142d573..263746c6 100644 --- a/const-oid/src/error.rs +++ b/const-oid/src/error.rs @@ -38,6 +38,8 @@ pub enum Error { Length, /// Arithmetic overflow (or underflow) errors. + /// + /// These generally indicate a bug in the `const-oid` crate. Overflow, /// Repeated `..` characters in input data.