From 9a8f2198f13bb36a9b8d41a66f495744051ccd9c Mon Sep 17 00:00:00 2001 From: Neshura Date: Wed, 1 Nov 2023 20:21:59 +0100 Subject: [PATCH] Primitive Backend Communication --- src-tauri/Cargo.lock | 44 +++++++- src-tauri/Cargo.toml | 10 +- src-tauri/src/main.rs | 12 ++- src-tauri/src/metadata/mod.rs | 198 ++++++++++++++++++++++++++++++++++ src-tauri/tauri.conf.json | 2 +- src/lib/MetadataInput.svelte | 67 +++++++++--- src/lib/metadata.ts | 58 ++++++++++ 7 files changed, 373 insertions(+), 18 deletions(-) create mode 100644 src-tauri/src/metadata/mod.rs create mode 100644 src/lib/metadata.ts diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 98caad3..ff33e0b 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -347,10 +347,14 @@ dependencies = [ [[package]] name = "comicinfo-editor-v2" -version = "0.0.0" +version = "0.1.0" dependencies = [ + "quick-xml", "serde", + "serde-xml-rs", "serde_json", + "strum", + "strum_macros", "tauri", "tauri-build", ] @@ -1996,6 +2000,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81b9228215d82c7b61490fec1de287136b5de6f5700f6e58ea9ad61a7964ca51" dependencies = [ "memchr", + "serde", ] [[package]] @@ -2272,6 +2277,18 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-xml-rs" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb3aa78ecda1ebc9ec9847d5d3aba7d618823446a049ba2491940506da6e2782" +dependencies = [ + "log", + "serde", + "thiserror", + "xml-rs", +] + [[package]] name = "serde_derive" version = "1.0.188" @@ -2497,6 +2514,25 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" + +[[package]] +name = "strum_macros" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.38", +] + [[package]] name = "syn" version = "1.0.109" @@ -3651,3 +3687,9 @@ checksum = "f4686009f71ff3e5c4dbcf1a282d0a44db3f021ba69350cd42086b3e5f1c6985" dependencies = [ "libc", ] + +[[package]] +name = "xml-rs" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index ebec1a2..584ec19 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "comicinfo-editor-v2" -version = "0.0.0" -description = "A Tauri App" -authors = ["you"] +version = "0.1.0" +description = "App for creating Comicinfo.xml files" +authors = ["Neshura"] license = "" repository = "" edition = "2021" @@ -14,8 +14,12 @@ tauri-build = { version = "1.4", features = [] } [dependencies] tauri = { version = "1.4", features = ["shell-open"] } +quick-xml = { version = "0.29.0", features = ["serde", "serialize"] } serde = { version = "1.0", features = ["derive"] } +serde-xml-rs = "0.6.0" serde_json = "1.0" +strum = "0.25.0" +strum_macros = "0.25.0" [features] # this feature is used for production builds or when `devPath` points to the filesystem diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 523550d..8ce01a4 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -1,6 +1,11 @@ // Prevents additional console window on Windows in release, DO NOT REMOVE!! #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] +use serde::{Deserialize, Serialize}; + +use crate::metadata::{*}; +mod metadata; + // Learn more about Tauri commands at https://tauri.app/v1/guides/features/command #[tauri::command] fn greet(name: &str) -> String { @@ -9,7 +14,12 @@ fn greet(name: &str) -> String { fn main() { tauri::Builder::default() - .invoke_handler(tauri::generate_handler![greet]) + .invoke_handler(tauri::generate_handler![greet, test]) .run(tauri::generate_context!()) .expect("error while running tauri application"); } + +#[tauri::command] +fn test(message: metadata::Metadata) -> String { + format!("Series: '{}' | Title: '{}'", message.series_title, message.title) +} diff --git a/src-tauri/src/metadata/mod.rs b/src-tauri/src/metadata/mod.rs new file mode 100644 index 0000000..094cd04 --- /dev/null +++ b/src-tauri/src/metadata/mod.rs @@ -0,0 +1,198 @@ +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: Option, + + pub(crate) year: i16, + pub(crate) month: i8, + pub(crate) day: i8, + + pub(crate) writer: Option, + pub(crate) translator: Option, + pub(crate) letterer: Option, + pub(crate) editor: Option, + + pub(crate) publisher: Option, + + pub(crate) genre: String, + + pub(crate) tags: Vec, + + pub(crate) page_count: u16, + + pub(crate) language: String, + + pub(crate) characters: Vec, + + 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: None, + year: -1, + month: -1, + day: -1, + writer: None, + letterer: None, + editor: None, + translator: None, + publisher: None, + genre: "".into(), + tags: vec![], + page_count: 0, + language: "en".into(), + characters: vec![], + age_rating: "Unknown".into() + } + } +} + +impl Serialize for Metadata { + fn serialize(&self, serializer: S) -> Result 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("Title", &self.title)?; + out_state.serialize_field("Series", &self.series_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.is_some() { + out_state.serialize_field("Summary", &self.summary)?; + } + + out_state.serialize_field("Year", &self.year)?; + out_state.serialize_field("Month", &self.month)?; + out_state.serialize_field("Day", &self.day)?; + + if self.writer.is_some() { + out_state.serialize_field("Writer", &self.writer)?; + } + + if self.letterer.is_some() { + out_state.serialize_field("Letterer", &self.letterer)?; + } + + if self.editor.is_some() { + out_state.serialize_field("Editor", &self.editor)?; + } + + if self.translator.is_some() { + out_state.serialize_field("Translator", &self.translator)?; + } + + if self.publisher.is_some() { + 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(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 +}*/ \ No newline at end of file diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index e32feae..686dc01 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -8,7 +8,7 @@ }, "package": { "productName": "comicinfo-editor-v2", - "version": "0.0.0" + "version": "0.1.0" }, "tauri": { "allowlist": { diff --git a/src/lib/MetadataInput.svelte b/src/lib/MetadataInput.svelte index 466598c..b102090 100644 --- a/src/lib/MetadataInput.svelte +++ b/src/lib/MetadataInput.svelte @@ -1,10 +1,12 @@ -
+

Metadata

@@ -78,15 +120,15 @@
+ +
+

- -
-
@@ -97,17 +139,18 @@ {/each}
- + - +
- +
-
+

{returnMessage}

+