2023-11-01 20:21:59 +01:00
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 ,
2023-11-01 21:55:08 +01:00
pub ( crate ) summary : String ,
2023-11-01 20:21:59 +01:00
2023-11-01 21:55:08 +01:00
pub ( crate ) release_date : ReleaseDate ,
2023-11-01 20:21:59 +01:00
2023-11-01 21:55:08 +01:00
pub ( crate ) writer : String ,
pub ( crate ) translator : String ,
pub ( crate ) letterer : String ,
pub ( crate ) editor : String ,
2023-11-01 20:21:59 +01:00
2023-11-01 21:55:08 +01:00
pub ( crate ) publisher : String ,
2023-11-01 20:21:59 +01:00
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 ,
2023-11-01 21:55:08 +01:00
summary : " " . into ( ) ,
release_date : ReleaseDate {
year : - 1 ,
month : - 1 ,
day : - 1 ,
} ,
writer : " " . into ( ) ,
letterer : " " . into ( ) ,
editor : " " . into ( ) ,
translator : " " . into ( ) ,
publisher : " " . into ( ) ,
2023-11-01 20:21:59 +01:00
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 ) ? ;
2023-11-01 21:55:08 +01:00
out_state . serialize_field ( " Title " , & self . title ) ? ;
2023-11-01 20:21:59 +01:00
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 ) ? ;
2023-11-01 21:55:08 +01:00
if self . summary ! = " " {
2023-11-01 20:21:59 +01:00
out_state . serialize_field ( " Summary " , & self . summary ) ? ;
}
2023-11-01 21:55:08 +01:00
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 ) ? ;
2023-11-01 20:21:59 +01:00
2023-11-01 21:55:08 +01:00
if self . writer ! = " " {
2023-11-01 20:21:59 +01:00
out_state . serialize_field ( " Writer " , & self . writer ) ? ;
}
2023-11-01 21:55:08 +01:00
if self . letterer ! = " " {
2023-11-01 20:21:59 +01:00
out_state . serialize_field ( " Letterer " , & self . letterer ) ? ;
}
2023-11-01 21:55:08 +01:00
if self . editor ! = " " {
2023-11-01 20:21:59 +01:00
out_state . serialize_field ( " Editor " , & self . editor ) ? ;
}
2023-11-01 21:55:08 +01:00
if self . translator ! = " " {
2023-11-01 20:21:59 +01:00
out_state . serialize_field ( " Translator " , & self . translator ) ? ;
}
2023-11-01 21:55:08 +01:00
if self . publisher ! = " " {
2023-11-01 20:21:59 +01:00
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 ( ) ;
}
}
2023-11-01 21:55:08 +01:00
#[ derive(Debug, Deserialize, PartialEq, Clone) ]
pub ( crate ) struct ReleaseDate {
year : i16 ,
month : i8 ,
day : i8
}
2023-11-01 20:21:59 +01:00
/* #[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
} * /