1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
// Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
// ------------------------------------------------------------

// Integrating service fabric config package with config-rs.
// Wraps the SF ConfigurationPackage as a Source for config-rs.
// config-rs can load from SF and user can use all higher level
// features of config-rs.

use config::{ConfigError, Source};
use log::info;

use crate::runtime::config::ConfigurationPackage;
pub use config::Config;

/// Integrate with config-rs
/// Example:
/// let source = FabricConfigSource::new(config);
/// let s = config::Config::builder()
/// .add_source(source)
/// .build()?
///
#[derive(Debug, Clone)]
pub struct FabricConfigSource {
    inner: ConfigurationPackage,
}

impl FabricConfigSource {
    pub fn new(c: ConfigurationPackage) -> Self {
        Self { inner: c }
    }
}

impl Source for FabricConfigSource {
    fn clone_into_box(&self) -> Box<dyn Source + Send + Sync> {
        Box::new(self.clone())
    }

    fn collect(&self) -> Result<config::Map<String, config::Value>, ConfigError> {
        let uri_origion = String::from("fabric source");
        let mut res = config::Map::new();
        let settings = self.inner.get_settings();
        settings
            .sections
            .iter()
            .enumerate()
            .for_each(|(_, section)| {
                let section_name = section.name.to_string();
                info!("Section: {}", section_name);
                section.parameters.iter().enumerate().for_each(|(_, p)| {
                    let param_name = p.name.to_string();
                    let param_val = p.value.to_string();
                    info!("Param: {:?}", param_name);
                    let val = config::Value::new(
                        Some(&uri_origion),
                        config::ValueKind::String(param_val),
                    );
                    // section and param is separated by a dot.
                    res.insert(section_name.clone() + "." + &param_name, val);
                })
            });
        Ok(res)
    }
}