pub mod error;
pub mod noop;
#[cfg(feature = "rest-api")]
pub mod rest_api;
#[cfg(feature = "node-registry-unified")]
pub mod unified;
pub mod yaml;
use std::collections::HashMap;
pub use error::{InvalidNodeError, NodeRegistryError};
#[cfg(feature = "node-registry-unified")]
pub use unified::UnifiedNodeRegistry;
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct Node {
pub identity: String,
pub endpoint: String,
pub display_name: String,
pub metadata: HashMap<String, String>,
}
impl Node {
pub fn new<S: Into<String>>(identity: S, endpoint: S) -> Self {
Self {
identity: identity.into(),
endpoint: endpoint.into(),
display_name: String::new(),
metadata: Default::default(),
}
}
}
#[derive(Clone)]
pub enum MetadataPredicate {
Eq(String, String),
Ne(String, String),
Gt(String, String),
Ge(String, String),
Lt(String, String),
Le(String, String),
}
impl MetadataPredicate {
pub fn apply(&self, node: &Node) -> bool {
match self {
MetadataPredicate::Eq(key, val) => {
node.metadata.get(key).map(|v| v == val).unwrap_or(false)
}
MetadataPredicate::Ne(key, val) => {
node.metadata.get(key).map(|v| v != val).unwrap_or(true)
}
MetadataPredicate::Gt(key, val) => {
node.metadata.get(key).map(|v| v > val).unwrap_or(false)
}
MetadataPredicate::Ge(key, val) => {
node.metadata.get(key).map(|v| v >= val).unwrap_or(false)
}
MetadataPredicate::Lt(key, val) => {
node.metadata.get(key).map(|v| v < val).unwrap_or(false)
}
MetadataPredicate::Le(key, val) => {
node.metadata.get(key).map(|v| v <= val).unwrap_or(false)
}
}
}
pub fn eq<S: Into<String>>(key: S, value: S) -> MetadataPredicate {
MetadataPredicate::Eq(key.into(), value.into())
}
pub fn ne<S: Into<String>>(key: S, value: S) -> MetadataPredicate {
MetadataPredicate::Ne(key.into(), value.into())
}
}
pub trait NodeRegistryReader: Send + Sync {
fn list_nodes<'a, 'b: 'a>(
&'b self,
predicates: &'a [MetadataPredicate],
) -> Result<Box<dyn Iterator<Item = Node> + Send + 'a>, NodeRegistryError>;
fn count_nodes(&self, predicates: &[MetadataPredicate]) -> Result<u32, NodeRegistryError>;
fn fetch_node(&self, identity: &str) -> Result<Node, NodeRegistryError>;
fn has_node(&self, identity: &str) -> Result<bool, NodeRegistryError> {
match self.fetch_node(identity) {
Ok(_) => Ok(true),
Err(NodeRegistryError::NotFoundError(_)) => Ok(false),
Err(err) => Err(err),
}
}
}
pub trait NodeRegistryWriter: Send + Sync {
fn insert_node(&self, node: Node) -> Result<(), NodeRegistryError>;
fn delete_node(&self, identity: &str) -> Result<(), NodeRegistryError>;
}
pub trait RwNodeRegistry: NodeRegistryWriter + NodeRegistryReader {
fn clone_box(&self) -> Box<dyn RwNodeRegistry>;
}
impl Clone for Box<dyn RwNodeRegistry> {
fn clone(&self) -> Box<dyn RwNodeRegistry> {
self.clone_box()
}
}
impl<NR> NodeRegistryReader for Box<NR>
where
NR: NodeRegistryReader + ?Sized,
{
fn list_nodes<'a, 'b: 'a>(
&'b self,
predicates: &'a [MetadataPredicate],
) -> Result<Box<dyn Iterator<Item = Node> + Send + 'a>, NodeRegistryError> {
(**self).list_nodes(predicates)
}
fn count_nodes(&self, predicates: &[MetadataPredicate]) -> Result<u32, NodeRegistryError> {
(**self).count_nodes(predicates)
}
fn fetch_node(&self, identity: &str) -> Result<Node, NodeRegistryError> {
(**self).fetch_node(identity)
}
fn has_node(&self, identity: &str) -> Result<bool, NodeRegistryError> {
(**self).has_node(identity)
}
}
impl<NW> NodeRegistryWriter for Box<NW>
where
NW: NodeRegistryWriter + ?Sized,
{
fn insert_node(&self, node: Node) -> Result<(), NodeRegistryError> {
(**self).insert_node(node)
}
fn delete_node(&self, identity: &str) -> Result<(), NodeRegistryError> {
(**self).delete_node(identity)
}
}