schematic/config/formats/
yaml.rs1use super::create_span;
2use crate::config::error::ConfigError;
3use crate::config::parser::ParserError;
4use crate::config::source::*;
5use miette::NamedSource;
6use serde::de::{DeserializeOwned, IntoDeserializer};
7use serde_norway::{Deserializer, Error, Value};
8use std::path::Path;
9
10#[derive(Default)]
11pub struct YamlFormat {}
12
13impl<T: DeserializeOwned> SourceFormat<T> for YamlFormat {
14 fn should_parse(&self, source: &Source) -> bool {
15 source
16 .get_file_ext()
17 .is_some_and(|ext| ext == "yml" || ext == "yaml")
18 }
19
20 fn parse(
21 &self,
22 source: &Source,
23 content: &str,
24 _cache_path: Option<&Path>,
25 ) -> Result<T, ConfigError> {
26 let name = source.get_file_name();
27
28 fn create_parser_error(
29 name: &str,
30 content: &str,
31 path: String,
32 error: Error,
33 ) -> ParserError {
34 ParserError {
35 content: NamedSource::new(name, content.to_owned()),
36 path,
37 span: error
38 .location()
39 .map(|s| create_span(content, s.line(), s.column())),
40 message: error.to_string(),
41 }
42 }
43
44 let de = Deserializer::from_str(content);
46
47 let mut result: Value = serde_path_to_error::deserialize(de).map_err(|error| {
48 create_parser_error(name, content, error.path().to_string(), error.into_inner())
49 })?;
50
51 result
53 .apply_merge()
54 .map_err(|error| create_parser_error(name, content, String::new(), error))?;
55
56 let de = result.into_deserializer();
58
59 let result: T = serde_path_to_error::deserialize(de).map_err(|error| {
60 create_parser_error(name, content, error.path().to_string(), error.into_inner())
61 })?;
62
63 Ok(result)
64 }
65}