mirror of
https://github.com/Astatin3/unshell.git
synced 2026-06-08 22:38:01 -06:00
Work on remaking routing
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
use alloc::{format, string::ToString};
|
||||
|
||||
use crate::{
|
||||
endpoint::error::EndpointError,
|
||||
packet::Packet,
|
||||
types::{ConnectionSet, HookMap, Path, RouteMap},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct EndpointRef<'a> {
|
||||
pub name: &'static str,
|
||||
pub path: &'a Path,
|
||||
|
||||
pub hooks: &'a mut HookMap,
|
||||
|
||||
pub connections: &'a mut ConnectionSet,
|
||||
|
||||
pub inbound: &'a mut RouteMap,
|
||||
pub outbound: &'a mut RouteMap,
|
||||
}
|
||||
|
||||
impl<'a> EndpointRef<'a> {
|
||||
pub fn add_inbound(&mut self, packet: Packet) -> Result<(), EndpointError> {
|
||||
// If the packet is routed towards this endpoint
|
||||
if packet.path.ends_with(self.name) {
|
||||
if packet.is_upwards_call {
|
||||
self.hooks.insert(packet.hook_id, packet.path.clone());
|
||||
}
|
||||
|
||||
self.outbound
|
||||
.entry(packet.path.clone())
|
||||
.or_default()
|
||||
.push_back(packet);
|
||||
|
||||
Ok(())
|
||||
} else {
|
||||
// If the absolute path of this endpoint hasn't been set yet
|
||||
if self.path.is_empty() {
|
||||
return Err(EndpointError::NoAbsoultePathYet);
|
||||
}
|
||||
|
||||
if *self.path == packet.path {
|
||||
return Err(EndpointError::IncorrectAbsolutePath);
|
||||
}
|
||||
|
||||
// For routing
|
||||
let connection = if packet.is_upwards_call && self.path.starts_with(&packet.path) {
|
||||
(
|
||||
packet
|
||||
.path
|
||||
.rsplit_once('/')
|
||||
.map_or(packet.path.clone(), |(_, after)| after.to_string()),
|
||||
true,
|
||||
)
|
||||
} else if packet
|
||||
.path
|
||||
.starts_with(&format!("{}/{}", self.path, self.name))
|
||||
{
|
||||
let concat_len = self.path.len() + self.name.len();
|
||||
|
||||
let after_self = &packet.path[concat_len..];
|
||||
|
||||
(
|
||||
after_self
|
||||
.split_once('/')
|
||||
.map_or(after_self.to_string(), |(before, _)| before.to_string()),
|
||||
false,
|
||||
)
|
||||
} else {
|
||||
return Err(EndpointError::IncorrectAbsolutePath);
|
||||
};
|
||||
|
||||
if !self.connections.contains(&connection) {
|
||||
return Err(EndpointError::RouteNotExist);
|
||||
}
|
||||
|
||||
self.add_outbound(packet);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_outbound_upwards(&mut self, packet: Packet) -> Result<(), EndpointError> {
|
||||
let next_hop = self
|
||||
.hooks
|
||||
.get(&packet.hook_id)
|
||||
.ok_or(EndpointError::RouteNotExist)?
|
||||
.clone();
|
||||
|
||||
if packet.end_hook {
|
||||
let _ = self.hooks.remove(&packet.hook_id);
|
||||
}
|
||||
|
||||
self.outbound
|
||||
.entry(next_hop.clone())
|
||||
.or_default()
|
||||
.push_back(packet);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn add_outbound_downwards(&mut self, packet: Packet) -> Result<(), EndpointError> {
|
||||
let next_hop = self
|
||||
.hooks
|
||||
.get(&packet.hook_id)
|
||||
.ok_or(EndpointError::RouteNotExist)?
|
||||
.clone();
|
||||
|
||||
if packet.end_hook {
|
||||
let _ = self.hooks.remove(&packet.hook_id);
|
||||
}
|
||||
|
||||
self.outbound
|
||||
.entry(next_hop.clone())
|
||||
.or_default()
|
||||
.push_back(packet);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn take_intbound<F>(&mut self, path: &str, f: F)
|
||||
where
|
||||
F: FnMut(&Packet),
|
||||
{
|
||||
if let Some(queue) = self.inbound.get_mut(path) {
|
||||
let _ = queue.iter().map(f);
|
||||
|
||||
queue.clear();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn take_outbound<F>(&mut self, path: &str, f: F)
|
||||
where
|
||||
F: FnMut(&Packet),
|
||||
{
|
||||
if let Some(queue) = self.inbound.get_mut(path) {
|
||||
let _ = queue.iter().map(f);
|
||||
|
||||
queue.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fn get_last_term_in_path(path: &Path) -> &str {}
|
||||
@@ -0,0 +1,9 @@
|
||||
#[derive(Debug)]
|
||||
pub enum EndpointError {
|
||||
NoAbsoultePathYet,
|
||||
IncorrectAbsolutePath,
|
||||
|
||||
RouteNotExist,
|
||||
HookDuplicate,
|
||||
HookNotExist,
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
mod endpoint_ref;
|
||||
pub mod error;
|
||||
|
||||
use alloc::{boxed::Box, string::String, vec::Vec};
|
||||
|
||||
use crate::{
|
||||
leaf::Leaf,
|
||||
types::{ConnectionSet, HookMap, Path, RouteMap},
|
||||
};
|
||||
|
||||
pub use endpoint_ref::EndpointRef;
|
||||
|
||||
pub struct Endpoint {
|
||||
pub name: &'static str,
|
||||
|
||||
// Absolute path for this node.
|
||||
pub path: Path,
|
||||
pub leaves: Vec<Box<dyn Leaf>>,
|
||||
|
||||
pub connections: ConnectionSet,
|
||||
|
||||
pub hooks: HookMap,
|
||||
pub inbound: RouteMap,
|
||||
pub outbound: RouteMap,
|
||||
}
|
||||
|
||||
impl Endpoint {
|
||||
pub fn new(name: &'static str, leaves: Vec<Box<dyn Leaf>>) -> Self {
|
||||
Self {
|
||||
name,
|
||||
path: String::new(),
|
||||
leaves,
|
||||
hooks: HookMap::new(),
|
||||
connections: ConnectionSet::new(),
|
||||
inbound: RouteMap::new(),
|
||||
outbound: RouteMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(&mut self) {
|
||||
let mut self_ref = EndpointRef {
|
||||
name: self.name,
|
||||
path: &mut self.path,
|
||||
hooks: &mut self.hooks,
|
||||
connections: &mut self.connections,
|
||||
inbound: &mut self.inbound,
|
||||
outbound: &mut self.outbound,
|
||||
};
|
||||
|
||||
let _ = self.leaves.iter_mut().map(|leaf| {
|
||||
leaf.update(&mut self_ref);
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user