From 8f6f8004361a2f597d16baf4d4e2d32ff477cd75 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Tue, 1 Apr 2025 17:32:31 +0200 Subject: accept list of maps in paths module for non-hacky ordering --- src/modules/paths.rs | 45 ++++++++++++++++++++++++++++++++++++++++----- 1 file 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> { - let routes = serde_yml::from_value::>(config)? - .into_iter() - .collect::>(); - + let routes = serde_yml::from_value::>(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(Vec<(String, T)>); +impl<'de, T: Deserialize<'de>> Deserialize<'de> for SeqOrMap { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + struct Vis(PhantomData); + impl<'de, V: Deserialize<'de>> Visitor<'de> for Vis { + type Value = SeqOrMap; + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("map or sequence of maps") + } + fn visit_seq(self, seq: A) -> Result + where + A: serde::de::SeqAccess<'de>, + { + Vec::>::deserialize(SeqAccessDeserializer::new(seq)) + .map(|e| SeqOrMap(e.into_iter().flat_map(|el| el.into_iter()).collect())) + } + fn visit_map(self, map: A) -> Result + where + A: serde::de::MapAccess<'de>, + { + BTreeMap::::deserialize(MapAccessDeserializer::new(map)) + .map(|map| SeqOrMap(map.into_iter().collect())) + } + } + deserializer.deserialize_any(Vis(PhantomData)) + } +} -- cgit v1.2.3-70-g09d2