feat: impl bunch of goodies

This commit is contained in:
Strix 2023-12-04 14:03:04 +01:00
parent a62fd81bf2
commit 54a99e43e1
No known key found for this signature in database
GPG key ID: 5F35B3B8537287A7
9 changed files with 173 additions and 5 deletions

View file

@ -0,0 +1,6 @@
use domo_proto::packet::Packet;
use crate::filter::FilterState;
pub type FunctionFilterFunction = fn(FilterState<Packet>) -> FilterState<Packet>;
pub struct FunctionFilter(pub FunctionFilterFunction);

View file

@ -0,0 +1,16 @@
use super::Filter;
pub mod function_filter;
pub mod packet;
/// Only allow Pass or Drops.
pub struct StrictFilter;
impl<T> Filter<T> for StrictFilter {
fn filter(&self, f: super::FilterState<T>) -> super::FilterState<T> {
if let super::FilterState::Skip(_) = f {
super::FilterState::Drop
} else {
f
}
}
}

View file

@ -0,0 +1,28 @@
use domo_proto::packet::Packet;
use crate::filter::{Filter, FilterState};
use super::function_filter::FunctionFilter;
pub trait PacketFilter: Filter<Packet> {
fn filter_packet(&self, filter_packet: Packet) -> FilterState<Packet> {
self.filter(FilterState::Pass(filter_packet))
}
}
impl PacketFilter for FunctionFilter {}
impl Filter<Packet> for FunctionFilter {
fn filter(&self, f: FilterState<Packet>) -> FilterState<Packet> {
(self.0)(f)
}
}
impl Filter<Packet> for Packet {
fn filter(&self, f: FilterState<Packet>) -> FilterState<Packet> {
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,
}
}
}

View file

@ -0,0 +1,18 @@
pub mod filters;
#[derive(Debug, PartialEq, Eq)]
pub enum FilterState<T> {
/// T passed filter
Pass(T),
/// T was not subject to filter.
Skip(T),
/// T did not pass filter
Drop
}
pub trait Filter<T> {
fn filter(&self, f: FilterState<T>) -> FilterState<T> {
f
}
}

View file

@ -1 +1,6 @@
/// Node abstraction
pub mod node; pub mod node;
/// Filters
pub mod filter;
/// Routing essentials
pub mod routing;

View file

@ -1,16 +1,51 @@
use std::collections::HashMap;
use domo_proto::identifier::Identifier;
use self::property::Property; use self::property::Property;
use domo_proto::identifier::Identifier;
use std::collections::HashMap;
pub mod property; pub mod property;
/// Simple Node abstraction.
#[derive(Debug, Clone)]
pub struct Node { pub struct Node {
/// Who owns this node? /// Who owns this node?
pub parent: Option<Identifier>, pub parent: Option<Identifier>,
/// Identifier of node /// Identifier of node
pub identifier: Identifier, pub identifier: Identifier,
/// Child nodes /// Child nodes
pub children: HashMap<Identifier, Node>, children: HashMap<Identifier, Node>,
/// All properties of the node. /// All properties of the node.
pub properties: HashMap<String, Property> pub properties: HashMap<String, Property>,
}
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
}
} }

View file

@ -1,5 +1,6 @@
use domo_proto::data_types::DataType; use domo_proto::data_types::DataType;
#[derive(Debug, Clone)]
pub struct Property { pub struct Property {
/// Is the property descriptive? /// Is the property descriptive?
pub descriptive: bool, pub descriptive: bool,

View file

@ -0,0 +1,7 @@
use crate::filter::Filter;
pub trait Endpoint<T>: Filter<T> {
fn handle(&mut self, item: T) {
self.handle(item)
}
}

View file

@ -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<Box<dyn PacketFilter + 'a>>,
endpoints: Vec<Box<dyn Endpoint<Packet> + '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<Packet> + 'a) {
self.endpoints.push(Box::new(endpoint))
}
}
impl PacketFilter for Router<'_> {}
impl Filter<Packet> for Router<'_> {
fn filter(&self, f: FilterState<Packet>) -> FilterState<Packet> {
let mut f = f;
for filter in &self.filters {
f = filter.filter(f);
}
f
}
}