scf_core/property/default/
mod.rs

1use std::any::TypeId;
2use std::cell::RefCell;
3use std::fmt;
4use std::fmt::{Debug, Formatter, Result};
5use std::hash::{Hash, Hasher};
6use std::marker::PhantomData;
7use std::sync::{Arc, RwLock};
8
9use super::*;
10
11#[derive(Clone)]
12pub struct DefaultRawPropertyConfig {
13    key: ImmutableKey,
14    value_type: TypeId,
15    default_value: Option<ImmutableValue>,
16    value_converters: Arc<Vec<Box<dyn RawTypeConverter>>>,
17    value_filter: Option<Box<dyn RawValueFilter>>,
18    doc: Option<String>,
19    _static: bool,
20    required: bool,
21}
22
23impl DefaultRawPropertyConfig {
24    pub fn check_valid(&self) {
25        if self.default_value.is_none() || self.value_filter.is_none() {
26            return;
27        }
28
29        let new_value = self
30            .value_filter
31            .as_ref()
32            .unwrap()
33            .filter_raw(self.default_value.as_ref().unwrap().raw_boxed());
34        if new_value.is_none() {
35            panic!(
36                "None is returned when the value filter filters the default value, \
37                you should either fix the default value or fix the value filter!\n\
38                Property Config: {:?}",
39                self
40            );
41        }
42    }
43}
44
45impl RawPropertyConfig for DefaultRawPropertyConfig {
46    fn get_raw_key(&self) -> Box<dyn Key> {
47        self.key.raw_boxed()
48    }
49
50    fn get_value_type(&self) -> TypeId {
51        self.value_type
52    }
53
54    fn get_raw_default_value(&self) -> Option<Box<dyn Value>> {
55        self.default_value.as_ref().map(|v| v.raw_boxed())
56    }
57
58    fn get_value_converters(&self) -> &[Box<dyn RawTypeConverter>] {
59        self.value_converters.as_ref().as_slice()
60    }
61
62    fn get_value_filter(&self) -> Option<&dyn RawValueFilter> {
63        self.value_filter.as_ref().map(|f| f.as_ref())
64    }
65
66    fn get_doc(&self) -> Option<&str> {
67        self.doc.as_ref().map(|v| v.as_str())
68    }
69
70    fn is_static(&self) -> bool {
71        self._static
72    }
73
74    fn is_required(&self) -> bool {
75        self.required
76    }
77
78    as_boxed!(impl RawPropertyConfig);
79    as_trait!(impl RawPropertyConfig);
80}
81
82impl Hash for DefaultRawPropertyConfig {
83    fn hash<H: Hasher>(&self, state: &mut H) {
84        self.key.hash(state);
85    }
86}
87
88impl PartialEq for DefaultRawPropertyConfig {
89    fn eq(&self, other: &Self) -> bool {
90        self.key == other.key
91            && self.value_type == other.value_type
92            && self.default_value == other.default_value
93            && self.value_converters.as_ref() == other.value_converters.as_ref()
94            && self.value_filter == other.value_filter
95            && self.doc == other.doc
96            && self._static == other._static
97            && self.required == other.required
98    }
99}
100
101impl Eq for DefaultRawPropertyConfig {}
102
103impl Debug for DefaultRawPropertyConfig {
104    fn fmt(&self, f: &mut Formatter) -> Result {
105        write!(
106            f,
107            "{} {{\n\tkey: {:?},\n\tvalue_type: {:?},\n\tdefault_value: {:?},\n\t\
108            value_converters: {:?},\n\tvalue_filter: {:?},\n\tdoc: {:?},\n\tstatic: {:?},\n\t\
109            required: {:?}\n}}",
110            self.type_name(),
111            self.key,
112            self.value_type,
113            self.default_value,
114            self.value_converters,
115            self.value_filter.type_name(),
116            self.doc,
117            self._static,
118            self.required
119        )
120    }
121}
122
123unsafe impl Sync for DefaultRawPropertyConfig {}
124unsafe impl Send for DefaultRawPropertyConfig {}
125
126#[derive(Clone)]
127pub struct DefaultPropertyConfig<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint> {
128    raw: Arc<Box<dyn RawPropertyConfig>>,
129    k: PhantomData<K>,
130    v: PhantomData<V>,
131}
132
133impl<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint> DefaultPropertyConfig<K, V> {
134    pub fn from_raw(config: &dyn RawPropertyConfig) -> Self {
135        DefaultPropertyConfig {
136            raw: Arc::new(RawPropertyConfig::clone_boxed(config)),
137            k: PhantomData::<K>,
138            v: PhantomData::<V>,
139        }
140    }
141}
142
143impl<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint> Hash for DefaultPropertyConfig<K, V> {
144    fn hash<H: Hasher>(&self, state: &mut H) {
145        self.raw.as_ref().hash(state);
146    }
147}
148
149impl<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint> PartialEq
150    for DefaultPropertyConfig<K, V>
151{
152    fn eq(&self, other: &Self) -> bool {
153        self.raw.as_ref() == other.raw.as_ref()
154    }
155}
156
157impl<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint> Eq for DefaultPropertyConfig<K, V> {}
158
159impl<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint> fmt::Debug
160    for DefaultPropertyConfig<K, V>
161{
162    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
163        write!(
164            f,
165            "{} {{\n\tkey: {:?},\n\tvalue_type: {:?},\n\tdefault_value: {:?},\n\t\
166            value_converters: {:?},\n\tvalue_filter: {:?},\n\tdoc: {:?},\n\tstatic: {:?},\n\t\
167            required: {:?}\n}}",
168            self.type_name(),
169            self.get_raw_key(),
170            self.get_value_type(),
171            self.get_raw_default_value(),
172            self.get_value_converters(),
173            self.get_value_filter().type_name(),
174            self.get_doc(),
175            self.is_static(),
176            self.is_required()
177        )
178    }
179}
180
181unsafe impl<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint> Sync
182    for DefaultPropertyConfig<K, V>
183{
184}
185unsafe impl<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint> Send
186    for DefaultPropertyConfig<K, V>
187{
188}
189
190impl<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint> RawPropertyConfig
191    for DefaultPropertyConfig<K, V>
192{
193    fn get_raw_key(&self) -> Box<dyn Key> {
194        self.raw.get_raw_key()
195    }
196
197    fn get_value_type(&self) -> TypeId {
198        self.raw.get_value_type()
199    }
200
201    fn get_raw_default_value(&self) -> Option<Box<dyn Value>> {
202        self.raw.get_raw_default_value()
203    }
204
205    fn get_value_converters(&self) -> &[Box<dyn RawTypeConverter>] {
206        self.raw.get_value_converters()
207    }
208
209    fn get_value_filter(&self) -> Option<&dyn RawValueFilter> {
210        self.raw.get_value_filter()
211    }
212
213    fn get_doc(&self) -> Option<&str> {
214        self.raw.get_doc()
215    }
216
217    fn is_static(&self) -> bool {
218        self.raw.is_static()
219    }
220
221    fn is_required(&self) -> bool {
222        self.raw.is_required()
223    }
224
225    as_boxed!(impl RawPropertyConfig);
226    as_trait!(impl RawPropertyConfig);
227}
228
229impl<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint> PropertyConfig<K, V>
230    for DefaultPropertyConfig<K, V>
231{
232    fn get_key(&self) -> Box<K> {
233        Box::new(
234            self.raw
235                .get_raw_key()
236                .as_ref()
237                .as_any_ref()
238                .downcast_ref::<K>()
239                .unwrap()
240                .clone(),
241        )
242    }
243
244    fn get_default_value(&self) -> Option<Box<V>> {
245        self.raw
246            .get_raw_default_value()
247            .map(|v| Box::new(v.as_ref().as_any_ref().downcast_ref::<V>().unwrap().clone()))
248    }
249
250    as_boxed!(impl PropertyConfig<K, V>);
251}
252
253pub struct DefaultPropertyConfigBuilder<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint> {
254    key: Option<Box<K>>,
255    value_type: TypeId,
256    default_value: Option<Box<V>>,
257    value_converters: Vec<Box<dyn RawTypeConverter>>,
258    value_filter: Option<Box<dyn ValueFilter<V>>>,
259    doc: Option<String>,
260    _static: bool,
261    required: bool,
262}
263
264impl<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint> DefaultPropertyConfigBuilder<K, V> {
265    pub fn new() -> Self {
266        Self {
267            key: None,
268            value_type: TypeId::of::<V>(),
269            default_value: None,
270            value_converters: Vec::new(),
271            value_filter: None,
272            doc: None,
273            _static: false,
274            required: false,
275        }
276    }
277}
278
279impl<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint> PropertyConfigBuilder<K, V>
280    for DefaultPropertyConfigBuilder<K, V>
281{
282    fn set_key(&mut self, key: Box<K>) -> &mut dyn PropertyConfigBuilder<K, V> {
283        self.key = Some(key);
284        self
285    }
286
287    fn set_default_value(&mut self, default_value: Box<V>) -> &mut dyn PropertyConfigBuilder<K, V> {
288        self.default_value = Some(default_value);
289        self
290    }
291
292    fn add_value_converter(
293        &mut self,
294        value_converter: Box<dyn RawTypeConverter>,
295    ) -> &mut dyn PropertyConfigBuilder<K, V> {
296        self.value_converters.push(value_converter);
297        self
298    }
299
300    fn add_value_converters(
301        &mut self,
302        value_converters: Vec<Box<dyn RawTypeConverter>>,
303    ) -> &mut dyn PropertyConfigBuilder<K, V> {
304        let mut value_converters = value_converters;
305        self.value_converters.append(&mut value_converters);
306        self
307    }
308
309    fn set_value_filter(
310        &mut self,
311        value_filter: Box<dyn ValueFilter<V>>,
312    ) -> &mut dyn PropertyConfigBuilder<K, V> {
313        self.value_filter = Some(value_filter);
314        self
315    }
316
317    fn set_doc(&mut self, doc: &str) -> &mut dyn PropertyConfigBuilder<K, V> {
318        self.doc = Some(doc.to_string());
319        self
320    }
321
322    fn set_static(&mut self, is_static: bool) -> &mut dyn PropertyConfigBuilder<K, V> {
323        self._static = is_static;
324        self
325    }
326
327    fn set_required(&mut self, required: bool) -> &mut dyn PropertyConfigBuilder<K, V> {
328        self.required = required;
329        self
330    }
331
332    fn build(&self) -> Box<dyn PropertyConfig<K, V>> {
333        let raw = DefaultRawPropertyConfig {
334            key: ImmutableKey::wrap(self.key.clone().unwrap()),
335            value_type: self.value_type,
336            default_value: self
337                .default_value
338                .as_ref()
339                .map(|v| v.clone())
340                .map(|v| ImmutableValue::wrap(v)),
341            value_converters: Arc::new(self.value_converters.clone()),
342            value_filter: self
343                .value_filter
344                .as_ref()
345                .map(|f| RawValueFilter::clone_boxed(f.as_ref())),
346            doc: self.doc.clone(),
347            _static: self._static,
348            required: self.required,
349        };
350        raw.check_valid();
351        Box::new(DefaultPropertyConfig {
352            raw: Arc::new(RawPropertyConfig::clone_boxed(&raw)),
353            k: PhantomData::<K>,
354            v: PhantomData::<V>,
355        })
356    }
357}
358
359#[derive(Clone)]
360pub struct DefaultRawProperty {
361    config: Arc<Box<dyn RawPropertyConfig>>,
362    value: Arc<RwLock<RefCell<Option<ImmutableValue>>>>,
363    source: Arc<RwLock<RefCell<Option<Box<dyn ConfigurationSource>>>>>,
364    change_listeners: Arc<RwLock<Vec<RawPropertyChangeListener>>>,
365}
366
367impl DefaultRawProperty {
368    pub fn new(config: &dyn RawPropertyConfig) -> Self {
369        DefaultRawProperty {
370            config: Arc::new(RawPropertyConfig::clone_boxed(config)),
371            value: Arc::new(RwLock::new(RefCell::new(None))),
372            source: Arc::new(RwLock::new(RefCell::new(None))),
373            change_listeners: Arc::new(RwLock::new(Vec::new())),
374        }
375    }
376
377    pub fn update(
378        &self,
379        value: Option<Box<dyn Value>>,
380        source: Option<Box<dyn ConfigurationSource>>,
381    ) {
382        let value_lock = self.value.write().unwrap();
383        value_lock.replace(value.map(|v| ImmutableValue::wrap(v)));
384        let source_lock = self.source.write().unwrap();
385        source_lock.replace(source);
386    }
387
388    pub fn raise_change_event(&self, event: &dyn RawPropertyChangeEvent) {
389        let listeners = self.change_listeners.read().unwrap();
390        for listener in listeners.iter() {
391            listener(event);
392        }
393    }
394}
395
396impl RawProperty for DefaultRawProperty {
397    fn get_raw_config(&self) -> &dyn RawPropertyConfig {
398        self.config.as_ref().as_ref()
399    }
400
401    fn get_raw_value(&self) -> Option<Box<dyn Value>> {
402        let cell = self.value.read().unwrap();
403        let r = cell.borrow();
404        r.as_ref().map(|v| v.raw_boxed())
405    }
406
407    fn add_raw_change_listener(&self, listener: RawPropertyChangeListener) {
408        self.change_listeners.write().unwrap().push(listener);
409    }
410
411    fn get_source(&self) -> Option<Box<dyn ConfigurationSource>> {
412        let cell = self.source.read().unwrap();
413        let r = cell.borrow();
414        r.as_ref().map(|v| v.clone())
415    }
416
417    as_boxed!(impl RawProperty);
418    as_trait!(impl RawProperty);
419}
420
421impl PartialEq for DefaultRawProperty {
422    fn eq(&self, other: &Self) -> bool {
423        self.value.as_ref().reference_equals(other.value.as_ref())
424    }
425}
426
427impl Eq for DefaultRawProperty {}
428
429impl fmt::Debug for DefaultRawProperty {
430    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
431        write!(
432            f,
433            "{} {{\n\tconfig: {:?},\n\tvalue: {:?},\n\tsource: {:?}\n}}",
434            self.type_name(),
435            self.get_raw_config(),
436            self.get_raw_value(),
437            self.get_source()
438                .map(|v| v.get_config().get_name().to_string())
439        )
440    }
441}
442
443unsafe impl Sync for DefaultRawProperty {}
444unsafe impl Send for DefaultRawProperty {}
445
446#[derive(Clone)]
447pub struct DefaultProperty<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint> {
448    config: Arc<Box<dyn PropertyConfig<K, V>>>,
449    raw: Arc<Box<dyn RawProperty>>,
450}
451
452impl<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint> DefaultProperty<K, V> {
453    pub fn from_raw(property: &dyn RawProperty) -> Self {
454        DefaultProperty {
455            config: Arc::new(Box::new(DefaultPropertyConfig::from_raw(
456                property.get_raw_config(),
457            ))),
458            raw: Arc::new(RawProperty::clone_boxed(property)),
459        }
460    }
461}
462
463impl<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint> PartialEq for DefaultProperty<K, V> {
464    fn eq(&self, other: &Self) -> bool {
465        self.raw.as_ref() == other.raw.as_ref()
466    }
467}
468
469impl<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint> Eq for DefaultProperty<K, V> {}
470
471impl<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint> fmt::Debug for DefaultProperty<K, V> {
472    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
473        write!(
474            f,
475            "{} {{\n\tvalue: {:?},\n\tsource: {:?},\n\tconfig: {:?}\n}}",
476            self.type_name(),
477            self.get_raw_config(),
478            self.get_raw_value(),
479            self.get_source()
480                .map(|v| v.get_config().get_name().to_string())
481        )
482    }
483}
484
485unsafe impl<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint> Sync for DefaultProperty<K, V> {}
486unsafe impl<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint> Send for DefaultProperty<K, V> {}
487
488impl<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint> RawProperty for DefaultProperty<K, V> {
489    fn get_raw_config(&self) -> &dyn RawPropertyConfig {
490        self.raw.get_raw_config()
491    }
492
493    fn get_raw_value(&self) -> Option<Box<dyn Value>> {
494        self.raw.get_raw_value()
495    }
496
497    fn add_raw_change_listener(&self, listener: RawPropertyChangeListener) {
498        self.raw.add_raw_change_listener(listener);
499    }
500
501    fn get_source(&self) -> Option<Box<dyn ConfigurationSource>> {
502        self.raw.get_source()
503    }
504
505    as_boxed!(impl RawProperty);
506    as_trait!(impl RawProperty);
507}
508
509impl<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint> Property<K, V>
510    for DefaultProperty<K, V>
511{
512    fn get_config(&self) -> &dyn PropertyConfig<K, V> {
513        self.config.as_ref().as_ref()
514    }
515
516    fn get_value(&self) -> Option<Box<V>> {
517        self.raw
518            .get_raw_value()
519            .map(|v| Box::new(v.as_ref().as_any_ref().downcast_ref::<V>().unwrap().clone()))
520    }
521
522    fn add_change_listener(&self, listener: PropertyChangeListener<K, V>) {
523        self.raw
524            .add_raw_change_listener(Arc::new(Box::new(move |e| {
525                listener(&DefaultPropertyChangeEvent::from_raw(e));
526            })));
527    }
528
529    as_boxed!(impl Property<K, V>);
530}
531
532#[derive(Clone, Debug)]
533pub struct DefaultRawPropertyChangeEvent {
534    property: Arc<Box<dyn RawProperty>>,
535    old_value: Option<ImmutableValue>,
536    new_value: Option<ImmutableValue>,
537    change_time: u128,
538}
539
540impl DefaultRawPropertyChangeEvent {
541    pub fn new(
542        property: Arc<Box<dyn RawProperty>>,
543        old_value: Option<ImmutableValue>,
544        new_value: Option<ImmutableValue>,
545        change_time: u128,
546    ) -> Self {
547        DefaultRawPropertyChangeEvent {
548            property,
549            old_value,
550            new_value,
551            change_time,
552        }
553    }
554}
555
556impl PartialEq for DefaultRawPropertyChangeEvent {
557    fn eq(&self, other: &Self) -> bool {
558        self.property.as_ref() == other.property.as_ref()
559            && self.old_value == other.old_value
560            && self.new_value == other.new_value
561            && self.change_time == other.change_time
562    }
563}
564
565impl Eq for DefaultRawPropertyChangeEvent {}
566
567unsafe impl Sync for DefaultRawPropertyChangeEvent {}
568unsafe impl Send for DefaultRawPropertyChangeEvent {}
569
570impl RawPropertyChangeEvent for DefaultRawPropertyChangeEvent {
571    fn get_raw_property(&self) -> &dyn RawProperty {
572        self.property.as_ref().as_ref()
573    }
574
575    fn get_raw_old_value(&self) -> Option<Box<dyn Value>> {
576        self.old_value.as_ref().map(|v| v.raw_boxed())
577    }
578
579    fn get_raw_new_value(&self) -> Option<Box<dyn Value>> {
580        self.new_value.as_ref().map(|v| v.raw_boxed())
581    }
582
583    fn get_change_time(&self) -> u128 {
584        self.change_time
585    }
586
587    as_boxed!(impl RawPropertyChangeEvent);
588    as_trait!(impl RawPropertyChangeEvent);
589}
590
591#[derive(Clone)]
592pub struct DefaultPropertyChangeEvent<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint> {
593    property: Arc<Box<dyn Property<K, V>>>,
594    raw: Arc<Box<dyn RawPropertyChangeEvent>>,
595}
596
597impl<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint> DefaultPropertyChangeEvent<K, V> {
598    pub fn from_raw(event: &dyn RawPropertyChangeEvent) -> Self {
599        let property = DefaultProperty::<K, V>::from_raw(event.get_raw_property());
600        DefaultPropertyChangeEvent {
601            property: Arc::new(Box::new(property)),
602            raw: Arc::new(RawPropertyChangeEvent::clone_boxed(event)),
603        }
604    }
605}
606
607impl<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint> PartialEq
608    for DefaultPropertyChangeEvent<K, V>
609{
610    fn eq(&self, other: &Self) -> bool {
611        self.raw.as_ref() == other.raw.as_ref()
612    }
613}
614
615impl<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint> Eq
616    for DefaultPropertyChangeEvent<K, V>
617{
618}
619
620impl<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint> fmt::Debug
621    for DefaultPropertyChangeEvent<K, V>
622{
623    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
624        write!(
625            f,
626            "{} {{\n\tproperty: {:?},\n\told_value: {:?},\n\tnew_value: {:?},\n\t\
627            change_time: {:?}\n}}",
628            self.type_name(),
629            self.get_property(),
630            self.get_old_value(),
631            self.get_new_value(),
632            self.get_change_time()
633        )
634    }
635}
636
637unsafe impl<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint> Sync
638    for DefaultPropertyChangeEvent<K, V>
639{
640}
641unsafe impl<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint> Send
642    for DefaultPropertyChangeEvent<K, V>
643{
644}
645
646impl<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint> RawPropertyChangeEvent
647    for DefaultPropertyChangeEvent<K, V>
648{
649    fn get_raw_property(&self) -> &dyn RawProperty {
650        self.raw.get_raw_property()
651    }
652
653    fn get_raw_old_value(&self) -> Option<Box<dyn Value>> {
654        self.raw.get_raw_old_value()
655    }
656
657    fn get_raw_new_value(&self) -> Option<Box<dyn Value>> {
658        self.raw.get_raw_new_value()
659    }
660
661    fn get_change_time(&self) -> u128 {
662        self.raw.get_change_time()
663    }
664
665    as_boxed!(impl RawPropertyChangeEvent);
666    as_trait!(impl RawPropertyChangeEvent);
667}
668
669impl<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint> PropertyChangeEvent<K, V>
670    for DefaultPropertyChangeEvent<K, V>
671{
672    fn get_property(&self) -> &dyn Property<K, V> {
673        self.property.as_ref().as_ref()
674    }
675
676    fn get_old_value(&self) -> Option<Box<V>> {
677        self.raw
678            .get_raw_old_value()
679            .map(|v| Box::new(v.as_ref().as_any_ref().downcast_ref::<V>().unwrap().clone()))
680    }
681
682    fn get_new_value(&self) -> Option<Box<V>> {
683        self.raw
684            .get_raw_new_value()
685            .map(|v| Box::new(v.as_ref().as_any_ref().downcast_ref::<V>().unwrap().clone()))
686    }
687
688    as_boxed!(impl PropertyChangeEvent<K, V>);
689}
690
691#[cfg(test)]
692mod test {
693
694    use super::*;
695    use std::any::Any;
696    use std::thread::*;
697    use std::time::*;
698
699    fn new_converter() -> DefaultTypeConverter<String, i32> {
700        DefaultTypeConverter::<String, i32>::new(Box::new(move |v| match v.parse::<i32>() {
701            Ok(v) => Ok(Box::new(v)),
702            Err(err) => Err(Box::new(err)),
703        }))
704    }
705
706    fn new_filter() -> DefaultValueFilter<i32> {
707        DefaultValueFilter::new(Box::new(move |v| {
708            if *v > 10 {
709                Some(Box::new(*v + 1))
710            } else if *v > 0 {
711                Some(v)
712            } else {
713                None
714            }
715        }))
716    }
717
718    fn new_config() -> Box<dyn PropertyConfig<i32, i32>> {
719        let c = new_converter();
720        let f = new_filter();
721
722        new_config_with(&c, &f)
723    }
724
725    fn new_config_with(
726        c: &DefaultTypeConverter<String, i32>,
727        f: &DefaultValueFilter<i32>,
728    ) -> Box<dyn PropertyConfig<i32, i32>> {
729        DefaultPropertyConfigBuilder::new()
730            .set_key(Box::new(1))
731            .set_default_value(Box::new(2))
732            .add_value_converter(RawTypeConverter::clone_boxed(c))
733            .set_value_filter(Box::new(f.clone()))
734            .set_doc("test property")
735            .build()
736    }
737
738    #[test]
739    fn property_config_test() {
740        let c = new_converter();
741        let f = new_filter();
742        let config = new_config_with(&c, &f);
743        println!("{:?}", config);
744        assert_eq!(1, *config.get_key());
745        assert_eq!(2.type_id(), config.get_value_type());
746        assert_eq!(Some(Box::new(2)), config.get_default_value());
747        assert_eq!(Some("test property"), config.get_doc());
748        assert_eq!(false, config.is_static());
749        assert_eq!(false, config.is_required());
750
751        assert_eq!(&config, &config.clone());
752        let boxed_config = RawPropertyConfig::clone_boxed(config.as_ref());
753        assert_eq!(&boxed_config, &boxed_config.clone());
754
755        let s = "1".to_string();
756        let s2 = "xx1".to_string();
757        let rc = config.get_value_converters().get(0).unwrap().as_ref();
758        assert_eq!(
759            Ok(Value::to_boxed(1)),
760            rc.convert_raw(Value::as_trait_ref(&s))
761        );
762        assert_ne!(
763            Ok(Value::to_boxed(2)),
764            rc.convert_raw(Value::as_trait_ref(&s))
765        );
766        assert!(rc.convert_raw(Value::as_trait_ref(&s2)).is_err());
767        assert!(rc.convert_raw(Value::as_trait_ref(&true)).is_err());
768        let rf = config.get_value_filter().unwrap();
769        assert_eq!(Some(Value::to_boxed(1)), rf.filter_raw(Value::to_boxed(1)));
770        assert_eq!(
771            Some(Value::to_boxed(12)),
772            rf.filter_raw(Value::to_boxed(11))
773        );
774        assert_eq!(None, rf.filter_raw(Value::to_boxed(0)));
775        assert_eq!(None, rf.filter_raw(Value::to_boxed(s2)));
776
777        let config2 = new_config_with(&c, &f);
778        assert!(!config.reference_equals(&config2));
779        assert!(
780            !config
781                .as_ref()
782                .reference_equals(config2.as_ref().as_any_ref())
783        );
784        assert!(config.as_ref().equals(config2.as_ref().as_any_ref()));
785        assert!(
786            RawPropertyConfig::as_trait_ref(config.as_ref())
787                .equals(RawPropertyConfig::as_trait_ref(config2.as_ref()).as_any_ref())
788        );
789        assert_eq!(
790            &RawPropertyConfig::clone_boxed(config.as_ref()),
791            &RawPropertyConfig::clone_boxed(config2.as_ref())
792        );
793    }
794
795    #[should_panic]
796    #[test]
797    fn invalid_property_config_test() {
798        let f = new_filter();
799        DefaultPropertyConfigBuilder::new()
800            .set_key(Box::new(1))
801            .set_default_value(Box::new(0))
802            .set_value_filter(Box::new(f.clone()))
803            .set_doc("test property")
804            .build();
805    }
806
807    #[test]
808    fn property_test() {
809        let config = new_config();
810        let property = DefaultRawProperty::new(RawPropertyConfig::as_trait_ref(config.as_ref()));
811        println!("property: {:?}", property);
812        assert!(
813            property
814                .get_raw_config()
815                .equals(config.as_ref().as_any_ref())
816        );
817        assert_eq!(None, property.get_raw_value());
818        property.update(Some(Box::new(0)), None);
819        assert_eq!(Some(Value::to_boxed(0)), property.get_raw_value());
820        assert_eq!(None, property.get_source());
821
822        assert_eq!(&property, &property.clone());
823        let boxed_property = RawProperty::clone_boxed(&property);
824        assert_eq!(&boxed_property, &boxed_property.clone());
825
826        let changed = Arc::new(RwLock::new(Box::new(false)));
827        let changed_clone = changed.clone();
828        property.add_raw_change_listener(Arc::new(Box::new(move |e| {
829            println!(
830                "property: {:?}, old_value: {:?}, new_value: {:?}, change_time: {:?}",
831                e.get_raw_property(),
832                e.get_raw_old_value(),
833                e.get_raw_new_value(),
834                e.get_change_time()
835            );
836            let mut v = changed_clone.write().unwrap();
837            **v = true;
838        })));
839        property.update(Some(Box::new(1)), None);
840        let arc_property = Arc::new(RawProperty::to_boxed(property.clone()));
841        let start = SystemTime::now();
842        let since_the_epoch = start.duration_since(UNIX_EPOCH).unwrap();
843        let event = DefaultRawPropertyChangeEvent::new(
844            arc_property,
845            Some(ImmutableValue::new(0)),
846            Some(ImmutableValue::new(0)),
847            since_the_epoch.as_millis(),
848        );
849        assert_eq!(false, **changed.read().unwrap());
850        property.raise_change_event(&event);
851        sleep(Duration::from_millis(100));
852        assert_eq!(true, **changed.read().unwrap());
853
854        let property2 = DefaultProperty::<i32, i32>::from_raw(&property);
855        println!("property: {:?}", property2);
856        assert_eq!(Some(Box::new(1)), property2.get_value());
857        property.update(Some(Box::new(2)), None);
858        assert_eq!(Some(Box::new(2)), property2.get_value());
859        let changed2 = Arc::new(RwLock::new(Box::new(false)));
860        let changed2_clone = changed2.clone();
861        property2.add_change_listener(Arc::new(Box::new(move |e| {
862            println!(
863                "property: {:?}, old_value: {:?}, new_value: {:?}, change_time: {:?}",
864                e.get_property(),
865                e.get_old_value(),
866                e.get_new_value(),
867                e.get_change_time()
868            );
869            let mut v = changed2_clone.write().unwrap();
870            **v = true;
871        })));
872
873        assert_eq!(&property2, &property2.clone());
874        let boxed_property2 = Property::<i32, i32>::clone_boxed(&property2);
875        assert_eq!(&boxed_property2, &boxed_property2.clone());
876
877        let arc_property = Arc::new(RawProperty::to_boxed(property.clone()));
878        let start = SystemTime::now();
879        let since_the_epoch = start.duration_since(UNIX_EPOCH).unwrap();
880        let event = DefaultRawPropertyChangeEvent::new(
881            arc_property,
882            Some(ImmutableValue::new(0)),
883            Some(ImmutableValue::new(0)),
884            since_the_epoch.as_millis(),
885        );
886        assert_eq!(false, **changed2.read().unwrap());
887        property.raise_change_event(&event);
888        sleep(Duration::from_millis(100));
889        assert_eq!(true, **changed2.read().unwrap());
890    }
891
892    #[test]
893    fn property_change_event_test() {
894        let config = DefaultPropertyConfigBuilder::new()
895            .set_key(Box::new(1))
896            .set_default_value(Box::new(2))
897            .build();
898        let property = DefaultRawProperty::new(RawPropertyConfig::as_trait_ref(config.as_ref()));
899        let arc_property = Arc::new(RawProperty::to_boxed(property.clone()));
900        let start = SystemTime::now();
901        let since_the_epoch = start.duration_since(UNIX_EPOCH).unwrap();
902        let event = DefaultRawPropertyChangeEvent::new(
903            arc_property,
904            Some(ImmutableValue::new(0)),
905            Some(ImmutableValue::new(1)),
906            since_the_epoch.as_millis(),
907        );
908
909        assert_eq!(&event, &event.clone());
910        let boxed_event = RawPropertyChangeEvent::clone_boxed(&event);
911        assert_eq!(&boxed_event, &boxed_event.clone());
912
913        println!("property event: {:?}", event);
914        assert!(property.equals(event.get_raw_property().as_any_ref()));
915        assert_eq!(Some(Value::to_boxed(0)), event.get_raw_old_value());
916        assert_eq!(Some(Value::to_boxed(1)), event.get_raw_new_value());
917        assert_eq!(since_the_epoch.as_millis(), event.get_change_time());
918        assert_eq!(event, event.clone());
919
920        let event2 = DefaultPropertyChangeEvent::<i32, i32>::from_raw(&event);
921        println!("property event: {:?}", event2);
922        assert_eq!(&event2, &event2.clone());
923        let boxed_event2 = RawPropertyChangeEvent::clone_boxed(&event2);
924        assert_eq!(&boxed_event2, &boxed_event2.clone());
925        assert_eq!(1, *event2.get_property().get_config().get_key());
926        assert_eq!(Some(Value::to_boxed(0)), event2.get_raw_old_value());
927        assert_eq!(Some(Value::to_boxed(1)), event2.get_raw_new_value());
928        assert_eq!(Some(Box::new(0)), event2.get_old_value());
929        assert_eq!(Some(Box::new(1)), event2.get_new_value());
930        assert_eq!(since_the_epoch.as_millis(), event2.get_change_time());
931        assert_eq!(event2, event2.clone());
932    }
933}