fix: remove PacketFilter, implement more filters and doc

This commit is contained in:
Strix 2023-12-10 03:32:08 +01:00
parent 745a7919b6
commit cea167c164
No known key found for this signature in database
GPG key ID: 5F35B3B8537287A7
8 changed files with 133 additions and 36 deletions

4
.gitignore vendored
View file

@ -4,5 +4,5 @@
# build # build
**/target/ **/target/
**/*.log **/*.log
# random testing # testing
domo_proto/src/main.rs domo_test/

4
domo_lib/Cargo.lock generated
View file

@ -19,14 +19,14 @@ dependencies = [
[[package]] [[package]]
name = "domo_lib" name = "domo_lib"
version = "0.1.0" version = "0.2.0"
dependencies = [ dependencies = [
"domo_proto", "domo_proto",
] ]
[[package]] [[package]]
name = "domo_proto" name = "domo_proto"
version = "0.2.0" version = "1.0.0"
dependencies = [ dependencies = [
"crc32fast", "crc32fast",
"rand", "rand",

View file

@ -1,6 +1,6 @@
[package] [package]
name = "domo_lib" name = "domo_lib"
version = "0.1.0" version = "0.2.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

View file

@ -4,13 +4,6 @@ use crate::filter::{Filter, FilterState};
use super::function_filter::FunctionFilter; 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 { impl Filter<Packet> for FunctionFilter {
fn filter(&self, f: FilterState<Packet>) -> FilterState<Packet> { fn filter(&self, f: FilterState<Packet>) -> FilterState<Packet> {
(self.0)(f) (self.0)(f)
@ -20,8 +13,20 @@ impl Filter<Packet> for FunctionFilter {
impl Filter<Packet> for Packet { impl Filter<Packet> for Packet {
fn filter(&self, f: FilterState<Packet>) -> FilterState<Packet> { fn filter(&self, f: FilterState<Packet>) -> FilterState<Packet> {
match f { match f {
FilterState::Pass(p) => if &p != self { FilterState::Drop } else { FilterState::Pass(p) }, FilterState::Pass(p) => {
FilterState::Skip(p) => if &p != self { FilterState::Drop } else { 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, FilterState::Drop => FilterState::Drop,
} }
} }

View file

@ -1,12 +1,46 @@
pub mod filters; pub mod filters;
#[derive(Clone)]
pub enum FilterState<T> { pub enum FilterState<T> {
/// T passed filter /// T passed filter
Pass(T), Pass(T),
/// T was not subject to filter. /// T was not subject to filter.
Skip(T), Skip(T),
/// T did not pass filter /// T did not pass filter
Drop 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> { pub trait Filter<T> {
@ -14,4 +48,3 @@ pub trait Filter<T> {
f f
} }
} }

View file

@ -1,5 +1,7 @@
use crate::filter::Filter;
use self::property::Property; use self::property::Property;
use domo_proto::identifier::Identifier; use domo_proto::{identifier::Identifier, packet::Packet};
use std::collections::HashMap; use std::collections::HashMap;
pub mod property; pub mod property;
@ -18,6 +20,7 @@ pub struct Node {
} }
impl Node { impl Node {
/// Create a new node
pub fn new(node_id: Identifier) -> Self { pub fn new(node_id: Identifier) -> Self {
Node { Node {
parent: None, parent: None,
@ -27,25 +30,69 @@ impl Node {
} }
} }
pub fn add_child(&mut self, node: Node) -> bool { /// Attempts to add child node to self.
/// Returns a mutable reference to the added node.
pub fn add_child<'a>(&'a mut self, mut node: Node) -> Option<&'a mut Node> {
if self.children.contains_key(&node.identifier) { if self.children.contains_key(&node.identifier) {
return false; return None;
} }
self.children.insert(node.identifier, node); node.parent = Some(self.identifier.clone());
true self.children.insert(node.identifier, node.clone());
self.children.get_mut(&node.identifier)
} }
/// Attempts to remove child from self.
/// Returns removed node.
pub fn remove_child(&mut self, identifier: &Identifier) -> Option<Node> {
self.children.remove(&identifier).map(|mut n| {
n.parent = None;
n
})
}
/// Returns if this node has the identifier.
pub fn has(&self, identifier: &Identifier) -> bool {
self.children.contains_key(identifier)
}
/// Attempts to find given identifier and returns mutable reference to it.
pub fn find<'a>(&'a mut self, identifier: &Identifier) -> Option<&'a mut Node> { 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() { for (_, child) in self.children.iter_mut() {
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 {
fn filter(
&self,
f: crate::filter::FilterState<Identifier>,
) -> 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
}
}
}

View file

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

View file

@ -1,10 +1,7 @@
use domo_proto::packet::Packet; use domo_proto::packet::Packet;
use crate::filter::{ use crate::filter::{
filters::{ filters::function_filter::{FunctionFilter, FunctionFilterFunction},
function_filter::{FunctionFilter, FunctionFilterFunction},
packet::PacketFilter,
},
Filter, FilterState, Filter, FilterState,
}; };
@ -15,7 +12,7 @@ pub mod endpoint;
/// The Router will first filter the packet through the filter chain. /// 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. /// Then it will filter past all endpoints and send the packet if the endpoint filter passed.
pub struct Router<'a> { pub struct Router<'a> {
filters: Vec<Box<dyn PacketFilter + 'a>>, filters: Vec<Box<dyn Filter<Packet> + 'a>>,
endpoints: Vec<Box<dyn Endpoint<Packet> + 'a>>, endpoints: Vec<Box<dyn Endpoint<Packet> + 'a>>,
} }
@ -27,7 +24,7 @@ impl<'a> Router<'a> {
} }
} }
pub fn add_filter(&mut self, filter: impl PacketFilter + 'a) { pub fn add_filter(&mut self, filter: impl Filter<Packet> + 'a) {
self.filters.push(Box::new(filter)); self.filters.push(Box::new(filter));
} }
@ -40,7 +37,6 @@ impl<'a> Router<'a> {
} }
} }
impl PacketFilter for Router<'_> {}
impl Filter<Packet> for Router<'_> { impl Filter<Packet> for Router<'_> {
fn filter(&self, f: FilterState<Packet>) -> FilterState<Packet> { fn filter(&self, f: FilterState<Packet>) -> FilterState<Packet> {
let mut f = f; let mut f = f;
@ -50,3 +46,17 @@ impl Filter<Packet> for Router<'_> {
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 => {}
}
}
}
}