From 53c95ff853f987f7d8d86fdad7f87e23a2c349ce Mon Sep 17 00:00:00 2001
From: Kubat <mael.martin31@gmail.com>
Date: Fri, 3 Feb 2023 00:08:39 +0100
Subject: [PATCH] KURISU-API: Add the routes in the APIv2

---
 src/rust/kurisu_api/src/route.rs | 13 ++----
 src/rust/kurisu_api/src/v2.rs    | 75 ++++++++++++++++++++++++++++----
 2 files changed, 70 insertions(+), 18 deletions(-)

diff --git a/src/rust/kurisu_api/src/route.rs b/src/rust/kurisu_api/src/route.rs
index 51e88355..c497855d 100644
--- a/src/rust/kurisu_api/src/route.rs
+++ b/src/rust/kurisu_api/src/route.rs
@@ -45,7 +45,7 @@ macro_rules! route {
 #[macro_export]
 macro_rules! new_route {
     ($obj:ident :: $route:literal # $args:literal -> $ret:ident) => {
-        struct $obj;
+        pub struct $obj;
         impl $crate::route::ApiRoute<$args> for $obj {
             const ROUTE: &'static str = $route;
             type Object<'de> = $ret<'de>;
@@ -55,23 +55,18 @@ macro_rules! new_route {
 
 #[cfg(test)]
 mod test {
-    use crate::v2::*;
-
     #[test]
     fn simple_example() {
-        new_route! { GetRepo     :: "/"           #0 -> Repo      };
-        new_route! { GetKara     :: "/kara/@"     #1 -> Kara      };
-        new_route! { GetPlaylist :: "/playlist/@" #1 -> Playlist  };
-
+        use crate::v2::*;
         assert_eq!(route!(GetKara -> 1), "/kara/1");
     }
 
     #[test]
     fn invalid_route() {
-        new_route! { GetKara::"/kara/@/@"#1 -> Kara };
-
+        use crate::v2::*;
         // Note that no error is returned, because we don't check the route
         // creation...
+        new_route! { GetKara :: "/kara/@/@" #1 -> Kara }
         assert_eq!(route!(GetKara -> 1), "/kara/1/@");
     }
 }
diff --git a/src/rust/kurisu_api/src/v2.rs b/src/rust/kurisu_api/src/v2.rs
index a75cddee..0ba6f985 100644
--- a/src/rust/kurisu_api/src/v2.rs
+++ b/src/rust/kurisu_api/src/v2.rs
@@ -9,7 +9,7 @@ pub struct Repo<'a> {
     pub trusted: Vec<&'a str>,
     pub song_types: Vec<&'a str>,
     pub song_origins: Vec<&'a str>,
-    pub playlists: Vec<&'a str>,
+    pub last_modified_epoch: i64,
 }
 
 #[derive(Debug, Deserialize, PartialEq, Eq)]
@@ -44,8 +44,6 @@ pub enum SongOrigin {
 
 #[derive(Debug, Deserialize, PartialEq, Eq)]
 pub struct Kara<'a> {
-    pub id: i64,
-
     #[serde(rename = "title")]
     pub song_title: &'a str,
 
@@ -72,16 +70,77 @@ pub struct Kara<'a> {
     pub tags: HashMap<&'a str, Vec<&'a str>>,
 }
 
+#[derive(Debug, Deserialize, PartialEq, Eq)]
+#[serde(transparent)]
+pub struct KaraDl<'a> {
+    pub content: Vec<u8>,
+
+    #[serde(skip)]
+    _phantom: std::marker::PhantomData<&'a u8>,
+}
+
+#[derive(Default, Debug, Deserialize, PartialEq, Eq)]
+#[serde(transparent)]
+pub struct KaraList<'a> {
+    pub content: Vec<i64>,
+
+    #[serde(skip)]
+    _phantom: std::marker::PhantomData<&'a u8>,
+}
+
+#[derive(Default, Debug, Deserialize, PartialEq, Eq)]
+#[serde(transparent)]
+pub struct PlaylistList<'a> {
+    pub content: Vec<i64>,
+
+    #[serde(skip)]
+    _phantom: std::marker::PhantomData<&'a u8>,
+}
+
+new_route! { GetRepo         :: "/"           #0 -> Repo          }
+
+new_route! { GetKaras        :: "/kara"       #0 -> KaraList      }
+new_route! { GetKara         :: "/kara/@"     #1 -> Kara          }
+new_route! { GetKaraDl       :: "/kara/dl/@"  #1 -> KaraDl        }
+
+new_route! { GetPlaylistList :: "/playlist"   #0 -> PlaylistList  }
+new_route! { GetPlaylist     :: "/playlist/@" #1 -> Playlist      }
+
 #[cfg(test)]
 mod test {
     use super::*;
     use commons::{assert_err, assert_ok};
 
+    #[test]
+    fn lists() {
+        assert_eq!(
+            assert_ok!(serde_json::from_str::<KaraList>(r#"[]"#)),
+            Default::default()
+        );
+        assert_eq!(
+            assert_ok!(serde_json::from_str::<PlaylistList>(r#"[]"#)),
+            Default::default()
+        );
+        assert_eq!(
+            assert_ok!(serde_json::from_str::<KaraList>(r#"[ 1, 2, 69 ]"#)),
+            KaraList {
+                content: vec![1, 2, 69],
+                ..Default::default()
+            }
+        );
+        assert_eq!(
+            assert_ok!(serde_json::from_str::<PlaylistList>(r#"[ 0, 42 ]"#)),
+            PlaylistList {
+                content: vec![0, 42],
+                ..Default::default()
+            }
+        );
+    }
+
     #[test]
     fn invalid_karas() {
         assert_err!(serde_json::from_str::<Kara>(
-            r#"{ "id": 001
-               , "title": "Totoro"
+            r#"{ "title": "Totoro"
                , "source": "Totoro"
                , "karamakers": [ "Viieux", "Totoro" ]
                , "is_virtual": false
@@ -135,8 +194,7 @@ mod test {
     #[test]
     fn simple_kara() {
         assert_ok!(serde_json::from_str::<Kara>(
-            r#"{ "id": 1
-               , "title": "Totoro"
+            r#"{ "title": "Totoro"
                , "source": "Totoro"
                , "karamakers": [ "Viieux", "Totoro" ]
                , "is_virtual": false
@@ -152,8 +210,7 @@ mod test {
     #[test]
     fn tagged_kara() {
         let Kara { tags, .. } = assert_ok!(serde_json::from_str::<Kara>(
-            r#"{ "id": 1
-               , "title": "Totoro"
+            r#"{ "title": "Totoro"
                , "source": "Totoro"
                , "karamakers": [ "Viieux", "Totoro" ]
                , "is_virtual": false
-- 
GitLab