Skip to content

Commit

Permalink
Add CastNone trait
Browse files Browse the repository at this point in the history
Closes gtk-rs#842
  • Loading branch information
ranfdev committed Dec 1, 2022
1 parent 543bc2f commit 2e8f18b
Showing 1 changed file with 49 additions and 0 deletions.
49 changes: 49 additions & 0 deletions glib/src/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,55 @@ pub trait Cast: ObjectType {

impl<T: ObjectType> Cast for T {}

// rustdoc-stripper-ignore-next
/// Convenience trait mirroring `Cast`, implemented on `Option<Object>` types.
pub trait CastNone: Sized {
type Inner;
fn downcast<T: ObjectType>(self) -> Result<T, Self>
where
Self::Inner: CanDowncast<T>;
fn downcast_ref<T: ObjectType>(&self) -> Option<&T>
where
Self::Inner: CanDowncast<T>;
fn upcast<T: ObjectType>(self) -> Option<T>
where
Self::Inner: IsA<T>;
fn upcast_ref<T: ObjectType>(&self) -> Option<&T>
where
Self::Inner: IsA<T>;
}
impl<I: ObjectType + Sized> CastNone for Option<I> {
type Inner = I;

fn downcast<T: ObjectType>(self) -> Result<T, Self>
where
Self::Inner: CanDowncast<T>,
{
self.ok_or(None)
.and_then(|i| i.downcast().map_err(|e| Some(e)))
}

fn downcast_ref<T: ObjectType>(&self) -> Option<&T>
where
Self::Inner: CanDowncast<T>,
{
self.as_ref().and_then(|i| i.downcast_ref())
}
fn upcast<T: ObjectType>(self) -> Option<T>
where
Self::Inner: IsA<T>,
{
self.map(|i| i.upcast())
}

fn upcast_ref<T: ObjectType>(&self) -> Option<&T>
where
Self::Inner: IsA<T>,
{
self.as_ref().map(|i| i.upcast_ref())
}
}

// rustdoc-stripper-ignore-next
/// Marker trait for the statically known possibility of downcasting from `Self` to `T`.
pub trait CanDowncast<T> {}
Expand Down

0 comments on commit 2e8f18b

Please sign in to comment.