little-hesinde/rusty-library/src/opds/entry.rs

106 lines
3.0 KiB
Rust
Raw Normal View History

2024-05-08 16:11:39 +00:00
use serde::Serialize;
use time::OffsetDateTime;
2024-05-09 09:18:47 +00:00
use crate::data::book::Book;
use super::{
author::Author, content::Content, link::Link, media_type::MediaType, relation::Relation,
};
2024-05-08 16:11:39 +00:00
#[derive(Debug, Serialize)]
#[serde(rename = "entry")]
pub struct Entry {
pub title: String,
pub id: String,
#[serde(with = "time::serde::rfc3339")]
pub updated: OffsetDateTime,
pub content: Content,
2024-05-09 09:18:47 +00:00
pub author: Option<Author>,
2024-05-08 16:11:39 +00:00
#[serde(rename = "link")]
pub links: Vec<Link>,
}
2024-05-09 09:18:47 +00:00
impl From<Book> for Entry {
fn from(value: Book) -> Self {
let author = Author {
name: value.clone().author.name,
uri: format!("/opds/authors/{}", value.author.id),
email: None,
};
let mut links = vec![Link {
href: format!("/cover/{}", value.id),
media_type: MediaType::Jpeg,
rel: Relation::Image,
title: None,
count: None,
}];
let mut format_links: Vec<Link> = value
.formats
.iter()
.map(|(key, val)| Link::from((&value, (key, val.as_str()))))
.collect();
links.append(&mut format_links);
Self {
title: value.title.clone(),
id: format!("urn:uuid:{}", value.uuid),
updated: value.last_modified,
content: Content {
media_type: MediaType::Html,
content: value.description.clone().unwrap_or("".to_string()),
},
author: Some(author),
links,
}
}
}
2024-05-08 16:11:39 +00:00
#[cfg(test)]
mod tests {
use quick_xml::se::to_string;
use time::macros::datetime;
use crate::opds::{content::Content, media_type::MediaType, relation::Relation};
use super::*;
fn init() -> Entry {
Entry {
title: "Authors".to_string(),
id: "rust:authors".to_string(),
updated: datetime!(2024-05-06 19:14:54 UTC),
content: Content {
media_type: MediaType::Text,
content: "All authors".to_string(),
},
2024-05-09 09:18:47 +00:00
author: None,
2024-05-08 16:11:39 +00:00
links: vec![
Link {
href: "/opds".to_string(),
media_type: MediaType::Text,
rel: Relation::Start,
title: None,
count: None,
},
Link {
href: "/opds".to_string(),
media_type: MediaType::Text,
rel: Relation::Start,
title: None,
count: None,
},
],
}
}
#[test]
fn serialize() {
let entry = init();
let xml = to_string(&entry).unwrap();
assert_eq!(
xml,
r#"<entry><title>Authors</title><id>rust:authors</id><updated>2024-05-06T19:14:54Z</updated><content type="text">All authors</content><link href="/opds" type="text" rel="start"/><link href="/opds" type="text" rel="start"/></entry>"#
);
}
}