ferroui_base/data/core/
weak_value.rs1use super::value_type::value_type_id;
2use super::ValueTypes;
3use crate::{AnyValue, BoxedValue, FerroObject, WeakRef};
4use std::any::TypeId;
5use std::rc::{Rc, Weak};
6
7#[derive(Clone)]
15pub enum WeakValue {
16 Reference(Weak<dyn AnyValue>),
18 Object(WeakRef<FerroObject>, TypeId),
20 Value(BoxedValue),
22}
23
24impl PartialEq for WeakValue {
27 fn eq(&self, other: &Self) -> bool {
28 match (self, other) {
29 (WeakValue::Reference(a), WeakValue::Reference(b)) => std::ptr::addr_eq(a.as_ptr(), b.as_ptr()),
30 (WeakValue::Object(a, a_id), WeakValue::Object(b, b_id)) => a.ptr_eq(b) && a_id == b_id,
31 (WeakValue::Value(a), WeakValue::Value(b)) => **a == **b,
32 _ => false,
33 }
34 }
35}
36
37impl WeakValue {
38 pub fn new(value: &BoxedValue) -> Self {
39 let id = value_type_id(&**value);
40 if let Some(object) = ValueTypes::as_object(&**value) {
41 WeakValue::Object(object.downgrade(), id)
42 } else if ValueTypes::is_reference(id) {
43 WeakValue::Reference(Rc::downgrade(value))
44 } else {
45 WeakValue::Value(value.clone())
46 }
47 }
48
49 pub fn upgrade(&self) -> Option<BoxedValue> {
51 match self {
52 WeakValue::Reference(weak) => weak.upgrade(),
53 WeakValue::Object(weak, id) => weak.upgrade().and_then(|o| ValueTypes::from_object(*id, o)),
54 WeakValue::Value(value) => Some(value.clone()),
55 }
56 }
57}