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