Skip to main content

ferroui_base/data/core/
i_binding_expression_sink.rs

1use crate::data::BindingExpressionBase;
2use crate::{FerroObject, WeakRef};
3use std::rc::{Rc, Weak};
4
5/// Receives the notifications of a binding expression.
6pub(crate) trait IBindingExpressionSink {
7    /// Called when a binding expression's value or error state changes.
8    fn on_changed(&self, instance: &Rc<dyn BindingExpressionBase>, has_value_changed: bool, has_error_changed: bool);
9
10    /// Called when a binding expression completes.
11    fn on_completed(&self, instance: &Rc<dyn BindingExpressionBase>);
12}
13
14/// A non-owning reference to a binding expression sink: the value store of
15/// an object, or another sink (an observable adapter or a parent
16/// expression).
17#[derive(Clone)]
18pub enum SinkRef {
19    #[doc(hidden)]
20    Store(WeakRef<FerroObject>),
21    #[doc(hidden)]
22    #[allow(private_interfaces)]
23    Other(Weak<dyn IBindingExpressionSink>),
24}
25
26impl SinkRef {
27    pub(crate) fn on_changed(
28        &self,
29        instance: &Rc<dyn BindingExpressionBase>,
30        has_value_changed: bool,
31        has_error_changed: bool,
32    ) {
33        match self {
34            SinkRef::Store(owner) => {
35                if let Some(owner) = owner.upgrade() {
36                    owner.values().on_expression_changed(&owner, instance, has_value_changed, has_error_changed);
37                }
38            }
39            SinkRef::Other(sink) => {
40                if let Some(sink) = sink.upgrade() {
41                    sink.on_changed(instance, has_value_changed, has_error_changed);
42                }
43            }
44        }
45    }
46
47    pub(crate) fn on_completed(&self, instance: &Rc<dyn BindingExpressionBase>) {
48        match self {
49            SinkRef::Store(owner) => {
50                if let Some(owner) = owner.upgrade() {
51                    owner.values().on_expression_completed(&owner, instance);
52                }
53            }
54            SinkRef::Other(sink) => {
55                if let Some(sink) = sink.upgrade() {
56                    sink.on_completed(instance);
57                }
58            }
59        }
60    }
61}