From 6c3524c381467483a025eda5e7e5f0ded53094fa Mon Sep 17 00:00:00 2001 From: metamuffin Date: Mon, 19 Aug 2024 02:52:14 +0200 Subject: paths module --- src/modules/paths.rs | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 src/modules/paths.rs (limited to 'src/modules/paths.rs') diff --git a/src/modules/paths.rs b/src/modules/paths.rs new file mode 100644 index 0000000..b994d48 --- /dev/null +++ b/src/modules/paths.rs @@ -0,0 +1,54 @@ +use super::{Node, NodeContext, NodeKind, NodeRequest, NodeResponse}; +use crate::{config::DynNode, error::ServiceError}; +use futures::Future; +use regex::RegexSet; +use serde_yaml::Value; +use std::{collections::BTreeMap, pin::Pin, sync::Arc}; + +pub struct PathsKind; + +struct Paths { + matcher: RegexSet, + handlers: Vec, +} + +impl NodeKind for PathsKind { + fn name(&self) -> &'static str { + "paths" + } + fn instanciate(&self, config: Value) -> anyhow::Result> { + let routes = serde_yaml::from_value::>(config)? + .into_iter() + .collect::>(); + + let mut handlers = Vec::new(); + let mut patterns = Vec::new(); + for (k, v) in routes { + handlers.push(v); + patterns.push(format!("^{}$", k)); + } + let matcher = RegexSet::new(&patterns)?; + + Ok(Arc::new(Paths { handlers, matcher })) + } +} +impl Node for Paths { + fn handle<'a>( + &'a self, + context: &'a mut NodeContext, + request: NodeRequest, + ) -> Pin> + Send + Sync + 'a>> { + Box::pin(async move { + let path = request.uri().path(); + + let index = self + .matcher + .matches(path) + .iter() + .next() + .ok_or(ServiceError::UnknownPath)?; + + self.handlers[index].handle(context, request).await + }) + } +} -- cgit v1.2.3-70-g09d2