Return a `Task<Result<()>>` in `{ItemView,Buffer,MultiBuffer}::save`

Antonio Scandurra created

Change summary

crates/diagnostics/src/diagnostics.rs |  2 +-
crates/editor/src/items.rs            | 10 ++++------
crates/editor/src/multi_buffer.rs     |  8 ++++----
crates/language/src/buffer.rs         | 15 ++++++++-------
crates/project/src/worktree.rs        |  6 +++---
crates/server/src/rpc.rs              |  3 +--
crates/workspace/src/workspace.rs     | 15 ++++++---------
7 files changed, 27 insertions(+), 32 deletions(-)

Detailed changes

crates/diagnostics/src/diagnostics.rs 🔗

@@ -560,7 +560,7 @@ impl workspace::ItemView for ProjectDiagnosticsEditor {
         true
     }
 
-    fn save(&mut self, cx: &mut ViewContext<Self>) -> Result<Task<Result<()>>> {
+    fn save(&mut self, cx: &mut ViewContext<Self>) -> Task<Result<()>> {
         self.excerpts.update(cx, |excerpts, cx| excerpts.save(cx))
     }
 

crates/editor/src/items.rs 🔗

@@ -160,20 +160,18 @@ impl ItemView for Editor {
         self.project_entry(cx).is_some()
     }
 
-    fn save(&mut self, cx: &mut ViewContext<Self>) -> Result<Task<Result<()>>> {
+    fn save(&mut self, cx: &mut ViewContext<Self>) -> Task<Result<()>> {
         let buffer = self.buffer().clone();
-        Ok(cx.spawn(|editor, mut cx| async move {
+        cx.spawn(|editor, mut cx| async move {
             buffer
                 .update(&mut cx, |buffer, cx| buffer.format(cx).log_err())
                 .await;
             editor.update(&mut cx, |editor, cx| {
                 editor.request_autoscroll(Autoscroll::Fit, cx)
             });
-            buffer
-                .update(&mut cx, |buffer, cx| buffer.save(cx))?
-                .await?;
+            buffer.update(&mut cx, |buffer, cx| buffer.save(cx)).await?;
             Ok(())
-        }))
+        })
     }
 
     fn can_save_as(&self, _: &AppContext) -> bool {

crates/editor/src/multi_buffer.rs 🔗

@@ -812,18 +812,18 @@ impl MultiBuffer {
         })
     }
 
-    pub fn save(&mut self, cx: &mut ModelContext<Self>) -> Result<Task<Result<()>>> {
+    pub fn save(&mut self, cx: &mut ModelContext<Self>) -> Task<Result<()>> {
         let mut save_tasks = Vec::new();
         for BufferState { buffer, .. } in self.buffers.borrow().values() {
-            save_tasks.push(buffer.update(cx, |buffer, cx| buffer.save(cx))?);
+            save_tasks.push(buffer.update(cx, |buffer, cx| buffer.save(cx)));
         }
 
-        Ok(cx.spawn(|_, _| async move {
+        cx.spawn(|_, _| async move {
             for save in save_tasks {
                 save.await?;
             }
             Ok(())
-        }))
+        })
     }
 
     pub fn language<'a>(&self, cx: &'a AppContext) -> Option<&'a Arc<Language>> {

crates/language/src/buffer.rs 🔗

@@ -510,21 +510,22 @@ impl Buffer {
     pub fn save(
         &mut self,
         cx: &mut ModelContext<Self>,
-    ) -> Result<Task<Result<(clock::Global, SystemTime)>>> {
-        let file = self
-            .file
-            .as_ref()
-            .ok_or_else(|| anyhow!("buffer has no file"))?;
+    ) -> Task<Result<(clock::Global, SystemTime)>> {
+        let file = if let Some(file) = self.file.as_ref() {
+            file
+        } else {
+            return Task::ready(Err(anyhow!("buffer has no file")));
+        };
         let text = self.as_rope().clone();
         let version = self.version();
         let save = file.save(self.remote_id(), text, version, cx.as_mut());
-        Ok(cx.spawn(|this, mut cx| async move {
+        cx.spawn(|this, mut cx| async move {
             let (version, mtime) = save.await?;
             this.update(&mut cx, |this, cx| {
                 this.did_save(version.clone(), mtime, None, cx);
             });
             Ok((version, mtime))
-        }))
+        })
     }
 
     pub fn set_language(&mut self, language: Option<Arc<Language>>, cx: &mut ModelContext<Self>) {

crates/project/src/worktree.rs 🔗

@@ -455,7 +455,7 @@ impl Worktree {
         let worktree_id = envelope.payload.worktree_id;
         let buffer_id = envelope.payload.buffer_id;
         let save = cx.spawn(|_, mut cx| async move {
-            buffer.update(&mut cx, |buffer, cx| buffer.save(cx))?.await
+            buffer.update(&mut cx, |buffer, cx| buffer.save(cx)).await
         });
 
         cx.background()
@@ -3094,7 +3094,7 @@ mod tests {
             .unwrap();
         let save = buffer.update(&mut cx, |buffer, cx| {
             buffer.edit(Some(0..0), "a line of text.\n".repeat(10 * 1024), cx);
-            buffer.save(cx).unwrap()
+            buffer.save(cx)
         });
         save.await.unwrap();
 
@@ -3132,7 +3132,7 @@ mod tests {
             .unwrap();
         let save = buffer.update(&mut cx, |buffer, cx| {
             buffer.edit(Some(0..0), "a line of text.\n".repeat(10 * 1024), cx);
-            buffer.save(cx).unwrap()
+            buffer.save(cx)
         });
         save.await.unwrap();
 

crates/server/src/rpc.rs 🔗

@@ -1474,7 +1474,7 @@ mod tests {
             .await;
 
         // Edit the buffer as the host and concurrently save as guest B.
-        let save_b = buffer_b.update(&mut cx_b, |buf, cx| buf.save(cx).unwrap());
+        let save_b = buffer_b.update(&mut cx_b, |buf, cx| buf.save(cx));
         buffer_a.update(&mut cx_a, |buf, cx| buf.edit([0..0], "hi-a, ", cx));
         save_b.await.unwrap();
         assert_eq!(
@@ -1591,7 +1591,6 @@ mod tests {
 
         buffer_b
             .update(&mut cx_b, |buf, cx| buf.save(cx))
-            .unwrap()
             .await
             .unwrap();
         worktree_b

crates/workspace/src/workspace.rs 🔗

@@ -168,14 +168,14 @@ pub trait ItemView: View {
         false
     }
     fn can_save(&self, cx: &AppContext) -> bool;
-    fn save(&mut self, cx: &mut ViewContext<Self>) -> Result<Task<Result<()>>>;
+    fn save(&mut self, cx: &mut ViewContext<Self>) -> Task<Result<()>>;
     fn can_save_as(&self, cx: &AppContext) -> bool;
     fn save_as(
         &mut self,
         project: ModelHandle<Project>,
         abs_path: PathBuf,
         cx: &mut ViewContext<Self>,
-    ) -> Task<anyhow::Result<()>>;
+    ) -> Task<Result<()>>;
     fn should_activate_item_on_event(_: &Self::Event) -> bool {
         false
     }
@@ -222,7 +222,7 @@ pub trait ItemViewHandle {
     fn has_conflict(&self, cx: &AppContext) -> bool;
     fn can_save(&self, cx: &AppContext) -> bool;
     fn can_save_as(&self, cx: &AppContext) -> bool;
-    fn save(&self, cx: &mut MutableAppContext) -> Result<Task<Result<()>>>;
+    fn save(&self, cx: &mut MutableAppContext) -> Task<Result<()>>;
     fn save_as(
         &self,
         project: ModelHandle<Project>,
@@ -377,7 +377,7 @@ impl<T: ItemView> ItemViewHandle for ViewHandle<T> {
         self.update(cx, |this, cx| this.navigate(data, cx));
     }
 
-    fn save(&self, cx: &mut MutableAppContext) -> Result<Task<Result<()>>> {
+    fn save(&self, cx: &mut MutableAppContext) -> Task<Result<()>> {
         self.update(cx, |item, cx| item.save(cx))
     }
 
@@ -822,15 +822,12 @@ impl Workspace {
                     cx.spawn(|_, mut cx| async move {
                         let answer = answer.recv().await;
                         if answer == Some(0) {
-                            cx.update(|cx| item.save(cx))?.await?;
+                            cx.update(|cx| item.save(cx)).await?;
                         }
                         Ok(())
                     })
                 } else {
-                    cx.spawn(|_, mut cx| async move {
-                        cx.update(|cx| item.save(cx))?.await?;
-                        Ok(())
-                    })
+                    item.save(cx)
                 }
             } else if item.can_save_as(cx) {
                 let worktree = self.worktrees(cx).first();