scf_core/source/default/
mod.rs1use std::fmt;
2use std::sync::{Arc, RwLock};
3use std::time::*;
4
5use super::*;
6
7pub type PropertyProvider = FunctionRef<dyn Key, Option<Box<dyn Value>>>;
8
9#[derive(PartialEq, Eq, Debug, Clone)]
10pub struct DefaultConfiguratonSourceConfig {
11 name: String,
12}
13
14impl ConfigurationSourceConfig for DefaultConfiguratonSourceConfig {
15 fn get_name(&self) -> &str {
16 self.name.as_str()
17 }
18
19 as_boxed!(impl ConfigurationSourceConfig);
20}
21
22pub struct DefaultConfigurationSourceConfigBuilder {
23 name: Option<String>,
24}
25
26impl DefaultConfigurationSourceConfigBuilder {
27 pub fn new() -> Self {
28 Self { name: None }
29 }
30}
31
32impl ConfigurationSourceConfigBuilder for DefaultConfigurationSourceConfigBuilder {
33 fn set_name(&mut self, name: &str) -> &mut dyn ConfigurationSourceConfigBuilder {
34 self.name = Some(name.to_owned());
35 self
36 }
37
38 fn build(&self) -> Box<dyn ConfigurationSourceConfig> {
39 Box::new(DefaultConfiguratonSourceConfig {
40 name: self.name.as_ref().unwrap().to_owned(),
41 })
42 }
43}
44
45#[derive(Clone)]
46pub struct DefaultConfigurationSource {
47 config: Arc<Box<dyn ConfigurationSourceConfig>>,
48 property_provider: Arc<RwLock<PropertyProvider>>,
49 listeners: Arc<RwLock<Vec<ConfigurationSourceChangeListener>>>,
50}
51
52impl DefaultConfigurationSource {
53 pub fn new(
54 config: Box<dyn ConfigurationSourceConfig>,
55 property_provider: PropertyProvider,
56 ) -> DefaultConfigurationSource {
57 DefaultConfigurationSource {
58 config: Arc::new(config),
59 property_provider: Arc::new(RwLock::new(property_provider)),
60 listeners: Arc::new(RwLock::new(Vec::new())),
61 }
62 }
63
64 pub fn raise_change_event(&self) {
65 let event = DefaultConfigurationSourceChangeEvent::new(
66 self,
67 SystemTime::now()
68 .duration_since(UNIX_EPOCH)
69 .unwrap()
70 .as_millis(),
71 );
72 let lock = self.listeners.read().unwrap();
73 for listener in lock.iter() {
74 listener(&event);
75 }
76 }
77}
78
79impl PartialEq for DefaultConfigurationSource {
80 fn eq(&self, other: &Self) -> bool {
81 self.property_provider
82 .as_ref()
83 .reference_equals(other.property_provider.as_ref())
84 }
85}
86
87impl Eq for DefaultConfigurationSource {}
88
89impl fmt::Debug for DefaultConfigurationSource {
90 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
91 write!(
92 f,
93 "{} {{\n\tconfig: {:?}\n}}",
94 self.type_name(),
95 self.config
96 )
97 }
98}
99
100unsafe impl Sync for DefaultConfigurationSource {}
101unsafe impl Send for DefaultConfigurationSource {}
102
103impl ConfigurationSource for DefaultConfigurationSource {
104 fn get_config(&self) -> &dyn ConfigurationSourceConfig {
105 self.config.as_ref().as_ref()
106 }
107
108 fn get_property_value(&self, config: &dyn RawPropertyConfig) -> Option<Box<dyn Value>> {
109 let lock = self.property_provider.read().unwrap();
110 match lock(config.get_raw_key().as_ref()) {
111 Some(v) => {
112 let type_id = v.as_ref().type_id();
113 if type_id == config.get_value_type() {
114 return Some(v);
115 } else {
116 for value_converter in config.get_value_converters() {
117 match value_converter.convert_raw(v.as_ref()) {
118 Ok(v_t) => {
119 debug!(
120 "property value converted by converter, from {:?} to {:?},\n\t\
121 property: {:?},\n\tconverter: {:?}",
122 v.as_ref(),
123 v_t.as_ref(),
124 config,
125 value_converter
126 );
127 return Some(v_t);
128 }
129 Err(error) => {
130 debug!(
131 "property value cannot be converted by converter,\n\tvalue: {:?},\n\t\
132 property: {:?},\n\tconverter: {:?},\n\tconvert error: {:?}",
133 v.as_ref(),
134 config,
135 value_converter,
136 error
137 );
138 }
139 }
140 }
141 }
142 None
143 }
144 None => None,
145 }
146 }
147
148 fn add_change_listener(&self, listener: ConfigurationSourceChangeListener) {
149 let mut lock = self.listeners.write().unwrap();
150 lock.push(listener);
151 }
152
153 as_boxed!(impl ConfigurationSource);
154}
155
156#[derive(Debug, Clone)]
157pub struct DefaultConfigurationSourceChangeEvent {
158 source: Box<dyn ConfigurationSource>,
159 change_time: u128,
160}
161
162impl DefaultConfigurationSourceChangeEvent {
163 pub fn new(source: &dyn ConfigurationSource, change_time: u128) -> Self {
164 DefaultConfigurationSourceChangeEvent {
165 source: ConfigurationSource::clone_boxed(source),
166 change_time,
167 }
168 }
169}
170
171impl PartialEq for DefaultConfigurationSourceChangeEvent {
172 fn eq(&self, other: &Self) -> bool {
173 self.source.eq(&other.source) && self.change_time == other.change_time
174 }
175}
176
177unsafe impl Sync for DefaultConfigurationSourceChangeEvent {}
178unsafe impl Send for DefaultConfigurationSourceChangeEvent {}
179
180impl ConfigurationSourceChangeEvent for DefaultConfigurationSourceChangeEvent {
181 fn get_source(&self) -> &dyn ConfigurationSource {
182 self.source.as_ref()
183 }
184
185 fn get_change_time(&self) -> u128 {
186 self.change_time
187 }
188
189 as_boxed!(impl ConfigurationSourceChangeEvent);
190}
191
192#[cfg(test)]
193mod tests {
194 use super::*;
195 use crate::property::default::*;
196 use crate::tests::init_log;
197 use lang_extension::convert::*;
198 use std::sync::atomic::*;
199
200 #[test]
201 fn source_config_test() {
202 let mut builder = DefaultConfigurationSourceConfigBuilder::new();
203 let config = builder.set_name("test").build();
204 println!("config: {:?}", config);
205 assert_eq!("test", config.get_name());
206 assert_eq!(&config, &config.clone());
207 }
208
209 #[test]
210 fn source_test() {
211 init_log();
212
213 let property_provider: PropertyProvider = Arc::new(Box::new(|k| {
214 if k.equals("10".to_string().as_any_ref()) {
215 Some(Value::to_boxed(10))
216 } else if k.equals("11".to_string().as_any_ref()) {
217 Some(Value::to_boxed("11".to_string()))
218 } else if k.equals("xx".to_string().as_any_ref()) {
219 Some(Value::to_boxed("xx"))
220 } else {
221 None
222 }
223 }));
224 let mut builder = DefaultConfigurationSourceConfigBuilder::new();
225 let config = builder.set_name("test").build();
226 let source = DefaultConfigurationSource::new(config.clone(), property_provider);
227 println!("config source: {:?}", source);
228 assert_eq!(
229 &config,
230 &ConfigurationSourceConfig::clone_boxed(source.get_config())
231 );
232
233 let value_converter =
234 DefaultTypeConverter::<String, i32>::new(Box::new(|s| match s.parse::<i32>() {
235 Ok(v) => {
236 println!("parse value: {}", v);
237 Ok(Box::new(v))
238 }
239 Err(e) => {
240 println!("parse error: {}", e);
241 Err(Box::new(e.to_string()))
242 }
243 }));
244 let property_config = DefaultPropertyConfigBuilder::<String, i32>::new()
245 .set_key(Box::new("10".to_string()))
246 .build();
247 assert_eq!(
248 Some(Value::to_boxed(10)),
249 source.get_property_value(RawPropertyConfig::as_trait_ref(property_config.as_ref()))
250 );
251 let property_config2 = DefaultPropertyConfigBuilder::<String, i32>::new()
252 .set_key(Box::new("1".to_string()))
253 .build();
254 assert_eq!(
255 None,
256 source.get_property_value(RawPropertyConfig::as_trait_ref(property_config2.as_ref()))
257 );
258 let property_config3 = DefaultPropertyConfigBuilder::<i32, i32>::new()
259 .set_key(Box::new(1))
260 .build();
261 assert_eq!(
262 None,
263 source.get_property_value(RawPropertyConfig::as_trait_ref(property_config3.as_ref()))
264 );
265 let property_config4 = DefaultPropertyConfigBuilder::<String, i32>::new()
266 .set_key(Box::new("11".to_string()))
267 .add_value_converter(Box::new(value_converter.clone()))
268 .build();
269 assert_eq!(
270 Some(Value::to_boxed(11)),
271 source.get_property_value(RawPropertyConfig::as_trait_ref(property_config4.as_ref()))
272 );
273 let property_config5 = DefaultPropertyConfigBuilder::<String, i32>::new()
274 .set_key(Box::new("xx".to_string()))
275 .add_value_converter(Box::new(value_converter.clone()))
276 .build();
277 assert_eq!(
278 None,
279 source.get_property_value(RawPropertyConfig::as_trait_ref(property_config5.as_ref()))
280 );
281
282 let changed = Arc::new(AtomicBool::default());
283 let changed_clone = changed.clone();
284 source.add_change_listener(Arc::new(Box::new(move |e| {
285 println!("event: {:?}", e);
286 changed_clone.swap(true, Ordering::Relaxed);
287 })));
288
289 source.raise_change_event();
290 assert!(changed.fetch_and(true, Ordering::Relaxed));
291 }
292
293 #[test]
294 fn source_event_test() {
295 let property_provider: PropertyProvider = Arc::new(Box::new(|k| {
296 if k.equals("10".to_string().as_any_ref()) {
297 Some(Value::to_boxed(10))
298 } else {
299 None
300 }
301 }));
302 let mut builder = DefaultConfigurationSourceConfigBuilder::new();
303 let config = builder.set_name("test").build();
304 let source = DefaultConfigurationSource::new(config.clone(), property_provider);
305
306 let start = SystemTime::now();
307 let since_the_epoch = start.duration_since(UNIX_EPOCH).unwrap();
308 let event =
309 DefaultConfigurationSourceChangeEvent::new(&source, since_the_epoch.as_millis());
310 println!("source event: {:?}", event);
311
312 assert!(source.equals(event.get_source().as_any_ref()));
313 assert_eq!(since_the_epoch.as_millis(), event.get_change_time());
314 }
315}