fix: fix json serialization
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

this can be so much better. current implementation bad
This commit is contained in:
Lys 2023-11-28 04:59:44 +02:00
parent ea2f9d0f64
commit fe1279d2af
Signed by: lyssieth
GPG key ID: C9CF3D614FAA3940

View file

@ -1,5 +1,5 @@
use poem::{http::StatusCode, IntoResponse, Response}; use poem::{http::StatusCode, IntoResponse, Response};
use serde::Serialize; use serde::{Serialize, Serializer};
use crate::authentication::VersionTriple; use crate::authentication::VersionTriple;
@ -16,10 +16,108 @@ pub use types::music_folder::MusicFolder;
pub struct SubsonicResponse { pub struct SubsonicResponse {
pub status: ResponseStatus, pub status: ResponseStatus,
pub version: VersionTriple, pub version: VersionTriple,
#[serde(skip_serializing_if = "SubResponseType::is_empty")] #[serde(
skip_serializing_if = "SubResponseType::is_empty",
serialize_with = "serialize_without_root",
flatten
)]
pub value: Box<SubResponseType>, pub value: Box<SubResponseType>,
} }
fn serialize_without_root<S>(value: &SubResponseType, s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match value {
SubResponseType::MusicFolders { music_folders } => {
#[derive(Serialize)]
struct MF {
id: String,
name: String,
}
impl From<MusicFolder> for MF {
fn from(value: MusicFolder) -> Self {
Self {
id: value.id,
name: value.name,
}
}
}
#[derive(Serialize)]
struct MusicFolders {
#[serde(rename = "musicFolders")]
music_folders: Vec<MF>,
}
MusicFolders {
music_folders: music_folders.iter().map(|v| v.clone().into()).collect(),
}
.serialize(s)
}
SubResponseType::Error(error) => error.serialize(s),
SubResponseType::License { valid } => valid.serialize(s),
SubResponseType::AlbumList { albums } | SubResponseType::AlbumList2 { albums } => {
albums.serialize(s)
}
SubResponseType::Album { album, songs } => {
#[derive(Serialize)]
#[serde(rename = "album")]
struct AlbumWithSongs<'a> {
#[serde(flatten)]
album: &'a Album,
#[serde(rename = "song")]
songs: &'a Vec<Child>,
}
AlbumWithSongs { album, songs }.serialize(s)
}
SubResponseType::ScanStatus { scanning, count } => {
#[derive(Serialize)]
#[serde(rename = "scanStatus")]
struct ScanStatus {
#[serde(rename = "scanning")]
scanning: bool,
#[serde(rename = "count")]
count: u64,
}
ScanStatus {
scanning: *scanning,
count: *count,
}
.serialize(s)
}
SubResponseType::SearchResult3 {
artists,
albums,
songs,
} => {
#[derive(Serialize)]
#[serde(rename = "searchResult3")]
struct SearchResult3<'a> {
#[serde(rename = "artist")]
artists: &'a Vec<Artist>,
#[serde(rename = "album")]
albums: &'a Vec<Album>,
#[serde(rename = "song")]
songs: &'a Vec<Child>,
}
SearchResult3 {
artists,
albums,
songs,
}
.serialize(s)
}
SubResponseType::Artists { artists } => artists.serialize(s),
SubResponseType::Artist { artist } => artist.serialize(s),
SubResponseType::Empty => s.serialize_none(),
}
}
impl From<SubsonicResponse> for SubsonicResponseJson { impl From<SubsonicResponse> for SubsonicResponseJson {
fn from(value: SubsonicResponse) -> Self { fn from(value: SubsonicResponse) -> Self {
Self { Self {
@ -142,7 +240,6 @@ impl SubsonicResponse {
} }
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
#[serde(untagged)]
pub enum SubResponseType { pub enum SubResponseType {
#[serde(rename = "musicFolders")] #[serde(rename = "musicFolders")]
MusicFolders { MusicFolders {