use std::{fs::File, io::{Write, Cursor}}; use quick_xml::{se::Serializer, events::BytesStart}; use serde::{Serialize, Deserialize}; use serde::ser::{SerializeSeq, SerializeStruct}; use serde_xml_rs::{to_string, to_writer}; #[derive(Debug, Deserialize, PartialEq, Clone)] pub(crate) struct Metadata { pub(crate) title: String, pub(crate) series_title: String, pub(crate) chapter_number: u16, pub(crate) total_chapter_count: i16, pub(crate) volume_number: i16, pub(crate) summary: String, pub(crate) release_date: ReleaseDate, pub(crate) writer: String, pub(crate) translator: String, pub(crate) letterer: String, pub(crate) editor: String, pub(crate) publisher: String, pub(crate) genre: String, pub(crate) tags: Vec<String>, pub(crate) page_count: u16, pub(crate) language: String, pub(crate) characters: Vec<String>, pub(crate) age_rating: String } impl Default for Metadata { fn default() -> Self { Self { title: "".into(), series_title: "".into(), chapter_number: 0, total_chapter_count: -1, volume_number: 1, summary: "".into(), release_date: ReleaseDate { year: -1, month: -1, day: -1, }, writer: "".into(), letterer: "".into(), editor: "".into(), translator: "".into(), publisher: "".into(), genre: "".into(), tags: vec![], page_count: 0, language: "en".into(), characters: vec![], age_rating: "Unknown".into() } } } impl Serialize for Metadata { fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer { let mut out_state = serializer.serialize_struct("Metadata", 22)?; out_state.serialize_field("@xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")?; out_state.serialize_field("@xsi:noNamespaceSchemaLocation", "ComicInfo.xsd")?; out_state.serialize_field("Series", &self.series_title)?; out_state.serialize_field("Title", &self.title)?; out_state.serialize_field("Number", &self.chapter_number)?; out_state.serialize_field("Count", &self.total_chapter_count)?; out_state.serialize_field("Volume", &self.volume_number)?; if self.summary != "" { out_state.serialize_field("Summary", &self.summary)?; } out_state.serialize_field("Year", &self.release_date.year)?; out_state.serialize_field("Month", &self.release_date.month)?; out_state.serialize_field("Day", &self.release_date.day)?; if self.writer != "" { out_state.serialize_field("Writer", &self.writer)?; } if self.letterer != "" { out_state.serialize_field("Letterer", &self.letterer)?; } if self.editor != "" { out_state.serialize_field("Editor", &self.editor)?; } if self.translator != "" { out_state.serialize_field("Translator", &self.translator)?; } if self.publisher != "" { out_state.serialize_field("Publisher", &self.publisher)?; } out_state.serialize_field("Genre", &self.genre)?; if self.tags.len() != 0 { out_state.serialize_field("Tags", &self.tags.join(", "))?; } out_state.serialize_field("PageCount", &self.page_count)?; out_state.serialize_field("LanguageISO", &self.language)?; if self.characters.len() != 0 { out_state.serialize_field("Characters", &self.characters.join(", "))?; } out_state.serialize_field("AgeRating", &self.age_rating)?; out_state.end() } } impl Metadata { pub(crate) fn save_to_xml(&self, path: &str) { let mut file = File::create(path).unwrap(); let mut buffer = String::new(); let root = "ComicInfo"; let mut ser = Serializer::with_root(&mut buffer, Some(root)).unwrap(); ser.indent(' ', 4); self.serialize(ser).unwrap(); file.write(buffer.as_bytes()).unwrap(); } } #[derive(Debug, Deserialize, PartialEq, Clone)] pub(crate) struct ReleaseDate { year: i16, month: i8, day: i8 } /*#[derive(strum_macros::Display, Debug, PartialEq, strum_macros::EnumIter, Serialize, Deserialize, Clone)] #[serde(tag = "AgeRating")] pub(crate) enum AgeRating { #[strum(serialize="Unknown")] Unknown, #[strum(serialize="Adults Only 18+")] #[serde(rename="Adults Only 18+")] AdultsOnly, #[strum(serialize="Early Childhood")] #[serde(rename="Early Childhood")] EarlyChildhood, #[strum(serialize="Everyone")] Everyone, #[strum(serialize="Everyone 10+")] #[serde(rename="Everyone 10+")] Everyone10, #[strum(serialize="G")] G, #[strum(serialize="Kids to Adults")] #[serde(rename="Kids to Adults")] KidsAdults, #[strum(serialize="M")] M, #[strum(serialize="MA15+")] #[serde(rename="MA15+")] MA15, #[strum(serialize="Mature 17+")] #[serde(rename="Mature 17+")] Mature, #[strum(serialize="PG")] PG, #[strum(serialize="R18+")] #[serde(rename="R18+")] R18, #[strum(serialize="Rating Pending")] #[serde(rename="Rating Pending")] RatingPending, #[strum(serialize="Teen")] Teen, #[strum(serialize="X18+")] #[serde(rename="X18+")] X18 } #[derive(strum_macros::Display, Debug, PartialEq, strum_macros::EnumIter, Serialize, Deserialize, Clone)] #[serde(tag = "LanguageISO")] pub(crate) enum LanguageISO { #[strum(serialize="en")] #[serde(rename="en")] EN, #[strum(serialize="jp")] #[serde(rename="jp")] JP }*/