use serde::{Deserialize, Serialize};
use std::fmt::{Debug, Display};
use std::hash::Hash;
pub trait PeerIdentity:
Clone + Debug + Display + Serialize + for<'de> Deserialize<'de> + Send + Sync + 'static
{
fn to_string_repr(&self) -> String;
fn from_string_repr(s: &str) -> anyhow::Result<Self>
where
Self: Sized;
fn unique_id(&self) -> String {
self.to_string_repr()
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct PeerIdentityString(pub String);
impl PeerIdentityString {
pub fn new(s: impl Into<String>) -> Self {
Self(s.into())
}
pub fn as_str(&self) -> &str {
&self.0
}
}
impl Display for PeerIdentityString {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl PeerIdentity for PeerIdentityString {
fn to_string_repr(&self) -> String {
self.0.clone()
}
fn from_string_repr(s: &str) -> anyhow::Result<Self> {
Ok(Self(s.to_string()))
}
}
impl From<&str> for PeerIdentityString {
fn from(s: &str) -> Self {
Self(s.to_string())
}
}
impl From<String> for PeerIdentityString {
fn from(s: String) -> Self {
Self(s)
}
}
#[cfg(test)]
#[allow(clippy::unwrap_used)]
mod tests {
use super::*;
#[test]
fn test_peer_identity_string() {
let id = PeerIdentityString::new("alice-bob-charlie-david");
assert_eq!(id.to_string(), "alice-bob-charlie-david");
assert_eq!(id.to_string_repr(), "alice-bob-charlie-david");
}
#[test]
fn test_peer_identity_from_string() {
let id = PeerIdentityString::from_string_repr("test-peer-id")
.ok()
.unwrap();
assert_eq!(id.as_str(), "test-peer-id");
}
#[test]
fn test_peer_identity_serialization() {
let id = PeerIdentityString::new("alice-bob");
let json = serde_json::to_string(&id).ok().unwrap();
let deserialized: PeerIdentityString = serde_json::from_str(&json).ok().unwrap();
assert_eq!(id, deserialized);
}
}