use serde::{Deserialize, Serialize}; use crate::domain::author; use crate::domain::book::Book; #[derive(Debug, Serialize, Deserialize)] #[serde(rename = "feed")] pub struct BooksFeed { #[serde(rename = "@xmlns", default = "default_atom_ns")] pub xmlns: String, #[serde(rename = "@xmlns:dc", default = "default_dc_ns")] pub xmlns_dc: String, pub id: String, pub title: String, pub updated: String, #[serde(default)] pub author: Option, #[serde(default)] pub entry: Vec, #[serde(default)] pub link: Vec, } impl Default for BooksFeed { fn default() -> Self { BooksFeed { xmlns: default_atom_ns(), xmlns_dc: default_dc_ns(), id: Default::default(), title: Default::default(), updated: Default::default(), author: Default::default(), entry: Default::default(), link: Default::default(), } } } fn default_atom_ns() -> String { "http://www.w3.org/2005/Atom".to_string() } fn default_dc_ns() -> String { "http://purl.org/dc/terms/".to_string() } #[derive(Debug, Serialize, Deserialize)] pub struct Author { pub name: String, pub url: String } impl From for Author { fn from(value: author::Author) -> Self { Author { name: value.to_string(), url: value.id.to_string() } } } #[derive(Debug, Serialize, Deserialize)] pub struct Link { #[serde(rename = "rel", default)] pub rel: Option, #[serde(rename = "href")] pub href: String, #[serde(rename = "type", default)] pub media_type: Option, } #[derive(Debug, Serialize, Deserialize)] #[serde(rename = "entry")] pub struct Entry { pub title: String, pub id: String, pub updated: String, pub author: Vec, #[serde(rename = "dc:language", default)] pub language: Option, #[serde(rename = "dc:issued", default)] pub issued: Option, #[serde(default)] pub summary: Option, #[serde(default)] pub link: Vec, // acquisition, cover, etc. } impl From<&Book> for Entry { fn from(book: &Book) -> Self { Entry{ title: book.title.clone(), id: book.id.to_string().clone(), updated: book.updated.to_rfc3339(), author: book.author.clone().into_iter().map(|a| a.into()).collect(), language: (!book.language.is_empty()).then(|| book.language.clone()), issued: (!book.published_at.is_empty()).then(|| book.published_at.clone()), summary: (!book.description.is_empty()).then(|| book.description.clone()), link: vec![], } } }