use core::fmt;
use std::{str::FromStr, sync::Arc};
#[cfg(feature = "serde")]
use serde::{de, Deserialize, Deserializer, Serialize};
use anyhow::Result;
use fuid::Fuid;
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct NodeID(Arc<String>);
impl NodeID {
pub fn new() -> NodeID {
NodeID(Arc::new(Fuid::new().to_string()))
}
pub fn with_str(s: &str) -> Result<NodeID> {
Ok(NodeID(Arc::new(s.to_string())))
}
pub fn with_u128(i: u128) -> NodeID {
NodeID(Arc::new(i.to_string()))
}
pub fn as_str(&self) -> &str {
self.0.as_str()
}
}
impl Default for NodeID {
fn default() -> Self {
Self::new()
}
}
impl fmt::Display for NodeID {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl fmt::Debug for NodeID {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("NodeID")
.field(&self.to_string())
.finish()
}
}
impl FromStr for NodeID {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self> {
NodeID::with_str(s)
}
}
impl From<&str> for NodeID {
fn from(val: &str) -> Self {
NodeID::with_str(val).unwrap()
}
}
impl From<String> for NodeID {
fn from(val: String) -> Self {
NodeID::with_str(&val).unwrap()
}
}
impl From<NodeID> for String {
fn from(val: NodeID) -> Self {
val.to_string()
}
}
impl From<&NodeID> for String {
fn from(val: &NodeID) -> Self {
val.to_string()
}
}
impl From<u128> for NodeID {
fn from(val: u128) -> Self {
NodeID::with_u128(val)
}
}
impl AsRef<NodeID> for NodeID {
fn as_ref(&self) -> &NodeID {
self
}
}
#[cfg(feature = "serde")]
impl Serialize for NodeID {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(&self.to_string())
}
}
#[cfg(feature = "serde")]
impl<'de> Deserialize<'de> for NodeID {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let s = String::deserialize(deserializer)?;
NodeID::with_str(&s).map_err(de::Error::custom)
}
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct EdgeID(Arc<String>);
impl EdgeID {
pub fn new() -> EdgeID {
EdgeID(Arc::new(Fuid::new().to_string()))
}
pub fn with_str(s: &str) -> Result<EdgeID> {
Ok(EdgeID(Arc::new(s.to_string())))
}
pub fn with_u128(i: u128) -> EdgeID {
EdgeID(Arc::new(i.to_string()))
}
pub fn as_str(&self) -> &str {
self.0.as_str()
}
}
impl Default for EdgeID {
fn default() -> Self {
Self::new()
}
}
impl fmt::Display for EdgeID {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl fmt::Debug for EdgeID {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("EdgeID")
.field(&self.to_string())
.finish()
}
}
impl FromStr for EdgeID {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self> {
EdgeID::with_str(s)
}
}
impl From<&str> for EdgeID {
fn from(val: &str) -> Self {
EdgeID::with_str(val).unwrap()
}
}
impl From<String> for EdgeID {
fn from(val: String) -> Self {
EdgeID::with_str(&val).unwrap()
}
}
impl From<EdgeID> for String {
fn from(val: EdgeID) -> Self {
val.to_string()
}
}
impl From<&EdgeID> for String {
fn from(val: &EdgeID) -> Self {
val.to_string()
}
}
impl From<u128> for EdgeID {
fn from(val: u128) -> Self {
EdgeID::with_u128(val)
}
}
impl AsRef<EdgeID> for EdgeID {
fn as_ref(&self) -> &EdgeID {
self
}
}
#[cfg(feature = "serde")]
impl Serialize for EdgeID {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(&self.to_string())
}
}
#[cfg(feature = "serde")]
impl<'de> Deserialize<'de> for EdgeID {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let s = String::deserialize(deserializer)?;
EdgeID::with_str(&s).map_err(de::Error::custom)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_node_id() -> Result<(), Box<dyn std::error::Error>> {
let a = "6fTiplVKIi6bJFe8rTXPcu";
let b = "5z1JeaxqBJ4Y3pEXh2B8Sj";
let fa = NodeID::with_str(a)?;
let fb = NodeID::with_str(b)?;
assert_eq!(fa.to_string(), a);
assert_eq!(fb.to_string(), b);
assert_ne!(NodeID::new(), fa);
assert_ne!(NodeID::new(), fb);
let _: NodeID = "A".into();
let _: NodeID = "A".to_string().into();
let _: NodeID = 1.into();
Ok(())
}
#[cfg(feature = "serde")]
#[test]
fn test_node_id_serde() -> Result<(), Box<dyn std::error::Error>> {
use serde_json::{to_string, from_str};
let a = NodeID::new();
let b = to_string(&a)?;
let c: NodeID = from_str(&b)?;
assert_eq!(a, c);
Ok(())
}
#[test]
fn test_edge_id() -> Result<(), Box<dyn std::error::Error>> {
let a = "6fTiplVKIi6bJFe8rTXPcu";
let b = "5z1JeaxqBJ4Y3pEXh2B8Sj";
let fa = EdgeID::with_str(a)?;
let fb = EdgeID::with_str(b)?;
assert_eq!(fa.to_string(), a);
assert_eq!(fb.to_string(), b);
assert_ne!(EdgeID::new(), fa);
assert_ne!(EdgeID::new(), fb);
let _: EdgeID = "A".into();
let _: EdgeID = "A".to_string().into();
let _: EdgeID = 1.into();
Ok(())
}
#[cfg(feature = "serde")]
#[test]
fn test_edge_id_serde() -> Result<(), Box<dyn std::error::Error>> {
use serde_json::{to_string, from_str};
let a = EdgeID::new();
let b = to_string(&a)?;
let c: EdgeID = from_str(&b)?;
assert_eq!(a, c);
Ok(())
}
}