pub struct PropertyChain<S, V> { /* private fields */ }Expand description
A path from an object to a value through properties, any step of which may be null (the
expression of WhenPropertyChanged and WhenValueChanged, split into its
ObservablePropertyParts).
Its value is None when a step is null (upstream’s UnobtainableValue). Each step that
notifies its changes is observed on the object it is read from; when a step changes, the
steps after it are observed again on the new objects, and none is observed past a null step.
use ferroui_dynamic_data::binding::PropertyChain;
use ferroui_system::component_model::{INotifyPropertyChanged, PropertyPath};
use ferroui_system::events::Event;
use std::cell::{Cell, RefCell};
use std::rc::Rc;
struct Child { age: Cell<i32>, changed: Event<str> }
impl Child { fn age(&self) -> i32 { self.age.get() } }
impl INotifyPropertyChanged for Child { fn property_changed(&self) -> &Event<str> { &self.changed } }
struct Parent { child: RefCell<Option<Rc<Child>>>, changed: Event<str> }
impl Parent { fn child(&self) -> Option<Rc<Child>> { self.child.borrow().clone() } }
impl INotifyPropertyChanged for Parent { fn property_changed(&self) -> &Event<str> { &self.changed } }
// x => x.Child!.Age
let chain = PropertyChain::nullable(ferroui_system::prop!(Parent => child)).then(ferroui_system::prop!(Child => age));
let parent = Rc::new(Parent { child: RefCell::new(None), changed: Event::new() });
assert_eq!(chain.get(&parent), None);
*parent.child.borrow_mut() = Some(Rc::new(Child { age: Cell::new(3), changed: Event::new() }));
assert_eq!(chain.get(&parent), Some(3));
assert_eq!(chain.path(), "Child.Age");Implementations§
Source§impl<S: 'static, V: 'static> PropertyChain<S, V>
impl<S: 'static, V: 'static> PropertyChain<S, V>
Sourcepub fn new(path: PropertyPath<S, V>) -> Self
pub fn new(path: PropertyPath<S, V>) -> Self
The chain of a path whose steps are never null.
Sourcepub fn nullable(path: PropertyPath<S, Option<V>>) -> Self
pub fn nullable(path: PropertyPath<S, Option<V>>) -> Self
The chain of a path whose last step may be null (x => x.Child!): its value is None
when the step is.
Sourcepub fn get(&self, source: &S) -> Option<V>
pub fn get(&self, source: &S) -> Option<V>
The value of the chain on source; None when a step is null (the walk of
ReadCurrent).
Sourcepub fn observe(&self, source: &S, changed: Rc<dyn Fn()>) -> Rc<dyn IDisposable>
pub fn observe(&self, source: &S, changed: Rc<dyn Fn()>) -> Rc<dyn IDisposable>
Runs changed whenever the value of the chain on source may have changed, until the
result is disposed (the subscriptions of the levels of DeepChainSubscription).
Sourcepub fn then<P: IntoPropertyChain<V>>(
self,
next: P,
) -> PropertyChain<S, P::Value>
pub fn then<P: IntoPropertyChain<V>>( self, next: P, ) -> PropertyChain<S, P::Value>
The chain that continues with next from the value of this one (x => x.A.B): when the
object of this step changes, the steps of next are observed on the new object, and on
none when it is null.
Sourcepub fn then_nullable<W: 'static>(
self,
next: PropertyPath<V, Option<W>>,
) -> PropertyChain<S, W>
pub fn then_nullable<W: 'static>( self, next: PropertyPath<V, Option<W>>, ) -> PropertyChain<S, W>
then with a step that may be null (x => x.A!.B).
Sourcepub fn map<W: 'static>(
self,
convert: impl Fn(V) -> W + 'static,
) -> PropertyChain<S, W>
pub fn map<W: 'static>( self, convert: impl Fn(V) -> W + 'static, ) -> PropertyChain<S, W>
The chain whose value is converted by convert (an expression’s Convert node, such as
x => (decimal)x.Amount or x => ((IHasAge)x.Child).Age); the steps observed are the
same.