use anyhow::Result;
use base32::Alphabet;
use bincode::{Decode, Encode};
use bytes::Bytes;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
pub use crate::key::PublicKey;
pub const UUID_V4_BYTES_LEN: usize = 16;
pub type NodeId = PublicKey;
#[derive(Serialize, Deserialize, Encode, Decode, Clone, Debug, Eq, PartialEq, Hash)]
pub struct UuidV4([u8; UUID_V4_BYTES_LEN]);
impl UuidV4 {
pub fn new() -> Self {
let unique_id: Uuid = Uuid::new_v4();
let mut id = [0u8; UUID_V4_BYTES_LEN];
id.copy_from_slice(unique_id.as_bytes());
Self(id)
}
pub fn zero() -> Self {
Self([0; UUID_V4_BYTES_LEN])
}
pub fn as_str(&self) -> &str {
std::str::from_utf8(&self.0).unwrap_or_default()
}
pub fn from_bytes(bytes: Bytes) -> Result<Self> {
if bytes.len() != UUID_V4_BYTES_LEN {
return Err(anyhow::anyhow!(
"Invalid length for UuidV4: expected {}, got {}",
UUID_V4_BYTES_LEN,
bytes.len()
));
}
let mut id = [0u8; UUID_V4_BYTES_LEN];
id.copy_from_slice(&bytes);
Ok(Self(id))
}
pub fn to_bytes(&self) -> Bytes {
Bytes::copy_from_slice(&self.0)
}
pub fn from_hex(encoded: &str) -> Result<Self> {
let bytes = hex::decode(encoded)?;
let mut id = [0u8; UUID_V4_BYTES_LEN];
id.copy_from_slice(&bytes);
Ok(Self(id))
}
pub fn to_hex(&self) -> String {
hex::encode(&self.0)
}
pub fn is_zero(&self) -> bool {
self.0.iter().all(|&x| x == 0)
}
pub fn from_base32(encoded: &str) -> Result<Self> {
let decoded = base32::decode(Alphabet::Rfc4648 { padding: false }, encoded)
.ok_or_else(|| anyhow::anyhow!("Failed to decode base32 string"))?;
match bincode::serde::decode_from_slice(&decoded, bincode::config::standard()) {
Ok((node_addr, _)) => Ok(node_addr),
Err(e) => Err(anyhow::anyhow!("Failed to decode base32 string: {}", e)),
}
}
pub fn to_base32(&self) -> Result<String> {
let serialized = bincode::serde::encode_to_vec(self, bincode::config::standard())?;
Ok(base32::encode(
Alphabet::Rfc4648 { padding: false },
&serialized,
))
}
}