use core::fmt;
use multi_codec::Codec;
use zeroize::{Zeroize, ZeroizeOnDrop};
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct PublicKeyBytes(Vec<u8>);
impl PublicKeyBytes {
pub fn new(bytes: Vec<u8>) -> Self {
Self(bytes)
}
pub fn as_bytes(&self) -> &[u8] {
&self.0
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn into_bytes(self) -> Vec<u8> {
self.0
}
}
impl From<Vec<u8>> for PublicKeyBytes {
fn from(bytes: Vec<u8>) -> Self {
Self(bytes)
}
}
impl AsRef<[u8]> for PublicKeyBytes {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
#[derive(Clone, Zeroize, ZeroizeOnDrop)]
pub struct PrivateKeyBytes(Vec<u8>);
impl PrivateKeyBytes {
pub fn new(bytes: Vec<u8>) -> Self {
Self(bytes)
}
pub fn as_bytes(&self) -> &[u8] {
&self.0
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn to_vec(&self) -> Vec<u8> {
self.0.clone()
}
}
impl From<Vec<u8>> for PrivateKeyBytes {
fn from(bytes: Vec<u8>) -> Self {
Self(bytes)
}
}
impl AsRef<[u8]> for PrivateKeyBytes {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
impl fmt::Debug for PrivateKeyBytes {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "PrivateKeyBytes([REDACTED {} bytes])", self.0.len())
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct KeyScheme(Codec);
impl KeyScheme {
pub const fn new(codec: Codec) -> Self {
Self(codec)
}
pub const fn codec(self) -> Codec {
self.0
}
pub fn name(self) -> &'static str {
self.0.into()
}
pub fn code(self) -> u64 {
self.0.code()
}
}
impl From<Codec> for KeyScheme {
fn from(codec: Codec) -> Self {
Self(codec)
}
}
impl From<KeyScheme> for Codec {
fn from(scheme: KeyScheme) -> Codec {
scheme.0
}
}
impl fmt::Display for KeyScheme {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.name())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_public_key_bytes() {
let pubkey = PublicKeyBytes::new(vec![1, 2, 3]);
assert_eq!(pubkey.len(), 3);
assert_eq!(pubkey.as_bytes(), &[1, 2, 3]);
}
#[test]
fn test_private_key_bytes_zeroization() {
let privkey = PrivateKeyBytes::new(vec![1, 2, 3]);
assert_eq!(privkey.len(), 3);
}
#[test]
fn test_private_key_debug_redacted() {
let privkey = PrivateKeyBytes::new(vec![1, 2, 3]);
let debug = format!("{:?}", privkey);
assert!(debug.contains("REDACTED"));
assert!(!debug.contains("1"));
}
#[test]
fn test_key_scheme() {
let scheme = KeyScheme::new(Codec::Ed25519Pub);
assert_eq!(scheme.codec(), Codec::Ed25519Pub);
assert_eq!(scheme.name(), "ed25519-pub");
}
#[test]
fn test_newtypes_send_sync() {
fn assert_send<T: Send>() {}
fn assert_sync<T: Sync>() {}
assert_send::<PublicKeyBytes>();
assert_sync::<PublicKeyBytes>();
assert_send::<PrivateKeyBytes>();
assert_sync::<PrivateKeyBytes>();
assert_send::<KeyScheme>();
assert_sync::<KeyScheme>();
}
}