diff --git a/domo_lib/src/filter/filters/function_filter.rs b/domo_lib/src/filter/filters/function_filter.rs new file mode 100644 index 0000000..1049e9a --- /dev/null +++ b/domo_lib/src/filter/filters/function_filter.rs @@ -0,0 +1,6 @@ +use domo_proto::packet::Packet; + +use crate::filter::FilterState; + +pub type FunctionFilterFunction = fn(FilterState) -> FilterState; +pub struct FunctionFilter(pub FunctionFilterFunction); diff --git a/domo_lib/src/filter/filters/mod.rs b/domo_lib/src/filter/filters/mod.rs new file mode 100644 index 0000000..c8eba15 --- /dev/null +++ b/domo_lib/src/filter/filters/mod.rs @@ -0,0 +1,16 @@ +use super::Filter; + +pub mod function_filter; +pub mod packet; + +/// Only allow Pass or Drops. +pub struct StrictFilter; +impl Filter for StrictFilter { + fn filter(&self, f: super::FilterState) -> super::FilterState { + if let super::FilterState::Skip(_) = f { + super::FilterState::Drop + } else { + f + } + } +} \ No newline at end of file diff --git a/domo_lib/src/filter/filters/packet.rs b/domo_lib/src/filter/filters/packet.rs new file mode 100644 index 0000000..27f8778 --- /dev/null +++ b/domo_lib/src/filter/filters/packet.rs @@ -0,0 +1,28 @@ +use domo_proto::packet::Packet; + +use crate::filter::{Filter, FilterState}; + +use super::function_filter::FunctionFilter; + +pub trait PacketFilter: Filter { + fn filter_packet(&self, filter_packet: Packet) -> FilterState { + self.filter(FilterState::Pass(filter_packet)) + } +} + +impl PacketFilter for FunctionFilter {} +impl Filter for FunctionFilter { + fn filter(&self, f: FilterState) -> FilterState { + (self.0)(f) + } +} + +impl Filter for Packet { + fn filter(&self, f: FilterState) -> FilterState { + match f { + FilterState::Pass(p) => if &p != self { FilterState::Drop } else { FilterState::Pass(p) }, + FilterState::Skip(p) => if &p != self { FilterState::Drop } else { FilterState::Pass(p) }, + FilterState::Drop => FilterState::Drop, + } + } +} \ No newline at end of file diff --git a/domo_lib/src/filter/mod.rs b/domo_lib/src/filter/mod.rs new file mode 100644 index 0000000..24f3f74 --- /dev/null +++ b/domo_lib/src/filter/mod.rs @@ -0,0 +1,18 @@ +pub mod filters; + +#[derive(Debug, PartialEq, Eq)] +pub enum FilterState { + /// T passed filter + Pass(T), + /// T was not subject to filter. + Skip(T), + /// T did not pass filter + Drop +} + +pub trait Filter { + fn filter(&self, f: FilterState) -> FilterState { + f + } +} + diff --git a/domo_lib/src/lib.rs b/domo_lib/src/lib.rs index 12e2c60..4b89800 100644 --- a/domo_lib/src/lib.rs +++ b/domo_lib/src/lib.rs @@ -1 +1,6 @@ -pub mod node; \ No newline at end of file +/// Node abstraction +pub mod node; +/// Filters +pub mod filter; +/// Routing essentials +pub mod routing; \ No newline at end of file diff --git a/domo_lib/src/node/mod.rs b/domo_lib/src/node/mod.rs index 78da42a..596f14f 100644 --- a/domo_lib/src/node/mod.rs +++ b/domo_lib/src/node/mod.rs @@ -1,16 +1,51 @@ -use std::collections::HashMap; -use domo_proto::identifier::Identifier; use self::property::Property; +use domo_proto::identifier::Identifier; +use std::collections::HashMap; pub mod property; +/// Simple Node abstraction. +#[derive(Debug, Clone)] pub struct Node { /// Who owns this node? pub parent: Option, /// Identifier of node pub identifier: Identifier, /// Child nodes - pub children: HashMap, + children: HashMap, /// All properties of the node. - pub properties: HashMap + pub properties: HashMap, +} + +impl Node { + pub fn new(node_id: Identifier) -> Self { + Node { + parent: None, + identifier: node_id, + children: HashMap::new(), + properties: HashMap::new(), + } + } + + pub fn add_child(&mut self, node: Node) -> bool { + if self.children.contains_key(&node.identifier) { + return false; + } + self.children.insert(node.identifier, node); + true + } + + pub fn find<'a>(&'a mut self, identifier: &Identifier) -> Option<&'a mut Node> { + if self.identifier == *identifier { + return Some(self); + } + + for (_, child) in self.children.iter_mut() { + if let Some(found) = child.find(identifier) { + return Some(found); + } + } + + None + } } \ No newline at end of file diff --git a/domo_lib/src/node/property.rs b/domo_lib/src/node/property.rs index 7bd7ea5..51a48d1 100644 --- a/domo_lib/src/node/property.rs +++ b/domo_lib/src/node/property.rs @@ -1,5 +1,6 @@ use domo_proto::data_types::DataType; +#[derive(Debug, Clone)] pub struct Property { /// Is the property descriptive? pub descriptive: bool, diff --git a/domo_lib/src/routing/endpoint.rs b/domo_lib/src/routing/endpoint.rs new file mode 100644 index 0000000..55d8be2 --- /dev/null +++ b/domo_lib/src/routing/endpoint.rs @@ -0,0 +1,7 @@ +use crate::filter::Filter; + +pub trait Endpoint: Filter { + fn handle(&mut self, item: T) { + self.handle(item) + } +} diff --git a/domo_lib/src/routing/mod.rs b/domo_lib/src/routing/mod.rs new file mode 100644 index 0000000..742b3b1 --- /dev/null +++ b/domo_lib/src/routing/mod.rs @@ -0,0 +1,52 @@ +use domo_proto::packet::Packet; + +use crate::filter::{ + filters::{ + function_filter::{FunctionFilter, FunctionFilterFunction}, + packet::PacketFilter, + }, + Filter, FilterState, +}; + +use self::endpoint::Endpoint; + +pub mod endpoint; + +/// The Router will first filter the packet through the filter chain. +/// Then it will filter past all endpoints and send the packet if the endpoint filter passed. +pub struct Router<'a> { + filters: Vec>, + endpoints: Vec + 'a>>, +} + +impl<'a> Router<'a> { + pub fn new() -> Router<'a> { + Router { + filters: vec![], + endpoints: vec![], + } + } + + pub fn add_filter(&mut self, filter: impl PacketFilter + 'a) { + self.filters.push(Box::new(filter)); + } + + pub fn add_function_filter(&mut self, function: FunctionFilterFunction) { + self.filters.push(Box::new(FunctionFilter(function))) + } + + pub fn add_endpoint(&mut self, endpoint: impl Endpoint + 'a) { + self.endpoints.push(Box::new(endpoint)) + } +} + +impl PacketFilter for Router<'_> {} +impl Filter for Router<'_> { + fn filter(&self, f: FilterState) -> FilterState { + let mut f = f; + for filter in &self.filters { + f = filter.filter(f); + } + f + } +} \ No newline at end of file