aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-04-01 17:32:31 +0200
committermetamuffin <metamuffin@disroot.org>2025-04-01 17:32:31 +0200
commit8f6f8004361a2f597d16baf4d4e2d32ff477cd75 (patch)
treece5a62276954a30299cd87b4bc7eb1526c879524 /src
parent7675d17f055005bf3bdeaf694a453ff134a78e8f (diff)
downloadgnix-8f6f8004361a2f597d16baf4d4e2d32ff477cd75.tar
gnix-8f6f8004361a2f597d16baf4d4e2d32ff477cd75.tar.bz2
gnix-8f6f8004361a2f597d16baf4d4e2d32ff477cd75.tar.zst
accept list of maps in paths module for non-hacky ordering
Diffstat (limited to 'src')
-rw-r--r--src/modules/paths.rs45
1 files changed, 40 insertions, 5 deletions
diff --git a/src/modules/paths.rs b/src/modules/paths.rs
index 38cdf4b..7131664 100644
--- a/src/modules/paths.rs
+++ b/src/modules/paths.rs
@@ -8,8 +8,15 @@ use crate::{config::DynNode, error::ServiceError};
use futures::Future;
use http::Uri;
use regex::{Regex, RegexSet};
+use serde::{
+ de::{
+ value::{MapAccessDeserializer, SeqAccessDeserializer},
+ Visitor,
+ },
+ Deserialize,
+};
use serde_yml::Value;
-use std::{collections::BTreeMap, pin::Pin, sync::Arc};
+use std::{collections::BTreeMap, marker::PhantomData, pin::Pin, sync::Arc};
pub struct PathsKind;
@@ -24,10 +31,7 @@ impl NodeKind for PathsKind {
"paths"
}
fn instanciate(&self, config: Value) -> anyhow::Result<Arc<dyn Node>> {
- let routes = serde_yml::from_value::<BTreeMap<String, DynNode>>(config)?
- .into_iter()
- .collect::<Vec<(String, DynNode)>>();
-
+ let routes = serde_yml::from_value::<SeqOrMap<DynNode>>(config)?.0;
let mut handlers = Vec::new();
let mut patterns = Vec::new();
let mut extractors = Vec::new();
@@ -88,3 +92,34 @@ impl Node for Paths {
})
}
}
+
+struct SeqOrMap<T>(Vec<(String, T)>);
+impl<'de, T: Deserialize<'de>> Deserialize<'de> for SeqOrMap<T> {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ struct Vis<V>(PhantomData<V>);
+ impl<'de, V: Deserialize<'de>> Visitor<'de> for Vis<V> {
+ type Value = SeqOrMap<V>;
+ fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
+ formatter.write_str("map or sequence of maps")
+ }
+ fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
+ where
+ A: serde::de::SeqAccess<'de>,
+ {
+ Vec::<BTreeMap<String, V>>::deserialize(SeqAccessDeserializer::new(seq))
+ .map(|e| SeqOrMap(e.into_iter().flat_map(|el| el.into_iter()).collect()))
+ }
+ fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error>
+ where
+ A: serde::de::MapAccess<'de>,
+ {
+ BTreeMap::<String, V>::deserialize(MapAccessDeserializer::new(map))
+ .map(|map| SeqOrMap(map.into_iter().collect()))
+ }
+ }
+ deserializer.deserialize_any(Vis(PhantomData))
+ }
+}