Crate cfgfifo

source ·
Expand description

cfgfifo is a Rust library for serializing & deserializing various common configuration file formats (JSON, JSON5, RON, TOML, and YAML), including autodetecting the format of a file based on its file extension. It’s good for application authors who want to support multiple configuration file formats but don’t want to write out a bunch of boilerplate. cfgfifo has already written that boilerplate for you, so let it (de)serialize your files!

Overview

  • Call load() on a file path to deserialize its contents as a serde::de::DeserializeOwned type. The file’s format will be determined based on its file extension.

  • Call dump() on a file path to serialize a serde::Serialize value to it. The file’s format will be determined based on its file extension.

  • For finer control over how file formats are identified, configure a Cfgfifo struct and use its load() and dump() methods.

  • For per-format operations, including (de)serializing to & from strings, readers, and writers, use the Format enum.

Features

Support for each configuration file format is controlled by a Cargo feature; the features for all formats are enabled by default. These features are:

  • json — Support for JSON via the serde_json crate
  • json5 — Support for JSON5 via the json5 crate
  • ron — Support for RON via the ron crate
  • toml — Support for TOML via the toml crate
  • yaml — Support for YAML via the serde_yaml crate

Format Limitations

If you wish to (de)serialize a type in multiple formats using this crate, you must first ensure that all of the formats you’re using support the type and its (de)serialization options, as not all formats are equal in this regard.

The following format-specific limitations are currently known:

  • RON has limited support for internally tagged enums with fields, untagged enums with fields, and the serde(flatten) attribute.

  • TOML does not support the unit tuple (), unit (fieldless) structs, maps with non-string keys, or top-level types that do not serialize to tables.

  • YAML does not support bytes or nested enums (e.g., Enum::Variant(AnotherEnum), where AnotherEnum is “fat”).

Example

use serde::Deserialize;

#[derive(Clone, Debug, Deserialize, Eq, PartialEq)]
struct AppConfig {
    #[serde(default)]
    enable_foo: bool,
    #[serde(default)]
    bar_type: BarType,
    #[serde(default)]
    flavor: Option<String>,
}

#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq)]
enum BarType {
    #[default]
    Open,
    Closed,
    Clopen,
}

fn main() -> anyhow::Result<()> {
    let Some(cfgpath) = std::env::args().nth(1) else {
        anyhow::bail!("No configuration file specified");
    };
    // cfgfifo identifies the format used by the file `cfgpath` based on its
    // file extension and deserializes it appropriately:
    let cfg: AppConfig = cfgfifo::load(cfgpath)?;
    println!("You specified the following configuration:");
    println!("{cfg:#?}");
    Ok(())
}

Structs

  • A configurable loader & dumper of serialized data in files.
  • An iterator over the variants of Format

Enums

Functions

  • Serialize a value to the given file, with the format automatically determined based on the file’s extension.
  • Deserialize the contents of the given file, with the format automatically determined based on the file’s extension.