1use crate::{de, section::OwnedSection, Configuration, ReloadableConfiguration, Section};
2use serde::de::DeserializeOwned;
3use std::rc::Rc;
4use std::str::FromStr;
5use std::sync::Arc;
6
7pub trait Binder: Sized {
9 fn reify<T: DeserializeOwned>(&self) -> crate::Result<T>;
11
12 fn reify_unchecked<T: DeserializeOwned>(&self) -> T {
18 match self.reify::<T>() {
19 Ok(data) => data,
20 Err(error) => panic!("{}", error),
21 }
22 }
23
24 fn bind<T: DeserializeOwned>(&self, instance: &mut T) -> crate::Result;
30
31 fn bind_unchecked<T: DeserializeOwned>(&self, instance: &mut T) {
41 if let Err(error) = self.bind(instance) {
42 panic!("{}", error);
43 }
44 }
45
46 fn bind_at<T: DeserializeOwned>(&self, key: impl AsRef<str>, instance: &mut T) -> crate::Result;
53
54 fn bind_at_unchecked<T: DeserializeOwned>(&self, key: impl AsRef<str>, instance: &mut T) {
65 if let Err(error) = self.bind_at(key, instance) {
66 panic!("{}", error);
67 }
68 }
69
70 fn get_value<T: FromStr>(&self, key: impl AsRef<str>) -> Result<Option<T>, T::Err>;
76
77 fn get_value_or_default<T: FromStr + Default>(&self, key: impl AsRef<str>) -> Result<T, T::Err>;
83}
84
85macro_rules! binder {
86 ($type:ty) => {
87 impl Binder for $type {
88 #[inline]
89 fn reify<T: DeserializeOwned>(&self) -> crate::Result<T> {
90 Ok(de::from::<T>(self.sections())?)
91 }
92
93 fn bind<T: DeserializeOwned>(&self, instance: &mut T) -> crate::Result {
94 Ok(de::bind(self.sections(), instance)?)
95 }
96
97 fn bind_at<T: DeserializeOwned>(&self, key: impl AsRef<str>, instance: &mut T) -> crate::Result {
98 let section = self.section(key.as_ref());
99
100 if section.exists() {
101 Ok(de::bind(section.sections(), instance)?)
102 } else {
103 Ok(())
104 }
105 }
106
107 fn get_value<T: FromStr>(&self, key: impl AsRef<str>) -> Result<Option<T>, T::Err> {
108 let section = self.section(key.as_ref());
109 let value = if section.exists() {
110 Some(T::from_str(section.value())?)
111 } else {
112 None
113 };
114
115 Ok(value)
116 }
117
118 fn get_value_or_default<T: FromStr + Default>(&self, key: impl AsRef<str>) -> Result<T, T::Err> {
119 let section = self.section(key.as_ref());
120 let value = if section.exists() {
121 T::from_str(section.value())?
122 } else {
123 T::default()
124 };
125
126 Ok(value)
127 }
128 }
129 };
130}
131
132binder!(Configuration);
133binder!(Arc<Configuration>);
134binder!(Rc<Configuration>);
135binder!(Section<'_>);
136binder!(OwnedSection);
137
138impl Binder for ReloadableConfiguration {
139 #[inline]
140 fn reify<T: DeserializeOwned>(&self) -> crate::Result<T> {
141 self.reify()
142 }
143
144 #[inline]
145 fn bind<T: DeserializeOwned>(&self, instance: &mut T) -> crate::Result {
146 self.bind(instance)
147 }
148
149 #[inline]
150 fn bind_at<T: DeserializeOwned>(&self, key: impl AsRef<str>, instance: &mut T) -> crate::Result {
151 self.bind_at(key, instance)
152 }
153
154 #[inline]
155 fn get_value<T: FromStr>(&self, key: impl AsRef<str>) -> Result<Option<T>, T::Err> {
156 self.get_value(key)
157 }
158
159 #[inline]
160 fn get_value_or_default<T: FromStr + Default>(&self, key: impl AsRef<str>) -> Result<T, T::Err> {
161 self.get_value_or_default(key)
162 }
163}