core: Reimpl `Key` with generics
@@ -5,57 +5,85 @@ use core::fmt::Debug;
use core::fmt::Display;
use core::fmt::Formatter;
use core::fmt::Result;
+use std::marker::PhantomData;
use zeroize::Zeroize;
-macro_rules! impl_key {
- ($ident:ident, $doc:expr) => {
+/// A cryptographic key with `Public` components.
+pub type PublicKey = Key<Public>;
+
+/// A cryptographic key with `Secret` components.
+pub type SecretKey = Key<Secret>;
+
+// =============================================================================
+// =============================================================================
+
+mod private {
+ pub trait Sealed {}
+}
+
+// A marker type for the `Public` components of a cryptographic key.
+#[derive(Clone, Copy, Debug)]
+pub enum Public {}
+
+// A marker type for the `Secret` components of a cryptographic key.
+#[derive(Clone, Copy, Debug)]
+pub enum Secret {}
+
+impl private::Sealed for Public {}
+
+impl private::Sealed for Secret {}
+
+// =============================================================================
+// =============================================================================
+
+/// A cryptographic key.
#[derive(Clone)]
- #[doc = $doc]
- pub struct $ident(Box<[u8]>);
+pub struct Key<V: private::Sealed> {
+ key: Box<[u8]>,
+ vis: PhantomData<V>,
+}
- impl Debug for $ident {
+impl<V: private::Sealed> Debug for Key<V> {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
- f.write_str(stringify!($ident))
+ f.write_str("Key")
}
}
- impl Display for $ident {
+impl<V: private::Sealed> Display for Key<V> {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
- f.write_str(stringify!($ident))
+ f.write_str("Key")
}
}
- impl Drop for $ident {
+impl<V: private::Sealed> Drop for Key<V> {
fn drop(&mut self) {
- self.0.zeroize();
+ self.key.zeroize();
}
}
- impl Zeroize for $ident {
+impl<V: private::Sealed> Zeroize for Key<V> {
fn zeroize(&mut self) {
- self.0.zeroize();
+ self.key.zeroize();
}
}
- impl AsRef<[u8]> for $ident {
+impl<V: private::Sealed> AsRef<[u8]> for Key<V> {
fn as_ref(&self) -> &[u8] {
- &self.0
+ &self.key
}
}
- impl From<Box<[u8]>> for $ident {
+impl<V: private::Sealed> From<Box<[u8]>> for Key<V> {
fn from(other: Box<[u8]>) -> Self {
- Self(other)
+ Self {
+ key: other,
+ vis: PhantomData,
+ }
}
}
- impl From<Vec<u8>> for $ident {
+impl<V: private::Sealed> From<Vec<u8>> for Key<V> {
fn from(other: Vec<u8>) -> Self {
other.into_boxed_slice().into()
}
}
- };
-}
-
-impl_key!(PublicKey, "A public key object.");
-impl_key!(SecretKey, "A secret key object.");
