use std::{convert::TryFrom, hash::Hash};
use byteorder::BigEndian;
use rand::Rng;
use log::error;
use serde::{de::DeserializeOwned, Deserialize, Serialize};
pub use cdr_encoding_size::*;
use crate::serialization::{cdr_serializer::to_bytes, error::Error};
pub trait Keyed {
type K;
fn key(&self) -> Self::K;
}
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Copy)]
pub struct KeyHash([u8; 16]);
impl KeyHash {
pub fn zero() -> KeyHash {
KeyHash([0; 16])
}
pub fn to_vec(self) -> Vec<u8> {
Vec::from(self.0)
}
pub fn into_cdr_bytes(self) -> Result<Vec<u8>, Error> {
Ok(self.to_vec())
}
pub fn from_cdr_bytes(bytes: Vec<u8>) -> Result<KeyHash, Error> {
let a = <[u8; 16]>::try_from(bytes).map_err(|_e| Error::Eof)?;
Ok(KeyHash(a))
}
}
pub trait Key:
Eq + PartialEq + PartialOrd + Ord + Hash + Clone + Serialize + DeserializeOwned + CdrEncodingSize
{
fn hash_key(&self) -> KeyHash {
let mut cdr_bytes = to_bytes::<Self, BigEndian>(self).unwrap_or_else(|e| {
error!("Hashing key {:?} failed!", e);
vec![0; 16]
});
KeyHash(
if Self::cdr_encoding_max_size() > CdrEncodingMaxSize::Bytes(16) {
*md5::compute(&cdr_bytes)
} else {
cdr_bytes.resize(16, 0x00); <[u8; 16]>::try_from(cdr_bytes).unwrap() },
)
}
}
impl Key for () {
fn hash_key(&self) -> KeyHash {
KeyHash::zero()
}
}
impl<D: Keyed> Keyed for &D {
type K = D::K;
fn key(&self) -> Self::K {
(*self).key()
}
}
impl Key for bool {}
impl Key for char {}
impl Key for i8 {}
impl Key for i16 {}
impl Key for i32 {}
impl Key for i64 {}
impl Key for i128 {}
impl Key for u8 {}
impl Key for u16 {}
impl Key for u32 {}
impl Key for u64 {}
impl Key for u128 {}
impl Key for String {}
#[derive(Debug, Eq, PartialEq, PartialOrd, Ord, Hash, Serialize, Deserialize, CdrEncodingSize)]
pub struct BuiltInTopicKey {
value: [i32; 3],
}
impl BuiltInTopicKey {
pub fn random_key() -> BuiltInTopicKey {
let mut rng = rand::thread_rng();
BuiltInTopicKey {
value: [rng.gen(), rng.gen(), rng.gen()],
}
}
pub fn default() -> BuiltInTopicKey {
BuiltInTopicKey { value: [0, 0, 0] }
}
}