Crate comicinfo

Crate comicinfo 

Source
Expand description

This crate provides bindings to interact with ComicInfo.xml files.

It is intended to be used in other crates, and aimed at developers.

§What is ComicInfo.xml?

ComicInfo.xml is an XML-based metadata format commonly used in digital comic book files (CBZ/CBR). It originates from the ComicRack application, but it had no spec or schema. The folks over at the Anansi project have “reverse-engineered” (they probably looked at a bunch of XML files) the format and created a schema for it.

Due to the “reverse engineering”, the format at times has a questionable specification. Nevertheless, this crate provides bindings for all known versions of the schema.

For more details, see anansi’s introduction. The linked site also hosts the schema’s.

§MSRV

This crate will always support the latest stable toolchain installed through rustup.

It was initially developed on rustc 1.91.1, but should probably work on earlier versions too.

§Features

  • Support for multiple versions of the ComicInfo.xml schema
  • Serialization and deserialization of ComicInfo.xml files using serde where possible, and custom implementations where necessary.
  • Builder-style setters for all fields, and helper methods for set-like fields (e.g. writers, genres, etc).
  • Fully documented, and fully tested.

§Usage

Add this crate as a dependency in your Cargo.toml (run cargo add comicinfo for latest version):

[dependencies]
comic_info_xml = "0.x.x"  # Replace with the latest version

§Example: read from string

We implement FromStr for all ComicInfo structs, so you can easily parse from a string.

use comicinfo::ComicInfo; // or use comic_info_xml::vX_X::ComicInfo; for explicit version
use std::str::FromStr;    // for from_str

// or from a file: let source = std::fs::read_to_string("path/to/ComicInfo.xml")?;
let source = r#"<ComicInfo><Title>Example Comic</Title><Volume>1</Volume></ComicInfo>"#;
let ci = ComicInfo::from_str(&source)?;
assert_eq!(ci.title(), Some("Example Comic".to_string()) );
assert_eq!(ci.volume(), Some(1) );

§Example: initialize a new ComicInfo object

Initialization is done using builder-style setters and helper methods. You can’t create a ComicInfo object with fields set directly, as all fields are private (for good reason).

use comicinfo::ComicInfo; // or use comic_info_xml::vX_X::ComicInfo; for explicit version   
use std::str::FromStr;    // for from_str

let mut ci = ComicInfo::new();      // Must be mutable, otherwise we can't set fields
ci.set_title(Some("Example Comic")) // The pattern is to chain setter calls for initialization
  .set_volume(Some(1))              // Basic fields expect Option<T> values
  .add_writer("Jane Doe")           // Set-like fields have helpers to add entries
  .add_writer("John Smith")         // These helpers can be chained too
  .add_many_genres(vec!["Action".to_string(), "Adventure".to_string()]);  // Or add many at once

§Example: writing to string

We implement Display for all ComicInfo structs, so you can write it to string using to_string().

use comicinfo::ComicInfo; // or use comic_info_xml::vX_X::ComicInfo; for explicit version   

let ci = ComicInfo::new();       // Assume you have a populated ComicInfo object
let xml_string = ci.to_string(); // Uses Display implementation
println!("{}", xml_string);      // or write to file, ...

Re-exports§

pub use v2_1::ComicInfo;

Modules§

v1_0
v2_0
v2_1