Skip to content

Commit 818a4a2

Browse files
committed
DynTypeContainer::try_take
1 parent cd78fbf commit 818a4a2

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed

fyrox-core/src/dyntype.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ impl std::error::Error for DynTypeError {}
8888
pub trait DynType: Reflect + Visit + Debug + FieldValue + Send {
8989
fn type_uuid(&self) -> Uuid;
9090
fn clone_box(&self) -> Box<dyn DynType>;
91+
fn into_any(self: Box<Self>) -> Box<dyn Any>;
9192
}
9293

9394
impl<T> DynType for T
@@ -101,6 +102,29 @@ where
101102
fn clone_box(&self) -> Box<dyn DynType> {
102103
Box::new(self.clone())
103104
}
105+
106+
fn into_any(self: Box<Self>) -> Box<dyn Any> {
107+
self
108+
}
109+
}
110+
111+
impl dyn DynType {
112+
pub fn downcast<T: DynType>(self: Box<dyn DynType>) -> Result<Box<T>, Box<dyn DynType>> {
113+
if self.is::<T>() {
114+
Ok(DynType::into_any(self).downcast().unwrap())
115+
} else {
116+
Err(self)
117+
}
118+
}
119+
120+
pub fn take<T: DynType>(self: Box<dyn DynType>) -> Result<T, Box<dyn DynType>> {
121+
self.downcast::<T>().map(|value| *value)
122+
}
123+
124+
#[inline]
125+
pub fn is<T: DynType>(&self) -> bool {
126+
self.type_id() == TypeId::of::<T>()
127+
}
104128
}
105129

106130
#[derive(Debug, TypeUuidProvider)]
@@ -218,6 +242,23 @@ impl Reflect for DynTypeWrapper {
218242
pub struct DynTypeContainer(pub Option<DynTypeWrapper>);
219243

220244
impl DynTypeContainer {
245+
pub fn try_take<T: DynType>(&mut self) -> Result<T, DynTypeError> {
246+
match self.0.take() {
247+
None => Err(DynTypeError::Empty),
248+
Some(wrapper) => match wrapper.0.take::<T>() {
249+
Ok(casted) => Ok(casted),
250+
Err(value) => {
251+
let actual_type_name = Reflect::type_name(&*value);
252+
self.0.replace(DynTypeWrapper(value));
253+
Err(DynTypeError::TypeCast {
254+
actual_type_name,
255+
requested_type_name: type_name::<T>(),
256+
})
257+
}
258+
},
259+
}
260+
}
261+
221262
pub fn value_ref(&self) -> Option<&dyn DynType> {
222263
self.0.as_ref().map(|v| &*v.0)
223264
}

0 commit comments

Comments
 (0)