Add downcast_ref to AnyViewHandle
Nathan Sobo
created 2 years ago
I use unsafe code to transmute an AnyViewHandle to a ViewHandle<T> when
the type matches. Because ViewHandle<T> is repr(transparent) to the
wrapped AnyViewHandle, this is safe.
Change summary
crates/file_finder/src/file_finder.rs | 3 +--
crates/gpui/src/app.rs | 9 +++++++++
crates/workspace/src/pane.rs | 3 +--
crates/zed/src/zed.rs | 12 ++++--------
4 files changed, 15 insertions(+), 12 deletions(-)
Detailed changes
@@ -353,8 +353,7 @@ mod tests {
assert_eq!(
active_item
.as_any()
- .clone()
- .downcast::<Editor>()
+ .downcast_ref::<Editor>()
.unwrap()
.read(cx)
.title(cx),
@@ -4661,6 +4661,7 @@ impl<T> Clone for WeakModelHandle<T> {
impl<T> Copy for WeakModelHandle<T> {}
+#[repr(transparent)]
pub struct ViewHandle<T> {
any_handle: AnyViewHandle,
view_type: PhantomData<T>,
@@ -4877,6 +4878,14 @@ impl AnyViewHandle {
}
}
+ pub fn downcast_ref<T: View>(&self) -> Option<&ViewHandle<T>> {
+ if self.is::<T>() {
+ Some(unsafe { mem::transmute(self) })
+ } else {
+ None
+ }
+ }
+
pub fn downgrade(&self) -> AnyWeakViewHandle {
AnyWeakViewHandle {
window_id: self.window_id,
@@ -2279,8 +2279,7 @@ mod tests {
.map(|(ix, item)| {
let mut state = item
.as_any()
- .clone()
- .downcast::<TestItem>()
+ .downcast_ref::<TestItem>()
.unwrap()
.read(cx)
.label
@@ -1021,8 +1021,7 @@ mod tests {
.active_item()
.unwrap()
.as_any()
- .clone()
- .downcast::<Editor>()
+ .downcast_ref::<Editor>()
.unwrap()
.read(cx)
.title(cx),
@@ -1058,8 +1057,7 @@ mod tests {
.active_item()
.unwrap()
.as_any()
- .clone()
- .downcast::<Editor>()
+ .downcast_ref::<Editor>()
.unwrap()
.read(cx)
.title(cx),
@@ -1095,8 +1093,7 @@ mod tests {
.active_item()
.unwrap()
.as_any()
- .clone()
- .downcast::<Editor>()
+ .downcast_ref::<Editor>()
.unwrap()
.read(cx)
.title(cx),
@@ -1146,8 +1143,7 @@ mod tests {
.active_item()
.unwrap()
.as_any()
- .clone()
- .downcast::<Editor>()
+ .downcast_ref::<Editor>()
.unwrap()
.read(cx)
.title(cx),