plugx_config/parser/
mod.rs

1//! Configuration parser trait and implementations.
2
3use plugx_input::Input;
4use std::fmt::{Debug, Display};
5use thiserror::Error;
6
7#[cfg(feature = "env")]
8pub mod env;
9#[cfg(feature = "json")]
10pub mod json;
11#[cfg(feature = "toml")]
12pub mod toml;
13#[cfg(feature = "yaml")]
14pub mod yaml;
15
16pub mod closure;
17
18/// Parser error type.
19#[derive(Debug, Error)]
20pub enum Error {
21    /// Could not parse contents.
22    #[error("{parser} with supported formats {supported_format_list:?} could not parse `{data}`")]
23    Parse {
24        data: String,
25        parser: String,
26        supported_format_list: Vec<String>,
27        source: anyhow::Error,
28    },
29    /// Could not find parser or guess format to choose correct parser.
30    #[error("Could not found parser to parse format `{format}`")]
31    ParserNotFound { format: String },
32}
33
34/// A trait to parse configuration contents.
35pub trait Parser: Send + Sync + Debug + Display {
36    /// Supported format list (e.g. "yml")
37    fn supported_format_list(&self) -> Vec<String>;
38
39    /// Parses a byte slice to [Input].
40    fn try_parse(&self, bytes: &[u8]) -> anyhow::Result<Input>;
41
42    /// Checks if provided byte slice is ok for future parsing. (e.g. is it YAML at all or not)
43    fn is_format_supported(&self, bytes: &[u8]) -> Option<bool>;
44
45    fn parse(&self, bytes: &[u8]) -> Result<Input, Error> {
46        self.try_parse(bytes).map_err(|source| Error::Parse {
47            data: String::from_utf8_lossy(bytes).to_string(),
48            parser: format!("{self}"),
49            supported_format_list: self.supported_format_list(),
50            source,
51        })
52    }
53}