Allow FollowableItem::to_state_message to return None

This way, we can avoid a panic if we don't handle certain cases,
like a non-singleton editor.
This commit is contained in:
Max Brunsfeld 2022-03-18 13:36:05 -07:00
parent df0632011c
commit d860ed25c1
2 changed files with 17 additions and 21 deletions

View file

@ -50,21 +50,15 @@ impl FollowableItem for Editor {
})) }))
} }
fn to_state_message(&self, cx: &AppContext) -> proto::view::Variant { fn to_state_message(&self, cx: &AppContext) -> Option<proto::view::Variant> {
let buffer_id = self let buffer_id = self.buffer.read(cx).as_singleton()?.read(cx).remote_id();
.buffer Some(proto::view::Variant::Editor(proto::view::Editor {
.read(cx)
.as_singleton()
.unwrap()
.read(cx)
.remote_id();
proto::view::Variant::Editor(proto::view::Editor {
buffer_id, buffer_id,
scroll_top: self scroll_top: self
.scroll_top_anchor .scroll_top_anchor
.as_ref() .as_ref()
.map(|anchor| language::proto::serialize_anchor(&anchor.text_anchor)), .map(|anchor| language::proto::serialize_anchor(&anchor.text_anchor)),
}) }))
} }
fn to_update_message( fn to_update_message(

View file

@ -247,7 +247,7 @@ pub trait FollowableItem: Item {
state: &mut Option<proto::view::Variant>, state: &mut Option<proto::view::Variant>,
cx: &mut MutableAppContext, cx: &mut MutableAppContext,
) -> Option<Task<Result<ViewHandle<Self>>>>; ) -> Option<Task<Result<ViewHandle<Self>>>>;
fn to_state_message(&self, cx: &AppContext) -> proto::view::Variant; fn to_state_message(&self, cx: &AppContext) -> Option<proto::view::Variant>;
fn to_update_message( fn to_update_message(
&self, &self,
event: &Self::Event, event: &Self::Event,
@ -261,7 +261,7 @@ pub trait FollowableItem: Item {
} }
pub trait FollowableItemHandle: ItemHandle { pub trait FollowableItemHandle: ItemHandle {
fn to_state_message(&self, cx: &AppContext) -> proto::view::Variant; fn to_state_message(&self, cx: &AppContext) -> Option<proto::view::Variant>;
fn to_update_message( fn to_update_message(
&self, &self,
event: &dyn Any, event: &dyn Any,
@ -275,7 +275,7 @@ pub trait FollowableItemHandle: ItemHandle {
} }
impl<T: FollowableItem> FollowableItemHandle for ViewHandle<T> { impl<T: FollowableItem> FollowableItemHandle for ViewHandle<T> {
fn to_state_message(&self, cx: &AppContext) -> proto::view::Variant { fn to_state_message(&self, cx: &AppContext) -> Option<proto::view::Variant> {
self.read(cx).to_state_message(cx) self.read(cx).to_state_message(cx)
} }
@ -381,14 +381,16 @@ impl<T: Item> ItemHandle for ViewHandle<T> {
cx: &mut ViewContext<Workspace>, cx: &mut ViewContext<Workspace>,
) { ) {
if let Some(followed_item) = self.to_followable_item_handle(cx) { if let Some(followed_item) = self.to_followable_item_handle(cx) {
if let Some(message) = followed_item.to_state_message(cx) {
workspace.update_followers( workspace.update_followers(
proto::update_followers::Variant::CreateView(proto::View { proto::update_followers::Variant::CreateView(proto::View {
id: followed_item.id() as u64, id: followed_item.id() as u64,
variant: Some(followed_item.to_state_message(cx)), variant: Some(message),
}), }),
cx, cx,
); );
} }
}
let pane = pane.downgrade(); let pane = pane.downgrade();
cx.subscribe(self, move |workspace, item, event, cx| { cx.subscribe(self, move |workspace, item, event, cx| {
@ -1523,7 +1525,7 @@ impl Workspace {
.filter_map(|item| { .filter_map(|item| {
let id = item.id() as u64; let id = item.id() as u64;
let item = item.to_followable_item_handle(cx)?; let item = item.to_followable_item_handle(cx)?;
let variant = item.to_state_message(cx); let variant = item.to_state_message(cx)?;
Some(proto::View { Some(proto::View {
id, id,
variant: Some(variant), variant: Some(variant),