This commit is contained in:
parent
2973a703cc
commit
9e4b2d99b4
10 changed files with 43 additions and 218 deletions
2
domo_lib/Cargo.lock
generated
2
domo_lib/Cargo.lock
generated
|
@ -19,7 +19,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "domo_lib"
|
name = "domo_lib"
|
||||||
version = "0.2.0"
|
version = "0.3.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"domo_proto",
|
"domo_proto",
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "domo_lib"
|
name = "domo_lib"
|
||||||
version = "0.2.0"
|
version = "0.3.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
use domo_proto::packet::Packet;
|
|
||||||
|
|
||||||
use crate::filter::FilterState;
|
|
||||||
|
|
||||||
pub type FunctionFilterFunction = fn(FilterState<Packet>) -> FilterState<Packet>;
|
|
||||||
pub struct FunctionFilter(pub FunctionFilterFunction);
|
|
|
@ -1,16 +0,0 @@
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
use domo_proto::packet::Packet;
|
|
||||||
|
|
||||||
use crate::filter::{Filter, FilterState};
|
|
||||||
|
|
||||||
use super::function_filter::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,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
pub mod filters;
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub enum FilterState<T> {
|
|
||||||
/// T passed filter
|
|
||||||
Pass(T),
|
|
||||||
/// T was not subject to filter.
|
|
||||||
Skip(T),
|
|
||||||
/// T did not pass filter
|
|
||||||
Drop,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> FilterState<T> {
|
|
||||||
pub fn to_type(self) -> Option<T> {
|
|
||||||
match self {
|
|
||||||
FilterState::Pass(v) | FilterState::Skip(v) => Some(v),
|
|
||||||
FilterState::Drop => None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_pass(&self) -> bool {
|
|
||||||
if let FilterState::Pass(_) = self {
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_skip(&self) -> bool {
|
|
||||||
if let FilterState::Skip(_) = self {
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_drop(&self) -> bool {
|
|
||||||
if let FilterState::Drop = self {
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Filter<T> {
|
|
||||||
fn filter(&self, f: FilterState<T>) -> FilterState<T> {
|
|
||||||
f
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +1,2 @@
|
||||||
/// Node abstraction
|
/// Node abstraction
|
||||||
pub mod node;
|
pub mod node;
|
||||||
/// Filters
|
|
||||||
pub mod filter;
|
|
||||||
/// Routing essentials
|
|
||||||
pub mod routing;
|
|
|
@ -1,7 +1,5 @@
|
||||||
use crate::filter::Filter;
|
|
||||||
|
|
||||||
use self::property::Property;
|
use self::property::Property;
|
||||||
use domo_proto::{identifier::Identifier, packet::Packet};
|
use domo_proto::identifier::Identifier;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
pub mod property;
|
pub mod property;
|
||||||
|
@ -12,11 +10,11 @@ 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,
|
identifier: Identifier,
|
||||||
/// Child nodes
|
/// Child nodes
|
||||||
children: HashMap<Identifier, Node>,
|
children: HashMap<Identifier, Node>,
|
||||||
/// All properties of the node.
|
/// All properties of the node.
|
||||||
pub properties: HashMap<String, Property>,
|
properties: HashMap<String, Property>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Node {
|
impl Node {
|
||||||
|
@ -30,6 +28,25 @@ impl Node {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return reference to Node's identifier
|
||||||
|
pub fn identifier(&self) -> &Identifier {
|
||||||
|
&self.identifier
|
||||||
|
}
|
||||||
|
|
||||||
|
/// (Over)writes property to self.
|
||||||
|
/// Returns a mutable reference to property.
|
||||||
|
pub fn insert_property<'a>(&'a mut self, property: Property) -> &'a mut Property {
|
||||||
|
self.properties
|
||||||
|
.insert(property.name.clone(), property.clone());
|
||||||
|
self.properties.get_mut(&property.name).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Attempts to remove property from self.
|
||||||
|
/// Returns a mutable reference to the added node.
|
||||||
|
pub fn remove_property(&mut self, name: String) -> Option<Property> {
|
||||||
|
self.properties.remove(&name)
|
||||||
|
}
|
||||||
|
|
||||||
/// Attempts to add child node to self.
|
/// Attempts to add child node to self.
|
||||||
/// Returns a mutable reference to the added node.
|
/// Returns a mutable reference to the added node.
|
||||||
pub fn add_child<'a>(&'a mut self, mut node: Node) -> Option<&'a mut Node> {
|
pub fn add_child<'a>(&'a mut self, mut node: Node) -> Option<&'a mut Node> {
|
||||||
|
@ -50,49 +67,35 @@ impl Node {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns if this node has the identifier.
|
/// Check if node has an identifier.
|
||||||
|
/// Only checks children.
|
||||||
pub fn has(&self, identifier: &Identifier) -> bool {
|
pub fn has(&self, identifier: &Identifier) -> bool {
|
||||||
self.children.contains_key(identifier)
|
self.children.contains_key(identifier)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempts to find given identifier and returns mutable reference to it.
|
/// Attempts to find given identifier and returns reference to it.
|
||||||
pub fn find<'a>(&'a mut self, identifier: &Identifier) -> Option<&'a mut Node> {
|
pub fn find<'a>(&'a self, identifier: &Identifier) -> Option<&'a Node> {
|
||||||
for (_, child) in self.children.iter_mut() {
|
if self.identifier == *identifier {
|
||||||
|
return Some(self);
|
||||||
|
}
|
||||||
|
for (_, child) in self.children.iter() {
|
||||||
if let Some(found) = child.find(identifier) {
|
if let Some(found) = child.find(identifier) {
|
||||||
return Some(found);
|
return Some(found);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl Filter<Identifier> for Node {
|
/// Attempts to find given identifier and returns mutable reference to it.
|
||||||
fn filter(
|
pub fn find_mut<'a>(&'a mut self, identifier: &Identifier) -> Option<&'a mut Node> {
|
||||||
&self,
|
if self.identifier == *identifier {
|
||||||
f: crate::filter::FilterState<Identifier>,
|
return Some(self);
|
||||||
) -> crate::filter::FilterState<Identifier> {
|
|
||||||
if let Some(i) = f.to_type() {
|
|
||||||
if self.has(&i) || i == self.identifier {
|
|
||||||
crate::filter::FilterState::Pass(i)
|
|
||||||
} else {
|
|
||||||
crate::filter::FilterState::Skip(i)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
crate::filter::FilterState::Drop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Filter<Packet> for Node {
|
|
||||||
fn filter(&self, f: crate::filter::FilterState<Packet>) -> crate::filter::FilterState<Packet> {
|
|
||||||
if let Some(p) = f.to_type() {
|
|
||||||
if self.has(&p.dest) || self.identifier == p.dest {
|
|
||||||
crate::filter::FilterState::Pass(p)
|
|
||||||
} else {
|
|
||||||
crate::filter::FilterState::Skip(p)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
crate::filter::FilterState::Drop
|
|
||||||
}
|
}
|
||||||
|
for (_, child) in self.children.iter_mut() {
|
||||||
|
if let Some(found) = child.find_mut(identifier) {
|
||||||
|
return Some(found);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
use crate::filter::Filter;
|
|
||||||
|
|
||||||
/// Endpoints are a non-returning trait.
|
|
||||||
/// Because endpoints *should* be the last thing in the chain, you *should* manage errors in there!
|
|
||||||
pub trait Endpoint<T>: Filter<T> {
|
|
||||||
fn handle(&mut self, item: T);
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
use domo_proto::packet::Packet;
|
|
||||||
|
|
||||||
use crate::filter::{
|
|
||||||
filters::function_filter::{FunctionFilter, FunctionFilterFunction},
|
|
||||||
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 Filter<Packet> + '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 Filter<Packet> + '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 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Endpoint<Packet> for Router<'_> {
|
|
||||||
fn handle(&mut self, item: Packet) {
|
|
||||||
let item = self.filter(FilterState::Pass(item));
|
|
||||||
for endpoint in &mut self.endpoints {
|
|
||||||
match endpoint.filter(item.clone()) {
|
|
||||||
FilterState::Pass(p) | FilterState::Skip(p) => {
|
|
||||||
let _ = &endpoint.handle(p);
|
|
||||||
}
|
|
||||||
FilterState::Drop => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue