206 lines
No EOL
5.7 KiB
Rust
206 lines
No EOL
5.7 KiB
Rust
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
|
|
}*/ |