pub mod error;
pub mod messages;
pub mod storage;
use self::storage::{ChunkAddress, DbcAddress, RegisterAddress};
use bytes::Bytes;
use libp2p::{
kad::{KBucketDistance as Distance, KBucketKey as Key, RecordKey},
PeerId,
};
use serde::{Deserialize, Serialize};
use std::fmt::{self, Debug, Display, Formatter};
use xor_name::XorName;
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum NetworkAddress {
PeerId(Vec<u8>),
ChunkAddress(ChunkAddress),
DbcAddress(DbcAddress),
RegisterAddress(RegisterAddress),
RecordKey(Vec<u8>),
}
impl NetworkAddress {
pub fn from_chunk_address(chunk_address: ChunkAddress) -> Self {
NetworkAddress::ChunkAddress(chunk_address)
}
pub fn from_dbc_address(dbc_address: DbcAddress) -> Self {
NetworkAddress::DbcAddress(dbc_address)
}
pub fn from_register_address(register_address: RegisterAddress) -> Self {
NetworkAddress::RegisterAddress(register_address)
}
pub fn from_peer(peer_id: PeerId) -> Self {
NetworkAddress::PeerId(peer_id.to_bytes())
}
pub fn from_record_key(record_key: RecordKey) -> Self {
NetworkAddress::RecordKey(record_key.to_vec())
}
pub fn as_bytes(&self) -> Vec<u8> {
match self {
NetworkAddress::PeerId(bytes) | NetworkAddress::RecordKey(bytes) => bytes.to_vec(),
NetworkAddress::ChunkAddress(chunk_address) => chunk_address.name().0.to_vec(),
NetworkAddress::DbcAddress(dbc_address) => dbc_address.name().0.to_vec(),
NetworkAddress::RegisterAddress(register_address) => register_address.id().0.to_vec(),
}
}
pub fn as_peer_id(&self) -> Option<PeerId> {
if let NetworkAddress::PeerId(bytes) = self {
if let Ok(peer_id) = PeerId::from_bytes(bytes) {
return Some(peer_id);
}
}
None
}
pub fn as_record_key(&self) -> Option<RecordKey> {
match self {
NetworkAddress::RecordKey(bytes) => Some(RecordKey::new(bytes)),
_ => None,
}
}
pub fn to_record_key(&self) -> RecordKey {
match self {
NetworkAddress::RecordKey(bytes) => RecordKey::new(bytes),
NetworkAddress::ChunkAddress(chunk_address) => RecordKey::new(chunk_address.name()),
NetworkAddress::RegisterAddress(register_address) => {
let mut reg_name: Vec<u8> = register_address.name().to_vec();
reg_name.extend(register_address.tag.to_be_bytes());
RecordKey::new(&XorName::from_content(®_name))
}
NetworkAddress::DbcAddress(dbc_address) => RecordKey::new(dbc_address.name()),
NetworkAddress::PeerId(bytes) => RecordKey::new(bytes),
}
}
pub fn as_kbucket_key(&self) -> Key<Vec<u8>> {
Key::new(self.as_bytes())
}
pub fn distance(&self, other: &NetworkAddress) -> Distance {
self.as_kbucket_key().distance(&other.as_kbucket_key())
}
}
impl Debug for NetworkAddress {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let name_str = match self {
NetworkAddress::PeerId(_) => "NetworkAddress::PeerId(".to_string(),
NetworkAddress::ChunkAddress(chunk_address) => {
format!("NetworkAddress::ChunkAddress({:?} - ", chunk_address.name())
}
NetworkAddress::DbcAddress(dbc_address) => {
format!("NetworkAddress::DbcAddress({:?} - ", dbc_address.name())
}
NetworkAddress::RegisterAddress(register_address) => format!(
"NetworkAddress::RegisterAddress({:?} - ",
register_address.id()
),
NetworkAddress::RecordKey(_) => "NetworkAddress::RecordKey(".to_string(),
};
write!(
f,
"{name_str} - {:?} - {:?})",
PrettyPrintRecordKey::from(self.to_record_key()),
self.as_kbucket_key()
)
}
}
impl Display for NetworkAddress {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
NetworkAddress::PeerId(id) => {
write!(f, "NetworkAddress::PeerId({})", hex::encode(id))
}
NetworkAddress::ChunkAddress(addr) => {
write!(f, "NetworkAddress::ChunkAddress({addr:?})")
}
NetworkAddress::DbcAddress(addr) => {
write!(f, "NetworkAddress::DbcAddress({addr:?})")
}
NetworkAddress::RegisterAddress(addr) => {
write!(f, "NetworkAddress::RegisterAddress({addr:?})")
}
NetworkAddress::RecordKey(key) => {
write!(f, "NetworkAddress::RecordKey({})", hex::encode(key))
}
}
}
}
#[derive(Clone)]
pub struct PrettyPrintRecordKey(RecordKey);
impl From<RecordKey> for PrettyPrintRecordKey {
fn from(key: RecordKey) -> Self {
PrettyPrintRecordKey(key)
}
}
impl std::fmt::Display for PrettyPrintRecordKey {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let b: Vec<u8> = self.0.as_ref().to_vec();
let record_key_b = Bytes::from(b);
write!(f, "{:64x}", record_key_b)
}
}
impl std::fmt::Debug for PrettyPrintRecordKey {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self)
}
}