2019-02-28 23:54:12 +00:00
|
|
|
use crate::view::View;
|
2019-03-01 00:04:14 +00:00
|
|
|
use std::any::Any;
|
2018-03-14 22:11:27 +00:00
|
|
|
|
|
|
|
/// A view that can be downcasted to its concrete type.
|
|
|
|
///
|
|
|
|
/// This trait is automatically implemented for any `T: View`.
|
|
|
|
pub trait AnyView {
|
|
|
|
/// Downcast self to a `Any`.
|
2019-02-28 23:55:02 +00:00
|
|
|
fn as_any(&self) -> &dyn Any;
|
2018-03-14 22:11:27 +00:00
|
|
|
|
|
|
|
/// Downcast self to a mutable `Any`.
|
2019-02-28 23:55:02 +00:00
|
|
|
fn as_any_mut(&mut self) -> &mut dyn Any;
|
2018-03-14 22:11:27 +00:00
|
|
|
|
|
|
|
/// Returns a boxed any from a boxed self.
|
|
|
|
///
|
|
|
|
/// Can be used before `Box::downcast()`.
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```rust
|
2020-04-15 19:20:50 +00:00
|
|
|
/// # use cursive_core::views::TextView;
|
|
|
|
/// # use cursive_core::view::View;
|
2018-03-14 22:11:27 +00:00
|
|
|
/// let boxed: Box<View> = Box::new(TextView::new("text"));
|
|
|
|
/// let text: Box<TextView> = boxed.as_boxed_any().downcast().unwrap();
|
|
|
|
/// ```
|
2019-02-28 23:55:02 +00:00
|
|
|
fn as_boxed_any(self: Box<Self>) -> Box<dyn Any>;
|
2018-03-14 22:11:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: View> AnyView for T {
|
|
|
|
/// Downcast self to a `Any`.
|
2019-02-28 23:55:02 +00:00
|
|
|
fn as_any(&self) -> &dyn Any {
|
2018-03-14 22:11:27 +00:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Downcast self to a mutable `Any`.
|
2019-02-28 23:55:02 +00:00
|
|
|
fn as_any_mut(&mut self) -> &mut dyn Any {
|
2018-03-14 22:11:27 +00:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2019-02-28 23:55:02 +00:00
|
|
|
fn as_boxed_any(self: Box<Self>) -> Box<dyn Any> {
|
2018-03-14 22:11:27 +00:00
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|
2019-04-09 00:44:36 +00:00
|
|
|
|
|
|
|
impl dyn AnyView {
|
|
|
|
/// Attempts to downcast `self` to a concrete type.
|
|
|
|
pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
|
|
|
|
self.as_any().downcast_ref()
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Attempts to downcast `self` to a concrete type.
|
|
|
|
pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
|
|
|
|
self.as_any_mut().downcast_mut()
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Attempts to downcast `Box<Self>` to a concrete type.
|
|
|
|
pub fn downcast<T: Any>(self: Box<Self>) -> Result<Box<T>, Box<Self>> {
|
|
|
|
// Do the check here + unwrap, so the error
|
|
|
|
// value is `Self` and not `dyn Any`.
|
|
|
|
if self.as_any().is::<T>() {
|
|
|
|
Ok(self.as_boxed_any().downcast().unwrap())
|
|
|
|
} else {
|
|
|
|
Err(self)
|
|
|
|
}
|
|
|
|
}
|
2020-03-03 21:08:55 +00:00
|
|
|
|
|
|
|
/// Checks if this view is of type `T`.
|
|
|
|
pub fn is<T: Any>(&mut self) -> bool {
|
|
|
|
self.as_any().is::<T>()
|
|
|
|
}
|
2019-04-09 00:44:36 +00:00
|
|
|
}
|