scconfig_rs/
environment.rs1use std::collections::BTreeMap;
2
3use serde::de::DeserializeOwned;
4use serde::{Deserialize, Serialize};
5use serde_json::Value;
6
7use crate::{
8 Result, ScalarCoercion,
9 binding::{coerce_json_value, deserialize_json_value, nested_value_from_flat_map},
10};
11
12#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
14pub struct Environment {
15 pub name: String,
17 #[serde(default)]
19 pub profiles: Vec<String>,
20 #[serde(default)]
22 pub label: Option<String>,
23 #[serde(default)]
25 pub version: Option<String>,
26 #[serde(default)]
28 pub state: Option<String>,
29 #[serde(rename = "propertySources", default)]
31 pub property_sources: Vec<PropertySource>,
32}
33
34impl Environment {
35 pub fn effective_properties(&self) -> BTreeMap<String, Value> {
40 let mut merged = BTreeMap::new();
41
42 for source in self.property_sources.iter().rev() {
43 for (key, value) in &source.source {
44 merged.insert(key.clone(), value.clone());
45 }
46 }
47
48 merged
49 }
50
51 pub fn to_value(&self) -> Value {
53 self.to_value_with_coercion(ScalarCoercion::None)
54 }
55
56 pub fn to_value_with_coercion(&self, coercion: ScalarCoercion) -> Value {
58 nested_value_from_flat_map(self.effective_properties(), coercion)
59 }
60
61 pub fn deserialize<T>(&self) -> Result<T>
63 where
64 T: DeserializeOwned,
65 {
66 self.deserialize_with_coercion(ScalarCoercion::Smart)
67 }
68
69 pub fn deserialize_with_coercion<T>(&self, coercion: ScalarCoercion) -> Result<T>
71 where
72 T: DeserializeOwned,
73 {
74 deserialize_json_value(
75 coerce_json_value(self.to_value_with_coercion(ScalarCoercion::None), coercion),
76 format!("environment `{}`", self.name),
77 )
78 }
79
80 pub fn deserialize_strict<T>(&self) -> Result<T>
82 where
83 T: DeserializeOwned,
84 {
85 self.deserialize_with_coercion(ScalarCoercion::None)
86 }
87}
88
89#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
91pub struct PropertySource {
92 pub name: String,
94 #[serde(default)]
96 pub source: BTreeMap<String, Value>,
97}