Skip to main content

ferroui_base/diagnostics/
ferro_object_extensions.rs

1//! Port of `Diagnostics/FerroObjectExtensions.cs` (with the parts of
2//! `FerroObject.GetDiagnosticInternal` and `ValueStore.GetDiagnostic` it
3//! is built on).
4
5use super::{FerroPropertyValue, ValueStoreDiagnostic};
6use crate::data::BindingPriority;
7use crate::{FerroObject, FerroProperty};
8
9/// Defines diagnostic extensions on [`FerroObject`]s.
10pub trait FerroObjectDiagnosticExtensions {
11    /// Gets a diagnostic for a [`FerroProperty`] on a [`FerroObject`]: a
12    /// [`FerroPropertyValue`] that can be used to diagnose the state of the
13    /// property on the object.
14    fn get_diagnostic(&self, property: &'static FerroProperty) -> FerroPropertyValue;
15
16    /// Gets a [`ValueStoreDiagnostic`]: the frames of values that are
17    /// applied to the object.
18    fn get_value_store_diagnostic(&self) -> ValueStoreDiagnostic;
19}
20
21impl FerroObjectDiagnosticExtensions for FerroObject {
22    fn get_diagnostic(&self, property: &'static FerroProperty) -> FerroPropertyValue {
23        // `FerroObject.GetDiagnosticInternal`
24        if property.is_direct() {
25            return FerroPropertyValue::new(
26                property,
27                self.get_value_untyped(property),
28                BindingPriority::LocalValue,
29                None,
30                false,
31            );
32        }
33
34        // `ValueStore.GetDiagnostic`: the effective value of the object, else
35        // the value it inherits, else the default value of the property.
36        let values = self.values();
37        let (value, priority, overridden) = match values.get_effective_value(property) {
38            Some(effective) => (effective.boxed_value(), effective.priority(), effective.is_overriden_current_value()),
39            None => {
40                let inherited =
41                    if property.inherits() { values.try_get_inherited_value(property) } else { None };
42                match inherited {
43                    Some(inherited) => (inherited.boxed_value(), BindingPriority::Inherited, false),
44                    None => (self.get_value_untyped(property), BindingPriority::Unset, false),
45                }
46            }
47        };
48
49        FerroPropertyValue::new(property, value, priority, None, overridden)
50    }
51
52    fn get_value_store_diagnostic(&self) -> ValueStoreDiagnostic {
53        self.values().get_store_diagnostic()
54    }
55}