pub mod store;
use bytes::Bytes;
use std::borrow::Borrow;
use std::hash::{Hash, Hasher};
use std::time::Instant;
use libp2prs_core::{multihash::Multihash, PeerId};
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Key(Bytes);
impl Key {
pub fn new<K: AsRef<[u8]>>(key: &K) -> Self {
Key(Bytes::copy_from_slice(key.as_ref()))
}
pub fn to_vec(&self) -> Vec<u8> {
Vec::from(&self.0[..])
}
}
impl Borrow<[u8]> for Key {
fn borrow(&self) -> &[u8] {
&self.0[..]
}
}
impl AsRef<[u8]> for Key {
fn as_ref(&self) -> &[u8] {
&self.0[..]
}
}
impl From<Vec<u8>> for Key {
fn from(v: Vec<u8>) -> Key {
Key(Bytes::from(v))
}
}
impl From<Multihash> for Key {
fn from(m: Multihash) -> Key {
Key::from(m.to_bytes())
}
}
impl From<PeerId> for Key {
fn from(m: PeerId) -> Key {
Key::from(m.to_bytes())
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Record {
pub key: Key,
pub value: Vec<u8>,
pub time_received: Option<Instant>,
pub publisher: Option<PeerId>,
}
impl Record {
pub fn new<K>(key: K, value: Vec<u8>, local: bool, publisher: Option<PeerId>) -> Self
where
K: Into<Key>,
{
Record {
key: key.into(),
value,
time_received: if local { None } else { Some(Instant::now()) },
publisher,
}
}
pub fn timestamp(&self) -> Option<Instant> {
self.time_received
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ProviderRecord {
pub key: Key,
pub provider: PeerId,
pub time_received: Option<Instant>,
}
#[allow(clippy::derive_hash_xor_eq)]
impl Hash for ProviderRecord {
fn hash<H: Hasher>(&self, state: &mut H) {
self.key.hash(state);
self.provider.hash(state);
}
}
impl ProviderRecord {
pub fn new<K>(key: K, provider: PeerId, local: bool) -> Self
where
K: Into<Key>,
{
ProviderRecord {
key: key.into(),
provider,
time_received: if local { None } else { Some(Instant::now()) },
}
}
pub fn timestamp(&self) -> Option<Instant> {
self.time_received
}
}
#[cfg(test)]
mod tests {
use super::*;
use libp2prs_core::multihash::{Code, Multihash};
use quickcheck::*;
use rand::Rng;
use std::time::Duration;
impl Arbitrary for Key {
fn arbitrary<G: Gen>(_: &mut G) -> Key {
let hash = rand::thread_rng().gen::<[u8; 32]>();
Key::from(Multihash::wrap(Code::Sha2_256.into(), &hash).unwrap())
}
}
impl Arbitrary for Record {
fn arbitrary<G: Gen>(g: &mut G) -> Record {
Record {
key: Key::arbitrary(g),
value: Vec::arbitrary(g),
time_received: if g.gen() {
Some(Instant::now() + Duration::from_secs(g.gen_range(0, 60)))
} else {
None
},
publisher: if g.gen() { Some(PeerId::random()) } else { None },
}
}
}
impl Arbitrary for ProviderRecord {
fn arbitrary<G: Gen>(g: &mut G) -> ProviderRecord {
ProviderRecord {
key: Key::arbitrary(g),
provider: PeerId::random(),
time_received: Some(Instant::now() + Duration::from_secs(g.gen_range(0, 60))),
}
}
}
}