//! Wrapping arithmetic. use crate::Zero; use core::fmt; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq}; #[cfg(feature = "rand_core")] use {crate::Random, rand_core::CryptoRngCore}; #[cfg(feature = "serde")] use serdect::serde::{Deserialize, Deserializer, Serialize, Serializer}; /// Provides intentionally-wrapped arithmetic on `T`. /// /// This is analogous to [`core::num::Wrapping`] but allows this crate to /// define trait impls for this type. #[derive(Copy, Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord)] pub struct Wrapping(pub T); impl Zero for Wrapping { const ZERO: Self = Self(T::ZERO); } impl fmt::Display for Wrapping { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0.fmt(f) } } impl fmt::Binary for Wrapping { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0.fmt(f) } } impl fmt::Octal for Wrapping { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0.fmt(f) } } impl fmt::LowerHex for Wrapping { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0.fmt(f) } } impl fmt::UpperHex for Wrapping { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0.fmt(f) } } impl ConditionallySelectable for Wrapping { fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { Wrapping(T::conditional_select(&a.0, &b.0, choice)) } } impl ConstantTimeEq for Wrapping { fn ct_eq(&self, other: &Self) -> Choice { self.0.ct_eq(&other.0) } } #[cfg(feature = "rand_core")] impl Random for Wrapping { fn random(rng: &mut impl CryptoRngCore) -> Self { Wrapping(Random::random(rng)) } } #[cfg(feature = "serde")] impl<'de, T: Deserialize<'de>> Deserialize<'de> for Wrapping { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { Ok(Self(T::deserialize(deserializer)?)) } } #[cfg(feature = "serde")] impl Serialize for Wrapping { fn serialize(&self, serializer: S) -> Result where S: Serializer, { self.0.serialize(serializer) } } #[cfg(all(test, feature = "serde"))] #[allow(clippy::unwrap_used)] mod tests { use crate::{Wrapping, U64}; #[test] fn serde() { const TEST: Wrapping = Wrapping(U64::from_u64(0x0011223344556677)); let serialized = bincode::serialize(&TEST).unwrap(); let deserialized: Wrapping = bincode::deserialize(&serialized).unwrap(); assert_eq!(TEST, deserialized); } #[test] fn serde_owned() { const TEST: Wrapping = Wrapping(U64::from_u64(0x0011223344556677)); let serialized = bincode::serialize(&TEST).unwrap(); let deserialized: Wrapping = bincode::deserialize_from(serialized.as_slice()).unwrap(); assert_eq!(TEST, deserialized); } }