From 88be4b9eb9f8cd1b0f5104b7d7ad83859343d38c Mon Sep 17 00:00:00 2001 From: Kubat <mael.martin31@gmail.com> Date: Wed, 1 Mar 2023 14:47:49 +0100 Subject: [PATCH] KURISU: Try to deserialize one or multiple karas with one structure --- src/rust/kurisu_api/src/v1.rs | 61 ++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/src/rust/kurisu_api/src/v1.rs b/src/rust/kurisu_api/src/v1.rs index f038adaa..6cd25131 100644 --- a/src/rust/kurisu_api/src/v1.rs +++ b/src/rust/kurisu_api/src/v1.rs @@ -1,8 +1,11 @@ //! Object rules for the Kurisu's V1 API +use commons::either; use serde::Deserialize; -#[derive(Debug, Deserialize)] +use crate::new_route; + +#[derive(Debug, Deserialize, Clone, Copy)] pub struct Kara<'a> { pub id: i64, pub source_name: &'a str, @@ -33,3 +36,59 @@ impl<'a> Kara<'a> { } } } + +#[derive(Debug)] +pub enum MaybeKaraList<'a> { + Empty, + Single(Kara<'a>), + Multi(Vec<Kara<'a>>), +} + +impl<'a, 'de> Deserialize<'de> for MaybeKaraList<'a> +where + 'de: 'a, +{ + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: serde::Deserializer<'de>, + { + struct Visitor; + impl<'de> ::serde::de::Visitor<'de> for Visitor { + type Value = MaybeKaraList<'de>; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(formatter, "a kara or a sequence of karas") + } + + fn visit_seq<S>(self, mut visitor: S) -> Result<Self::Value, S::Error> + where + S: serde::de::SeqAccess<'de>, + { + let mut ret: Vec<Kara> = Vec::new(); + while let Ok(Some(kara)) = visitor.next_element() { + ret.push(kara); + } + Ok(match ret[..] { + [] => MaybeKaraList::Empty, + [single] => MaybeKaraList::Single(single), + _ => MaybeKaraList::Multi(ret), + }) + } + } + + deserializer.deserialize_any(Visitor) + } +} + +#[derive(Debug, Deserialize, PartialEq, Eq)] +#[serde(transparent)] +pub struct KaraDl<'a> { + pub content: Vec<u8>, + + #[serde(skip)] + _phantom: std::marker::PhantomData<&'a u8>, +} + +new_route! { GetKara :: "/@" #1 -> MaybeKaraList } +new_route! { GetKaraPerId :: "/id/@" #1 -> Kara } +new_route! { GetKaraDl :: "/download/@" #1 -> KaraDl } -- GitLab