use cirious_codex_result::{codex_ok, CodexError, Result};
use serde::de::DeserializeOwned;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ConfigFormat {
Ron,
Json,
#[cfg(feature = "toml")]
Toml,
#[cfg(feature = "yaml")]
Yaml,
}
impl ConfigFormat {
pub fn parse<T: DeserializeOwned>(&self, content: &str) -> Result<T> {
match self {
Self::Ron => match ron::from_str::<T>(content) {
Ok(v) => codex_ok!(v),
Err(e) => Err(CodexError::builder(
crate::utils::format_error_code("RON_PARSE_ERROR"),
format!("Invalid RON format: {e}"),
)),
},
Self::Json => match serde_json::from_str::<T>(content) {
Ok(v) => codex_ok!(v),
Err(e) => Err(CodexError::builder(
crate::utils::format_error_code("JSON_PARSE_ERROR"),
format!("Invalid JSON format: {e}"),
)),
},
#[cfg(feature = "toml")]
Self::Toml => match toml::from_str::<T>(content) {
Ok(v) => codex_ok!(v),
Err(e) => Err(CodexError::builder(
crate::utils::format_error_code("TOML_PARSE_ERROR"),
format!("Invalid TOML format: {e}"),
)),
},
#[cfg(feature = "yaml")]
Self::Yaml => match serde_yaml::from_str::<T>(content) {
Ok(v) => codex_ok!(v),
Err(e) => Err(CodexError::builder(
crate::utils::format_error_code("YAML_PARSE_ERROR"),
format!("Invalid YAML format: {e}"),
)),
},
#[allow(unreachable_patterns)]
_ => Err(CodexError::builder(
crate::utils::format_error_code("FORMAT_NOT_ENABLED"),
"Selected format is not enabled via features",
)),
}
}
}
#[cfg(test)]
mod tests {
#![allow(clippy::unwrap_used)]
use super::*;
use serde::Deserialize;
#[derive(Debug, Deserialize, PartialEq)]
struct DummyConfig {
name: String,
version: u8,
}
#[test]
fn test_parse_ron() {
let content = r#"(
name: "Codex",
version: 1,
)"#;
let result: Result<DummyConfig> = ConfigFormat::Ron.parse(content);
assert!(result.is_ok());
let config = result.unwrap().value;
assert_eq!(config.name, "Codex");
assert_eq!(config.version, 1);
}
#[test]
fn test_parse_json() {
let content = r#"{
"name": "Codex",
"version": 1
}"#;
let result: Result<DummyConfig> = ConfigFormat::Json.parse(content);
assert!(result.is_ok());
}
#[cfg(feature = "yaml")]
#[test]
fn test_parse_yaml() {
let content = "
name: Codex
version: 1
";
let result: Result<DummyConfig> = ConfigFormat::Yaml.parse(content);
assert!(result.is_ok());
}
#[cfg(feature = "toml")]
#[test]
fn test_parse_toml() {
let content = r#"
name = "Codex"
version = 1
"#;
let result: Result<DummyConfig> = ConfigFormat::Toml.parse(content);
assert!(result.is_ok());
}
}