Skip to content

Commit

Permalink
User defined types in Env
Browse files Browse the repository at this point in the history
  • Loading branch information
maan2003 committed Aug 10, 2021
1 parent acde646 commit 9970e55
Showing 1 changed file with 23 additions and 5 deletions.
28 changes: 23 additions & 5 deletions druid/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

//! An environment which is passed downward into the widget tree.

use std::any;
use std::any::{self, Any};
use std::borrow::Borrow;
use std::collections::{hash_map::Entry, HashMap};
use std::fmt::{Debug, Formatter};
Expand Down Expand Up @@ -92,11 +92,8 @@ pub struct Key<T> {
value_type: PhantomData<T>,
}

// we could do some serious deriving here: the set of types that can be stored
// could be defined per-app
// Also consider Box<Any> (though this would also impact debug).
/// A dynamic type representing all values that can be stored in an environment.
#[derive(Clone, Data, PartialEq)]
#[derive(Clone, Data)]
#[allow(missing_docs)]
// ANCHOR: value_type
pub enum Value {
Expand All @@ -110,6 +107,7 @@ pub enum Value {
UnsignedInt(u64),
String(ArcStr),
Font(FontDescriptor),
Other(Arc<dyn Any + Send + Sync>),
}
// ANCHOR_END: value_type

Expand Down Expand Up @@ -472,6 +470,7 @@ impl Debug for Value {
Value::UnsignedInt(x) => write!(f, "UnsignedInt {}", x),
Value::String(s) => write!(f, "String {:?}", s),
Value::Font(font) => write!(f, "Font {:?}", font),
Value::Other(other) => write!(f, "{:?}", other),
}
}
}
Expand Down Expand Up @@ -615,6 +614,25 @@ impl_value_type!(Insets, Insets);
impl_value_type!(ArcStr, String);
impl_value_type!(FontDescriptor, Font);

impl<T: 'static + Send + Sync> From<Arc<T>> for Value {
fn from(this: Arc<T>) -> Value {
Value::Other(this)
}
}

impl<T: 'static + Send + Sync> ValueType for Arc<T> {
fn try_from_value(v: &Value) -> Result<Self, ValueTypeError> {
let err = ValueTypeError {
expected: any::type_name::<T>(),
found: v.clone(),
};
match v {
Value::Other(o) => o.clone().downcast::<T>().map_err(|_| err),
_ => Err(err),
}
}
}

impl<T: ValueType> KeyOrValue<T> {
/// Resolve the concrete type `T` from this `KeyOrValue`, using the provided
/// [`Env`] if required.
Expand Down

0 comments on commit 9970e55

Please sign in to comment.