diff options
author | metamuffin <metamuffin@disroot.org> | 2025-04-01 17:32:31 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2025-04-01 17:32:31 +0200 |
commit | 8f6f8004361a2f597d16baf4d4e2d32ff477cd75 (patch) | |
tree | ce5a62276954a30299cd87b4bc7eb1526c879524 /src | |
parent | 7675d17f055005bf3bdeaf694a453ff134a78e8f (diff) | |
download | gnix-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.rs | 45 |
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)) + } +} |