config-file-0.2.3/.cargo_vcs_info.json0000644000000001360000000000100132200ustar { "git": { "sha1": "7179e26d4a9d619c7572976e215354ab6dca13f1" }, "path_in_vcs": "" }config-file-0.2.3/.github/FUNDING.yml000064400000000000000000000000200072674642500152050ustar 00000000000000github: Keruspe config-file-0.2.3/.github/workflows/build-and-test.yaml000064400000000000000000000020250072674642500211340ustar 00000000000000name: Build and test on: push: branches: - main pull_request: jobs: build_and_test: runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macos-latest] rust: [nightly, beta, stable, 1.56.0] steps: - uses: actions/checkout@v2 - name: Install latest ${{ matrix.rust }} uses: actions-rs/toolchain@v1 with: toolchain: ${{ matrix.rust }} profile: minimal override: true - name: Run cargo check uses: actions-rs/cargo@v1 with: command: check args: --all --bins --examples --tests --all-features - name: Run cargo check (without dev-dependencies to catch missing feature flags) if: startsWith(matrix.rust, 'nightly') uses: actions-rs/cargo@v1 with: command: check args: -Z features=dev_dep - name: Run cargo test uses: actions-rs/cargo@v1 with: command: test config-file-0.2.3/.github/workflows/lint.yaml000064400000000000000000000014000072674642500172620ustar 00000000000000name: Lint on: push: branches: - main pull_request: jobs: clippy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: toolchain: stable profile: minimal components: clippy - uses: actions-rs/clippy-check@v1 with: token: ${{ secrets.GITHUB_TOKEN }} args: --all-features -- -W clippy::all rustfmt: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: toolchain: stable profile: minimal components: rustfmt - uses: actions-rs/cargo@v1 with: command: fmt args: --all -- --check config-file-0.2.3/.github/workflows/security.yaml000064400000000000000000000004220072674642500201660ustar 00000000000000name: Security audit on: push: branches: - main pull_request: jobs: security_audit: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions-rs/audit-check@v1 with: token: ${{ secrets.GITHUB_TOKEN }} config-file-0.2.3/.gitignore000064400000000000000000000000230072674642500140230ustar 00000000000000/target Cargo.lock config-file-0.2.3/Cargo.toml0000644000000026550000000000100112260ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2021" rust-version = "1.56.0" name = "config-file" version = "0.2.3" authors = ["Marc-Antoine Perennou "] description = "Read and parse configuration file automatically" documentation = "https://docs.rs/config-file" keywords = [ "config", "configuration", ] categories = ["config"] license = "BSD-2-Clause" repository = "https://github.com/Keruspe/config-file" resolver = "2" [lib] name = "config_file" [dependencies.serde] version = "^1.0" [dependencies.serde-xml-rs] version = "^0.5" optional = true [dependencies.serde_json] version = "^1.0" optional = true [dependencies.serde_yaml] version = "^0.8" optional = true [dependencies.thiserror] version = "^1.0" [dependencies.toml-crate] version = "^0.5" optional = true package = "toml" [dev-dependencies.serde] version = "^1.0" features = ["derive"] [features] default = ["toml"] json = ["serde_json"] toml = ["toml-crate"] xml = ["serde-xml-rs"] yaml = ["serde_yaml"] config-file-0.2.3/Cargo.toml.orig000064400000000000000000000017030072674642500147300ustar 00000000000000[package] name = "config-file" version = "0.2.3" # remember to update html_root_url authors = ["Marc-Antoine Perennou "] edition = "2021" description = "Read and parse configuration file automatically" repository = "https://github.com/Keruspe/config-file" documentation = "https://docs.rs/config-file" keywords = ["config", "configuration"] categories = ["config"] license = "BSD-2-Clause" rust-version = "1.56.0" [lib] name = "config_file" [features] default = ["toml"] json = ["serde_json"] toml = ["toml-crate"] xml = ["serde-xml-rs"] yaml = ["serde_yaml"] [dependencies] serde = "^1.0" thiserror = "^1.0" [dependencies.serde_json] version = "^1.0" optional = true [dependencies.serde-xml-rs] version = "^0.5" optional = true [dependencies.serde_yaml] version = "^0.8" optional = true [dependencies.toml-crate] package = "toml" version = "^0.5" optional = true [dev-dependencies.serde] version = "^1.0" features = ["derive"] config-file-0.2.3/README.md000064400000000000000000000012240072674642500133160ustar 00000000000000# config-file [![API Docs](https://docs.rs/config-file/badge.svg)](https://docs.rs/config-file) [![Downloads](https://img.shields.io/crates/d/config-file.svg)](https://crates.io/crates/config-file) ## Read and parse configuration file automatically config-file reads your configuration files and parse them automatically using their extension. ## Features - toml is enabled by default - json is optional - xml is optional - yaml is optional ## Examples ```rust use config_file::FromConfigFile; use serde::Deserialize; #[derive(Deserialize)] struct Config { host: String, } let config = Config::from_config_file("/etc/myconfig.toml").unwrap(); ``` config-file-0.2.3/src/lib.rs000064400000000000000000000126620072674642500137520ustar 00000000000000#![deny(missing_docs)] #![warn(rust_2018_idioms)] #![doc(html_root_url = "https://docs.rs/config-file/0.2.3/")] //! # Read and parse configuration file automatically //! //! config-file reads your configuration files and parse them automatically using their extension. //! //! # Features //! //! - toml is enabled by default //! - json is optional //! - xml is optional //! - yaml is optional //! //! # Examples //! //! ```rust,no_run //! use config_file::FromConfigFile; //! use serde::Deserialize; //! //! #[derive(Deserialize)] //! struct Config { //! host: String, //! } //! //! let config = Config::from_config_file("/etc/myconfig.toml").unwrap(); //! ``` use serde::de::DeserializeOwned; use std::{ffi::OsStr, fs::File, path::Path}; use thiserror::Error; #[cfg(feature = "toml")] use toml_crate as toml; /// Trait for loading a struct from a configuration file. /// This trait is automatically implemented when serde::Deserialize is. pub trait FromConfigFile { /// Load ourselves from the configuration file located at @path fn from_config_file>(path: P) -> Result where Self: Sized; } impl FromConfigFile for C { fn from_config_file>(path: P) -> Result where Self: Sized, { let path = path.as_ref(); let extension = path .extension() .and_then(OsStr::to_str) .map(|extension| extension.to_lowercase()); match extension.as_deref() { #[cfg(feature = "json")] Some("json") => { serde_json::from_reader(open_file(path)?).map_err(ConfigFileError::Json) } #[cfg(feature = "toml")] Some("toml") => toml::from_str( std::fs::read_to_string(path) .map_err(ConfigFileError::FileAccess)? .as_str(), ) .map_err(ConfigFileError::Toml), #[cfg(feature = "xml")] Some("xml") => { serde_xml_rs::from_reader(open_file(path)?).map_err(ConfigFileError::Xml) } #[cfg(feature = "yaml")] Some("yaml") | Some("yml") => { serde_yaml::from_reader(open_file(path)?).map_err(ConfigFileError::Yaml) } _ => Err(ConfigFileError::UnsupportedFormat), } } } #[allow(unused)] fn open_file(path: &Path) -> Result { File::open(path).map_err(ConfigFileError::FileAccess) } /// This type represents all possible errors that can occur when loading data from a configuration file. #[derive(Error, Debug)] pub enum ConfigFileError { #[error("couldn't read config file")] /// There was an error while reading the configuration file FileAccess(#[from] std::io::Error), #[cfg(feature = "json")] #[error("couldn't parse JSON file")] /// There was an error while parsing the JSON data Json(#[from] serde_json::Error), #[cfg(feature = "toml")] #[error("couldn't parse TOML file")] /// There was an error while parsing the TOML data Toml(#[from] toml::de::Error), #[cfg(feature = "xml")] #[error("couldn't parse XML file")] /// There was an error while parsing the XML data Xml(#[from] serde_xml_rs::Error), #[cfg(feature = "yaml")] #[error("couldn't parse YAML file")] /// There was an error while parsing the YAML data Yaml(#[from] serde_yaml::Error), #[error("don't know how to parse file")] /// We don't know how to parse this format according to the file extension UnsupportedFormat, } #[cfg(test)] mod test { use super::*; use serde::Deserialize; #[derive(Debug, Deserialize, PartialEq)] struct TestConfig { host: String, port: u64, tags: Vec, inner: TestConfigInner, } #[derive(Debug, Deserialize, PartialEq)] struct TestConfigInner { answer: u8, } impl TestConfig { #[allow(unused)] fn example() -> Self { Self { host: "example.com".to_string(), port: 443, tags: vec!["example".to_string(), "test".to_string()], inner: TestConfigInner { answer: 42 }, } } } #[test] fn test_unknown() { let config = TestConfig::from_config_file("/tmp/foobar"); assert!(matches!(config, Err(ConfigFileError::UnsupportedFormat))); } #[test] #[cfg(feature = "toml")] fn test_file_not_found() { let config = TestConfig::from_config_file("/tmp/foobar.toml"); assert!(matches!(config, Err(ConfigFileError::FileAccess(_)))); } #[test] #[cfg(feature = "json")] fn test_json() { let config = TestConfig::from_config_file("testdata/config.json"); assert_eq!(config.unwrap(), TestConfig::example()); } #[test] #[cfg(feature = "toml")] fn test_toml() { let config = TestConfig::from_config_file("testdata/config.toml"); assert_eq!(config.unwrap(), TestConfig::example()); } #[test] #[cfg(feature = "xml")] fn test_xml() { let config = TestConfig::from_config_file("testdata/config.xml"); assert_eq!(config.unwrap(), TestConfig::example()); } #[test] #[cfg(feature = "yaml")] fn test_yaml() { let config = TestConfig::from_config_file("testdata/config.yml"); assert_eq!(config.unwrap(), TestConfig::example()); } } config-file-0.2.3/testdata/config.json000064400000000000000000000001730072674642500160120ustar 00000000000000{ "host": "example.com", "port": 443, "tags": ["example", "test"], "inner": { "answer": 42 } } config-file-0.2.3/testdata/config.toml000064400000000000000000000001170072674642500160120ustar 00000000000000host = "example.com" port = 443 tags = ["example", "test"] [inner] answer = 42 config-file-0.2.3/testdata/config.xml000064400000000000000000000002610072674642500156370ustar 00000000000000 example.com 443 example test 42 config-file-0.2.3/testdata/config.yml000064400000000000000000000001140072674642500156350ustar 00000000000000host: "example.com" port: 443 tags: ["example", "test"] inner: answer: 42