1 use config::{Config, File, FileStoredFormat, Format, Map, Value, ValueKind};
2
main()3 fn main() {
4 let config = Config::builder()
5 .add_source(File::from_str("bad", MyFormat))
6 .add_source(File::from_str("good", MyFormat))
7 .build();
8
9 match config {
10 Ok(cfg) => println!("A config: {:#?}", cfg),
11 Err(e) => println!("An error: {}", e),
12 }
13 }
14
15 #[derive(Debug, Clone)]
16 pub struct MyFormat;
17
18 impl Format for MyFormat {
parse( &self, uri: Option<&String>, text: &str, ) -> Result<Map<String, config::Value>, Box<dyn std::error::Error + Send + Sync>>19 fn parse(
20 &self,
21 uri: Option<&String>,
22 text: &str,
23 ) -> Result<Map<String, config::Value>, Box<dyn std::error::Error + Send + Sync>> {
24 // Let's assume our format is somewhat malformed, but this is fine
25 // In real life anything can be used here - nom, serde or other.
26 //
27 // For some more real-life examples refer to format implementation within the library code
28 let mut result = Map::new();
29
30 if text == "good" {
31 result.insert(
32 "key".to_string(),
33 Value::new(uri, ValueKind::String(text.into())),
34 );
35 } else {
36 println!("Something went wrong in {:?}", uri);
37 }
38
39 Ok(result)
40 }
41 }
42
43 // As strange as it seems for config sourced from a string, legacy demands its sacrifice
44 // It is only required for File source, custom sources can use Format without caring for extensions
45 static MY_FORMAT_EXT: Vec<&'static str> = vec![];
46 impl FileStoredFormat for MyFormat {
file_extensions(&self) -> &'static [&'static str]47 fn file_extensions(&self) -> &'static [&'static str] {
48 &MY_FORMAT_EXT
49 }
50 }
51