diff --git a/README.md b/README.md index ef0f0cf..2e52194 100644 --- a/README.md +++ b/README.md @@ -95,25 +95,25 @@ If you need strong memory protection before and after a `Secret` is dropped cons [PartialOrd], [Eq], [PartialEq], -[ops::Add], -[ops::AddAssign], -[ops::BitAnd], -[ops::BitAndAssign], -[ops::BitOr], -[ops::BitOrAssign], -[ops::BitXor], -[ops::BitXorAssign], -[ops::Div], -[ops::DivAssign], -[ops::Mul], -[ops::MulAssign], -[ops::Rem], -[ops::RemAssign], -[ops::Shl], -[ops::ShlAssign], -[ops::Shr], -[ops::ShrAssign], -[ops::Sub], -[ops::SubAssign], -[ops::Neg] and -[ops::Not] +[std::ops::Add], +[std::ops::AddAssign], +[std::ops::BitAnd], +[std::ops::BitAndAssign], +[std::ops::BitOr], +[std::ops::BitOrAssign], +[std::ops::BitXor], +[std::ops::BitXorAssign], +[std::ops::Div], +[std::ops::DivAssign], +[std::ops::Mul], +[std::ops::MulAssign], +[std::ops::Rem], +[std::ops::RemAssign], +[std::ops::Shl], +[std::ops::ShlAssign], +[std::ops::Shr], +[std::ops::ShrAssign], +[std::ops::Sub], +[std::ops::SubAssign], +[std::ops::Neg] and +[std::ops::Not] diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..b50eabb --- /dev/null +++ b/src/error.rs @@ -0,0 +1,13 @@ +use crate::Secret; + +use core::fmt; +use std::error::Error; + +impl fmt::Display for Secret { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + ::fmt(self, f) + } +} + +impl Error for Secret {} diff --git a/src/fake.rs b/src/fake.rs new file mode 100644 index 0000000..62951e9 --- /dev/null +++ b/src/fake.rs @@ -0,0 +1,16 @@ +use crate::Secret; + +use fake::Dummy; +use rand::Rng; + +impl, U> Dummy for Secret { + #[inline] + fn dummy_with_rng(config: &U, rng: &mut R) -> Self { + Secret(T::dummy_with_rng(config, rng)) + } + + #[inline] + fn dummy(config: &U) -> Self { + Secret(T::dummy(config)) + } +} diff --git a/src/lib.rs b/src/lib.rs index 08ff4f4..e40050f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,7 +2,18 @@ #![cfg_attr(not(feature = "std"), no_std)] #![forbid(unsafe_code)] -use core::{any::type_name, fmt, ops, str::FromStr}; +#[cfg(feature = "std")] +mod error; +#[cfg(feature = "fake")] +mod fake; +mod ops; +#[cfg(feature = "serde")] +mod serde; + +#[cfg(feature = "serde")] +pub use crate::serde::expose_secret; + +use core::{any::type_name, fmt, str::FromStr}; /// See [module level documentation][crate] #[derive(Default, Hash, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)] @@ -87,102 +98,6 @@ impl, T> FromIterator> for Secret { } } -macro_rules! ops { - { ($type:tt, $trait:ident, $method:ident), $($tt:tt)* } => { - ops!(($type, $trait, $method)); - ops!($($tt)*); - }; - { (binary, $trait:ident, $method:ident)} => { - impl ops::$trait> for Secret - where - T: ops::$trait, - { - type Output = Secret; - #[inline] - fn $method(self, rhs: Secret) -> Self::Output { - Secret(self.0.$method(rhs.0)) - } - } - }; - { (assign, $trait:ident, $method:ident)} => { - impl ops::$trait> for Secret - where - T: ops::$trait, - { - #[inline] - fn $method(&mut self, rhs: Secret) { - self.0.$method(rhs.0) - } - } - }; - { (unary, $trait:ident, $method:ident)} => { - impl ops::$trait for Secret - where - T: ops::$trait, - { - type Output = Secret; - #[inline] - fn $method(self) -> Self::Output { - Secret(self.0.$method()) - } - } - }; - () => () -} - -ops! { - (binary, Add, add), - (assign, AddAssign, add_assign), - (binary, BitAnd, bitand), - (assign, BitAndAssign, bitand_assign), - (binary, BitOr, bitor), - (assign, BitOrAssign, bitor_assign), - (binary, BitXor, bitxor), - (assign, BitXorAssign, bitxor_assign), - (binary, Div, div), - (assign, DivAssign, div_assign), - (binary, Mul, mul), - (assign, MulAssign, mul_assign), - (binary, Rem, rem), - (assign, RemAssign, rem_assign), - (binary, Shl, shl), - (assign, ShlAssign, shl_assign), - (binary, Shr, shr), - (assign, ShrAssign, shr_assign), - (binary, Sub, sub), - (assign, SubAssign, sub_assign), - (unary, Neg, neg), - (unary, Not, not), -} - -#[cfg(feature = "std")] -mod error { - use crate::Secret; - - use core::fmt; - use std::error::Error; - - impl fmt::Display for Secret { - #[inline] - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - ::fmt(self, f) - } - } - - impl Error for Secret {} -} - -use serde::{Deserialize, Deserializer, Serialize, Serializer}; - -#[cfg(feature = "serde")] -/// *This API requires the following crate features to be activated: `serde`* -impl<'de, T: Deserialize<'de>> Deserialize<'de> for Secret { - #[inline] - fn deserialize>(deserializer: D) -> Result { - T::deserialize(deserializer).map(Self) - } -} - #[cfg(feature = "serde")] #[derive(Serialize)] struct Test { @@ -236,20 +151,3 @@ pub fn expose_secret( .serialize(serializer) } -#[cfg(feature = "fake")] -use fake::Dummy; -#[cfg(feature = "fake")] -use rand::Rng; - -#[cfg(feature = "fake")] -impl, U> Dummy for Secret { - #[inline] - fn dummy_with_rng(config: &U, rng: &mut R) -> Self { - Secret(T::dummy_with_rng(config, rng)) - } - - #[inline] - fn dummy(config: &U) -> Self { - Secret(T::dummy(config)) - } -} diff --git a/src/ops.rs b/src/ops.rs new file mode 100644 index 0000000..7aece84 --- /dev/null +++ b/src/ops.rs @@ -0,0 +1,71 @@ +use crate::Secret; + +use core::ops; + +macro_rules! ops { + { ($type:tt, $trait:ident, $method:ident), $($tt:tt)* } => { + ops!(($type, $trait, $method)); + ops!($($tt)*); + }; + { (binary, $trait:ident, $method:ident)} => { + impl ops::$trait> for Secret + where + T: ops::$trait, + { + type Output = Secret; + #[inline] + fn $method(self, rhs: Secret) -> Self::Output { + Secret(self.0.$method(rhs.0)) + } + } + }; + { (assign, $trait:ident, $method:ident)} => { + impl ops::$trait> for Secret + where + T: ops::$trait, + { + #[inline] + fn $method(&mut self, rhs: Secret) { + self.0.$method(rhs.0) + } + } + }; + { (unary, $trait:ident, $method:ident)} => { + impl ops::$trait for Secret + where + T: ops::$trait, + { + type Output = Secret; + #[inline] + fn $method(self) -> Self::Output { + Secret(self.0.$method()) + } + } + }; + () => () +} + +ops! { + (binary, Add, add), + (assign, AddAssign, add_assign), + (binary, BitAnd, bitand), + (assign, BitAndAssign, bitand_assign), + (binary, BitOr, bitor), + (assign, BitOrAssign, bitor_assign), + (binary, BitXor, bitxor), + (assign, BitXorAssign, bitxor_assign), + (binary, Div, div), + (assign, DivAssign, div_assign), + (binary, Mul, mul), + (assign, MulAssign, mul_assign), + (binary, Rem, rem), + (assign, RemAssign, rem_assign), + (binary, Shl, shl), + (assign, ShlAssign, shl_assign), + (binary, Shr, shr), + (assign, ShrAssign, shr_assign), + (binary, Sub, sub), + (assign, SubAssign, sub_assign), + (unary, Neg, neg), + (unary, Not, not), +} diff --git a/src/serde.rs b/src/serde.rs new file mode 100644 index 0000000..7b33ccf --- /dev/null +++ b/src/serde.rs @@ -0,0 +1,26 @@ +use crate::Secret; + +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +/// *This API requires the following crate features to be activated: `serde`* +impl<'de, T: Deserialize<'de>> Deserialize<'de> for Secret { + #[inline] + fn deserialize>(deserializer: D) -> Result { + T::deserialize(deserializer).map(Self) + } +} + +/// Exposes a [Secret] for serialization. +/// +/// For general-purpose secret exposing see [Secret::expose_secret]. +/// +/// See [module level documentation][crate] for usage example. +/// +/// *This API requires the following crate features to be activated: `serde`* +#[inline] +pub fn expose_secret( + secret: &Secret, + serializer: S, +) -> Result { + secret.expose_secret().serialize(serializer) +}