Skip to main content

confex_core/
format.rs

1use std::path::Path;
2
3use crate::{error::SourceError, value::ConfigValue};
4
5/// Pluggable serialization format for config files.
6pub trait Format {
7    fn name(&self) -> &'static str;
8
9    /// Parse raw bytes from `path` into a `ConfigValue` tree.
10    ///
11    /// # Errors
12    /// Returns [`SourceError::Parse`] if the bytes are not valid for this format.
13    fn parse(&self, path: &Path, bytes: &[u8]) -> Result<ConfigValue, SourceError>;
14
15    /// Serialize a `ConfigValue` tree to bytes.
16    ///
17    /// # Errors
18    /// Returns [`SourceError::Serialize`] if the value cannot be expressed in this format.
19    fn serialize(&self, value: &ConfigValue) -> Result<Vec<u8>, SourceError>;
20}
21
22/// TOML format. Requires the `toml` feature.
23#[cfg(feature = "toml")]
24pub struct TomlFormat;
25
26#[cfg(feature = "toml")]
27impl Format for TomlFormat {
28    fn name(&self) -> &'static str {
29        "toml"
30    }
31
32    fn parse(&self, path: &Path, bytes: &[u8]) -> Result<ConfigValue, SourceError> {
33        let s = std::str::from_utf8(bytes).map_err(|e| SourceError::Parse {
34            path: path.to_owned(),
35            message: e.to_string(),
36        })?;
37        let toml_val: toml::Value = toml::from_str(s).map_err(|e| SourceError::Parse {
38            path: path.to_owned(),
39            message: e.to_string(),
40        })?;
41        Ok(toml_val.into())
42    }
43
44    fn serialize(&self, value: &ConfigValue) -> Result<Vec<u8>, SourceError> {
45        let toml_val: toml::Value = value.clone().into();
46        toml::to_string(&toml_val)
47            .map(String::into_bytes)
48            .map_err(|e| SourceError::Serialize(e.to_string()))
49    }
50}