diff --git a/src/rust/kurisu_api/src/v1.rs b/src/rust/kurisu_api/src/v1.rs index f038adaa7bfc52573aae139778018e36c35b8959..6cd25131ca7b49a4b2d692fef2a70672926f9602 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 }