use crate::{multihash::Multihash, PeerId};
use bytes::Bytes;
use libp2p_kad::RecordKey as Libp2pKey;
use litep2p::protocol::libp2p::kademlia::{Record as Litep2pRecord, RecordKey as Litep2pKey};
use std::{error::Error, fmt, time::Instant};
#[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> {
self.0.to_vec()
}
}
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<Litep2pKey> for Key {
fn from(key: Litep2pKey) -> Self {
Self::from(key.to_vec())
}
}
impl From<Key> for Litep2pKey {
fn from(key: Key) -> Self {
Self::from(key.to_vec())
}
}
impl From<Libp2pKey> for Key {
fn from(key: Libp2pKey) -> Self {
Self::from(key.to_vec())
}
}
impl From<Key> for Libp2pKey {
fn from(key: Key) -> Self {
Self::from(key.to_vec())
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Record {
pub key: Key,
pub value: Vec<u8>,
pub publisher: Option<PeerId>,
pub expires: Option<Instant>,
}
impl Record {
pub fn new(key: Key, value: Vec<u8>) -> Self {
Record { key, value, publisher: None, expires: None }
}
pub fn is_expired(&self, now: Instant) -> bool {
self.expires.map_or(false, |t| now >= t)
}
}
impl From<libp2p_kad::Record> for Record {
fn from(out: libp2p_kad::Record) -> Self {
let vec: Vec<u8> = out.key.to_vec();
let key: Key = vec.into();
let publisher = out.publisher.map(Into::into);
Record { key, value: out.value, publisher, expires: out.expires }
}
}
impl From<Record> for Litep2pRecord {
fn from(val: Record) -> Self {
let vec: Vec<u8> = val.key.to_vec();
let key: Litep2pKey = vec.into();
let publisher = val.publisher.map(Into::into);
Litep2pRecord { key, value: val.value, publisher, expires: val.expires }
}
}
impl From<Record> for libp2p_kad::Record {
fn from(a: Record) -> libp2p_kad::Record {
let peer = a.publisher.map(Into::into);
libp2p_kad::Record {
key: a.key.to_vec().into(),
value: a.value,
publisher: peer,
expires: a.expires,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PeerRecord {
pub peer: Option<PeerId>,
pub record: Record,
}
impl From<libp2p_kad::PeerRecord> for PeerRecord {
fn from(out: libp2p_kad::PeerRecord) -> Self {
let peer = out.peer.map(Into::into);
let record = out.record.into();
PeerRecord { peer, record }
}
}
#[derive(Debug)]
pub struct SigningError {
msg: String,
source: Option<Box<dyn Error + Send + Sync>>,
}
#[allow(dead_code)]
impl SigningError {
pub(crate) fn new<S: ToString>(msg: S) -> Self {
Self { msg: msg.to_string(), source: None }
}
pub(crate) fn source(self, source: impl Error + Send + Sync + 'static) -> Self {
Self { source: Some(Box::new(source)), ..self }
}
}
impl fmt::Display for SigningError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Key signing error: {}", self.msg)
}
}
impl Error for SigningError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
self.source.as_ref().map(|s| &**s as &dyn Error)
}
}