1use crate::{ext::*, *};
2use serde::de::DeserializeOwned;
3use std::{str::FromStr, ops::Deref};
4
5pub trait ConfigurationBinder {
7 fn reify<T: DeserializeOwned>(&self) -> T;
9
10 fn bind<T: DeserializeOwned>(&self, instance: &mut T);
16
17 fn bind_at<T: DeserializeOwned>(&self, key: impl AsRef<str>, instance: &mut T);
24
25 fn get_value<T: FromStr>(&self, key: impl AsRef<str>) -> Result<Option<T>, T::Err>;
31
32 fn get_value_or_default<T: FromStr + Default>(&self, key: impl AsRef<str>) -> Result<T, T::Err>;
38}
39
40impl ConfigurationBinder for dyn Configuration + '_ {
41 fn reify<T: DeserializeOwned>(&self) -> T {
42 from_config::<T>(self).unwrap()
43 }
44
45 fn bind<T: DeserializeOwned>(&self, instance: &mut T) {
46 bind_config(self, instance).unwrap()
47 }
48
49 fn bind_at<T: DeserializeOwned>(&self, key: impl AsRef<str>, instance: &mut T) {
50 let section = self.section(key.as_ref());
51
52 if section.exists() {
53 bind_config(section.deref().as_ref(), instance).unwrap()
54 }
55 }
56
57 fn get_value<T: FromStr>(&self, key: impl AsRef<str>) -> Result<Option<T>, T::Err> {
58 let section = self.section(key.as_ref());
59 let value = if section.exists() {
60 Some(T::from_str(section.value().as_str())?)
61 } else {
62 None
63 };
64
65 Ok(value)
66 }
67
68 fn get_value_or_default<T: FromStr + Default>(&self, key: impl AsRef<str>) -> Result<T, T::Err> {
69 let section = self.section(key.as_ref());
70 let value = if section.exists() {
71 T::from_str(section.value().as_str())?
72 } else {
73 T::default()
74 };
75
76 Ok(value)
77 }
78}
79
80impl<C: AsRef<dyn Configuration>> ConfigurationBinder for C {
81 fn reify<T: DeserializeOwned>(&self) -> T {
82 from_config::<T>(self.as_ref()).unwrap()
83 }
84
85 fn bind<T: DeserializeOwned>(&self, instance: &mut T) {
86 bind_config(self.as_ref(), instance).unwrap()
87 }
88
89 fn bind_at<T: DeserializeOwned>(&self, key: impl AsRef<str>, instance: &mut T) {
90 let section = self.as_ref().section(key.as_ref());
91
92 if section.exists() {
93 bind_config(section.deref().as_ref(), instance).unwrap()
94 }
95 }
96
97 fn get_value<T: FromStr>(&self, key: impl AsRef<str>) -> Result<Option<T>, T::Err> {
98 let section = self.as_ref().section(key.as_ref());
99 let value = if section.exists() {
100 Some(T::from_str(section.value().as_str())?)
101 } else {
102 None
103 };
104
105 Ok(value)
106 }
107
108 fn get_value_or_default<T: FromStr + Default>(&self, key: impl AsRef<str>) -> Result<T, T::Err> {
109 let section = self.as_ref().section(key.as_ref());
110 let value = if section.exists() {
111 T::from_str(section.value().as_str())?
112 } else {
113 T::default()
114 };
115
116 Ok(value)
117 }
118}