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