From 5a149b970c3f977266e991ad3bc97ac42228aa20 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Wed, 29 May 2024 18:06:45 -0700 Subject: [PATCH] Make tests less noisy (#12463) When running the tests for linux, I found a lot of benign errors getting logged. This PR cuts down some of the noise from unnecessary workspace serialization and SVG renders Release Notes: - N/A --- crates/assets/src/assets.rs | 9 ++-- crates/audio/src/assets.rs | 7 ++- crates/collab/src/tests/editor_tests.rs | 12 ++--- crates/collab/src/tests/test_server.rs | 16 ++---- crates/collab_ui/src/channel_view.rs | 6 ++- crates/diagnostics/src/diagnostics.rs | 2 +- crates/editor/src/editor.rs | 2 +- crates/editor/src/items.rs | 11 ++-- crates/editor/src/scroll.rs | 7 +-- crates/extensions_ui/src/extensions_ui.rs | 2 +- crates/file_icons/src/file_icons.rs | 9 ++-- crates/gpui/examples/animation.rs | 7 ++- crates/gpui/src/assets.rs | 11 ++-- crates/gpui/src/platform.rs | 4 +- crates/gpui/src/platform/blade/blade_atlas.rs | 12 +++-- crates/gpui/src/platform/mac/metal_atlas.rs | 12 +++-- crates/gpui/src/platform/test/window.rs | 23 ++++---- crates/gpui/src/svg_renderer.rs | 8 +-- crates/gpui/src/window.rs | 49 ++++++++++------- crates/image_viewer/src/image_viewer.rs | 26 ++++----- crates/language_tools/src/syntax_tree_view.rs | 2 +- crates/recent_projects/src/recent_projects.rs | 4 +- crates/search/src/project_search.rs | 2 +- .../src/project_index_debug_view.rs | 2 +- crates/storybook/src/assets.rs | 3 +- crates/storybook/src/storybook.rs | 5 +- crates/terminal_view/src/terminal_panel.rs | 6 ++- crates/terminal_view/src/terminal_view.rs | 39 +++++++------- crates/theme/src/registry.rs | 4 +- crates/theme_importer/src/assets.rs | 3 +- crates/welcome/src/welcome.rs | 2 +- crates/workspace/src/item.rs | 13 +++-- crates/workspace/src/shared_screen.rs | 2 +- crates/workspace/src/workspace.rs | 54 ++++++++++++------- crates/zed/src/main.rs | 2 +- crates/zed/src/zed.rs | 10 +++- 36 files changed, 216 insertions(+), 172 deletions(-) diff --git a/crates/assets/src/assets.rs b/crates/assets/src/assets.rs index b0a32a9d9c..d46cdb3a20 100644 --- a/crates/assets/src/assets.rs +++ b/crates/assets/src/assets.rs @@ -16,9 +16,9 @@ use rust_embed::RustEmbed; pub struct Assets; impl AssetSource for Assets { - fn load(&self, path: &str) -> Result> { + fn load(&self, path: &str) -> Result>> { Self::get(path) - .map(|f| f.data) + .map(|f| Some(f.data)) .ok_or_else(|| anyhow!("could not find asset at path \"{}\"", path)) } @@ -42,7 +42,10 @@ impl Assets { let mut embedded_fonts = Vec::new(); for font_path in font_paths { if font_path.ends_with(".ttf") { - let font_bytes = cx.asset_source().load(&font_path)?; + let font_bytes = cx + .asset_source() + .load(&font_path)? + .expect("Assets should never return None"); embedded_fonts.push(font_bytes); } } diff --git a/crates/audio/src/assets.rs b/crates/audio/src/assets.rs index 387990cb72..591f9ac9d6 100644 --- a/crates/audio/src/assets.rs +++ b/crates/audio/src/assets.rs @@ -41,7 +41,12 @@ impl SoundRegistry { } let path = format!("sounds/{}.wav", name); - let bytes = self.assets.load(&path)?.into_owned(); + let bytes = self + .assets + .load(&path)? + .map(|asset| Ok(asset)) + .unwrap_or_else(|| Err(anyhow::anyhow!("No such asset available")))? + .into_owned(); let cursor = Cursor::new(bytes); let source = Decoder::new(cursor)?.convert_samples::().buffered(); diff --git a/crates/collab/src/tests/editor_tests.rs b/crates/collab/src/tests/editor_tests.rs index 88146bae16..261fdcb165 100644 --- a/crates/collab/src/tests/editor_tests.rs +++ b/crates/collab/src/tests/editor_tests.rs @@ -42,7 +42,7 @@ use std::{ }, }; use text::Point; -use workspace::{Workspace, WorkspaceId}; +use workspace::Workspace; #[gpui::test(iterations = 10)] async fn test_host_disconnect( @@ -85,14 +85,8 @@ async fn test_host_disconnect( assert!(worktree_a.read_with(cx_a, |tree, _| tree.as_local().unwrap().is_shared())); - let workspace_b = cx_b.add_window(|cx| { - Workspace::new( - WorkspaceId::default(), - project_b.clone(), - client_b.app_state.clone(), - cx, - ) - }); + let workspace_b = cx_b + .add_window(|cx| Workspace::new(None, project_b.clone(), client_b.app_state.clone(), cx)); let cx_b = &mut VisualTestContext::from_window(*workspace_b, cx_b); let workspace_b_view = workspace_b.root_view(cx_b).unwrap(); diff --git a/crates/collab/src/tests/test_server.rs b/crates/collab/src/tests/test_server.rs index fc663cbc2d..275ef01438 100644 --- a/crates/collab/src/tests/test_server.rs +++ b/crates/collab/src/tests/test_server.rs @@ -42,7 +42,7 @@ use std::{ Arc, }, }; -use workspace::{Workspace, WorkspaceId, WorkspaceStore}; +use workspace::{Workspace, WorkspaceStore}; pub struct TestServer { pub app_state: Arc, @@ -906,12 +906,7 @@ impl TestClient { ) -> (View, &'a mut VisualTestContext) { cx.add_window_view(|cx| { cx.activate_window(); - Workspace::new( - WorkspaceId::default(), - project.clone(), - self.app_state.clone(), - cx, - ) + Workspace::new(None, project.clone(), self.app_state.clone(), cx) }) } @@ -922,12 +917,7 @@ impl TestClient { let project = self.build_test_project(cx).await; cx.add_window_view(|cx| { cx.activate_window(); - Workspace::new( - WorkspaceId::default(), - project.clone(), - self.app_state.clone(), - cx, - ) + Workspace::new(None, project.clone(), self.app_state.clone(), cx) }) } diff --git a/crates/collab_ui/src/channel_view.rs b/crates/collab_ui/src/channel_view.rs index 59099dd486..d62f86419a 100644 --- a/crates/collab_ui/src/channel_view.rs +++ b/crates/collab_ui/src/channel_view.rs @@ -400,7 +400,11 @@ impl Item for ChannelView { None } - fn clone_on_split(&self, _: WorkspaceId, cx: &mut ViewContext) -> Option> { + fn clone_on_split( + &self, + _: Option, + cx: &mut ViewContext, + ) -> Option> { Some(cx.new_view(|cx| { Self::new( self.project.clone(), diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index a590ed9d92..4d81629723 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -704,7 +704,7 @@ impl Item for ProjectDiagnosticsEditor { fn clone_on_split( &self, - _workspace_id: workspace::WorkspaceId, + _workspace_id: Option, cx: &mut ViewContext, ) -> Option> where diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 67f0d0908a..bca2a060b6 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -484,7 +484,7 @@ pub struct Editor { current_line_highlight: CurrentLineHighlight, collapse_matches: bool, autoindent_mode: Option, - workspace: Option<(WeakView, WorkspaceId)>, + workspace: Option<(WeakView, Option)>, keymap_context_layers: BTreeMap, input_enabled: bool, use_modal_editing: bool, diff --git a/crates/editor/src/items.rs b/crates/editor/src/items.rs index 268c62a054..2d5ea9be7f 100644 --- a/crates/editor/src/items.rs +++ b/crates/editor/src/items.rs @@ -657,7 +657,7 @@ impl Item for Editor { fn clone_on_split( &self, - _workspace_id: WorkspaceId, + _workspace_id: Option, cx: &mut ViewContext, ) -> Option> where @@ -846,9 +846,12 @@ impl Item for Editor { } fn added_to_workspace(&mut self, workspace: &mut Workspace, cx: &mut ViewContext) { - let workspace_id = workspace.database_id(); - let item_id = cx.view().item_id().as_u64() as ItemId; self.workspace = Some((workspace.weak_handle(), workspace.database_id())); + let Some(workspace_id) = workspace.database_id() else { + return; + }; + + let item_id = cx.view().item_id().as_u64() as ItemId; fn serialize( buffer: Model, @@ -873,7 +876,7 @@ impl Item for Editor { serialize(buffer.clone(), workspace_id, item_id, cx); cx.subscribe(&buffer, |this, buffer, event, cx| { - if let Some((_, workspace_id)) = this.workspace.as_ref() { + if let Some((_, Some(workspace_id))) = this.workspace.as_ref() { if let language::Event::FileHandleChanged = event { serialize( buffer, diff --git a/crates/editor/src/scroll.rs b/crates/editor/src/scroll.rs index 1107c97022..095c9e9845 100644 --- a/crates/editor/src/scroll.rs +++ b/crates/editor/src/scroll.rs @@ -389,7 +389,8 @@ impl Editor { cx: &mut ViewContext, ) { hide_hover(self, cx); - let workspace_id = self.workspace.as_ref().map(|workspace| workspace.1); + let workspace_id = self.workspace.as_ref().and_then(|workspace| workspace.1); + self.scroll_manager.set_scroll_position( scroll_position, &display_map, @@ -409,7 +410,7 @@ impl Editor { pub fn set_scroll_anchor(&mut self, scroll_anchor: ScrollAnchor, cx: &mut ViewContext) { hide_hover(self, cx); - let workspace_id = self.workspace.as_ref().map(|workspace| workspace.1); + let workspace_id = self.workspace.as_ref().and_then(|workspace| workspace.1); let top_row = scroll_anchor .anchor .to_point(&self.buffer().read(cx).snapshot(cx)) @@ -424,7 +425,7 @@ impl Editor { cx: &mut ViewContext, ) { hide_hover(self, cx); - let workspace_id = self.workspace.as_ref().map(|workspace| workspace.1); + let workspace_id = self.workspace.as_ref().and_then(|workspace| workspace.1); let snapshot = &self.buffer().read(cx).snapshot(cx); if !scroll_anchor.anchor.is_valid(snapshot) { log::warn!("Invalid scroll anchor: {:?}", scroll_anchor); diff --git a/crates/extensions_ui/src/extensions_ui.rs b/crates/extensions_ui/src/extensions_ui.rs index c60b28e61d..0ec675d46f 100644 --- a/crates/extensions_ui/src/extensions_ui.rs +++ b/crates/extensions_ui/src/extensions_ui.rs @@ -992,7 +992,7 @@ impl Item for ExtensionsPage { fn clone_on_split( &self, - _workspace_id: WorkspaceId, + _workspace_id: Option, _: &mut ViewContext, ) -> Option> { None diff --git a/crates/file_icons/src/file_icons.rs b/crates/file_icons/src/file_icons.rs index 63e8558e06..ff653e6693 100644 --- a/crates/file_icons/src/file_icons.rs +++ b/crates/file_icons/src/file_icons.rs @@ -38,11 +38,10 @@ impl FileIcons { pub fn new(assets: impl AssetSource) -> Self { assets .load("icons/file_icons/file_types.json") - .and_then(|file| { - serde_json::from_str::(str::from_utf8(&file).unwrap()) - .map_err(Into::into) - }) - .unwrap_or_else(|_| FileIcons { + .ok() + .flatten() + .and_then(|file| serde_json::from_str::(str::from_utf8(&file).unwrap()).ok()) + .unwrap_or_else(|| FileIcons { stems: HashMap::default(), suffixes: HashMap::default(), types: HashMap::default(), diff --git a/crates/gpui/examples/animation.rs b/crates/gpui/examples/animation.rs index f3d8f56eda..a672d3b0d6 100644 --- a/crates/gpui/examples/animation.rs +++ b/crates/gpui/examples/animation.rs @@ -5,8 +5,11 @@ use gpui::*; struct Assets {} impl AssetSource for Assets { - fn load(&self, path: &str) -> Result> { - std::fs::read(path).map(Into::into).map_err(Into::into) + fn load(&self, path: &str) -> Result>> { + std::fs::read(path) + .map(Into::into) + .map_err(Into::into) + .map(|result| Some(result)) } fn list(&self, path: &str) -> Result> { diff --git a/crates/gpui/src/assets.rs b/crates/gpui/src/assets.rs index dd7485a30a..a5072c45a1 100644 --- a/crates/gpui/src/assets.rs +++ b/crates/gpui/src/assets.rs @@ -1,5 +1,5 @@ use crate::{size, DevicePixels, Result, SharedString, Size}; -use anyhow::anyhow; + use image::{Bgra, ImageBuffer}; use std::{ borrow::Cow, @@ -11,18 +11,15 @@ use std::{ /// A source of assets for this app to use. pub trait AssetSource: 'static + Send + Sync { /// Load the given asset from the source path. - fn load(&self, path: &str) -> Result>; + fn load(&self, path: &str) -> Result>>; /// List the assets at the given path. fn list(&self, path: &str) -> Result>; } impl AssetSource for () { - fn load(&self, path: &str) -> Result> { - Err(anyhow!( - "load called on empty asset provider with \"{}\"", - path - )) + fn load(&self, _path: &str) -> Result>> { + Ok(None) } fn list(&self, _path: &str) -> Result> { diff --git a/crates/gpui/src/platform.rs b/crates/gpui/src/platform.rs index 11ba6af6c8..a806109287 100644 --- a/crates/gpui/src/platform.rs +++ b/crates/gpui/src/platform.rs @@ -344,8 +344,8 @@ pub(crate) trait PlatformAtlas: Send + Sync { fn get_or_insert_with<'a>( &self, key: &AtlasKey, - build: &mut dyn FnMut() -> Result<(Size, Cow<'a, [u8]>)>, - ) -> Result; + build: &mut dyn FnMut() -> Result, Cow<'a, [u8]>)>>, + ) -> Result>; } #[derive(Clone, Debug, PartialEq, Eq)] diff --git a/crates/gpui/src/platform/blade/blade_atlas.rs b/crates/gpui/src/platform/blade/blade_atlas.rs index f2cdb7e957..d42b1e4285 100644 --- a/crates/gpui/src/platform/blade/blade_atlas.rs +++ b/crates/gpui/src/platform/blade/blade_atlas.rs @@ -114,18 +114,20 @@ impl PlatformAtlas for BladeAtlas { fn get_or_insert_with<'a>( &self, key: &AtlasKey, - build: &mut dyn FnMut() -> Result<(Size, Cow<'a, [u8]>)>, - ) -> Result { + build: &mut dyn FnMut() -> Result, Cow<'a, [u8]>)>>, + ) -> Result> { let mut lock = self.0.lock(); if let Some(tile) = lock.tiles_by_key.get(key) { - Ok(tile.clone()) + Ok(Some(tile.clone())) } else { profiling::scope!("new tile"); - let (size, bytes) = build()?; + let Some((size, bytes)) = build()? else { + return Ok(None); + }; let tile = lock.allocate(size, key.texture_kind()); lock.upload_texture(tile.texture_id, tile.bounds, &bytes); lock.tiles_by_key.insert(key.clone(), tile.clone()); - Ok(tile) + Ok(Some(tile)) } } } diff --git a/crates/gpui/src/platform/mac/metal_atlas.rs b/crates/gpui/src/platform/mac/metal_atlas.rs index 49dd38c109..89a6987752 100644 --- a/crates/gpui/src/platform/mac/metal_atlas.rs +++ b/crates/gpui/src/platform/mac/metal_atlas.rs @@ -60,20 +60,22 @@ impl PlatformAtlas for MetalAtlas { fn get_or_insert_with<'a>( &self, key: &AtlasKey, - build: &mut dyn FnMut() -> Result<(Size, Cow<'a, [u8]>)>, - ) -> Result { + build: &mut dyn FnMut() -> Result, Cow<'a, [u8]>)>>, + ) -> Result> { let mut lock = self.0.lock(); if let Some(tile) = lock.tiles_by_key.get(key) { - Ok(tile.clone()) + Ok(Some(tile.clone())) } else { - let (size, bytes) = build()?; + let Some((size, bytes)) = build()? else { + return Ok(None); + }; let tile = lock .allocate(size, key.texture_kind()) .ok_or_else(|| anyhow!("failed to allocate"))?; let texture = lock.texture(tile.texture_id); texture.upload(tile.bounds, &bytes); lock.tiles_by_key.insert(key.clone(), tile.clone()); - Ok(tile) + Ok(Some(tile)) } } } diff --git a/crates/gpui/src/platform/test/window.rs b/crates/gpui/src/platform/test/window.rs index 3b48ea6d87..cd7196a291 100644 --- a/crates/gpui/src/platform/test/window.rs +++ b/crates/gpui/src/platform/test/window.rs @@ -291,25 +291,26 @@ impl PlatformAtlas for TestAtlas { fn get_or_insert_with<'a>( &self, key: &crate::AtlasKey, - build: &mut dyn FnMut() -> anyhow::Result<( - Size, - std::borrow::Cow<'a, [u8]>, - )>, - ) -> anyhow::Result { + build: &mut dyn FnMut() -> anyhow::Result< + Option<(Size, std::borrow::Cow<'a, [u8]>)>, + >, + ) -> anyhow::Result> { let mut state = self.0.lock(); if let Some(tile) = state.tiles.get(key) { - return Ok(tile.clone()); + return Ok(Some(tile.clone())); } + drop(state); + let Some((size, _)) = build()? else { + return Ok(None); + }; + + let mut state = self.0.lock(); state.next_id += 1; let texture_id = state.next_id; state.next_id += 1; let tile_id = state.next_id; - drop(state); - let (size, _) = build()?; - let mut state = self.0.lock(); - state.tiles.insert( key.clone(), crate::AtlasTile { @@ -326,6 +327,6 @@ impl PlatformAtlas for TestAtlas { }, ); - Ok(state.tiles[key].clone()) + Ok(Some(state.tiles[key].clone())) } } diff --git a/crates/gpui/src/svg_renderer.rs b/crates/gpui/src/svg_renderer.rs index 54f52a55a8..0074cdc355 100644 --- a/crates/gpui/src/svg_renderer.rs +++ b/crates/gpui/src/svg_renderer.rs @@ -24,13 +24,15 @@ impl SvgRenderer { Self { asset_source } } - pub fn render(&self, params: &RenderSvgParams) -> Result> { + pub fn render(&self, params: &RenderSvgParams) -> Result>> { if params.size.is_zero() { return Err(anyhow!("can't render at a zero size")); } // Load the tree. - let bytes = self.asset_source.load(¶ms.path)?; + let Some(bytes) = self.asset_source.load(¶ms.path)? else { + return Ok(None); + }; let pixmap = self.render_pixmap(&bytes, SvgSize::Size(params.size))?; @@ -40,7 +42,7 @@ impl SvgRenderer { .iter() .map(|p| p.alpha()) .collect::>(); - Ok(alpha_mask) + Ok(Some(alpha_mask)) } pub fn render_pixmap(&self, bytes: &[u8], size: SvgSize) -> Result { diff --git a/crates/gpui/src/window.rs b/crates/gpui/src/window.rs index 253bb36396..7c2ce490d4 100644 --- a/crates/gpui/src/window.rs +++ b/crates/gpui/src/window.rs @@ -2347,13 +2347,14 @@ impl<'a> WindowContext<'a> { let raster_bounds = self.text_system().raster_bounds(¶ms)?; if !raster_bounds.is_zero() { - let tile = - self.window - .sprite_atlas - .get_or_insert_with(¶ms.clone().into(), &mut || { - let (size, bytes) = self.text_system().rasterize_glyph(¶ms)?; - Ok((size, Cow::Owned(bytes))) - })?; + let tile = self + .window + .sprite_atlas + .get_or_insert_with(¶ms.clone().into(), &mut || { + let (size, bytes) = self.text_system().rasterize_glyph(¶ms)?; + Ok(Some((size, Cow::Owned(bytes)))) + })? + .expect("Callback above only errors or returns Some"); let bounds = Bounds { origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into), size: tile.bounds.size.map(Into::into), @@ -2410,13 +2411,15 @@ impl<'a> WindowContext<'a> { let raster_bounds = self.text_system().raster_bounds(¶ms)?; if !raster_bounds.is_zero() { - let tile = - self.window - .sprite_atlas - .get_or_insert_with(¶ms.clone().into(), &mut || { - let (size, bytes) = self.text_system().rasterize_glyph(¶ms)?; - Ok((size, Cow::Owned(bytes))) - })?; + let tile = self + .window + .sprite_atlas + .get_or_insert_with(¶ms.clone().into(), &mut || { + let (size, bytes) = self.text_system().rasterize_glyph(¶ms)?; + Ok(Some((size, Cow::Owned(bytes)))) + })? + .expect("Callback above only errors or returns Some"); + let bounds = Bounds { origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into), size: tile.bounds.size.map(Into::into), @@ -2464,13 +2467,18 @@ impl<'a> WindowContext<'a> { .map(|pixels| DevicePixels::from((pixels.0 * 2.).ceil() as i32)), }; - let tile = + let Some(tile) = self.window .sprite_atlas .get_or_insert_with(¶ms.clone().into(), &mut || { - let bytes = self.svg_renderer.render(¶ms)?; - Ok((params.size, Cow::Owned(bytes))) - })?; + let Some(bytes) = self.svg_renderer.render(¶ms)? else { + return Ok(None); + }; + Ok(Some((params.size, Cow::Owned(bytes)))) + })? + else { + return Ok(()); + }; let content_mask = self.content_mask().scale(scale_factor); self.window @@ -2513,8 +2521,9 @@ impl<'a> WindowContext<'a> { .window .sprite_atlas .get_or_insert_with(¶ms.clone().into(), &mut || { - Ok((data.size(), Cow::Borrowed(data.as_bytes()))) - })?; + Ok(Some((data.size(), Cow::Borrowed(data.as_bytes())))) + })? + .expect("Callback above only returns Some"); let content_mask = self.content_mask().scale(scale_factor); let corner_radii = corner_radii.scale(scale_factor); diff --git a/crates/image_viewer/src/image_viewer.rs b/crates/image_viewer/src/image_viewer.rs index ec7cf222ba..8c03a5d5f2 100644 --- a/crates/image_viewer/src/image_viewer.rs +++ b/crates/image_viewer/src/image_viewer.rs @@ -95,17 +95,19 @@ impl Item for ImageView { let workspace_id = workspace.database_id(); let image_path = self.path.clone(); - cx.background_executor() - .spawn({ - let image_path = image_path.clone(); - async move { - IMAGE_VIEWER - .save_image_path(item_id, workspace_id, image_path) - .await - .log_err(); - } - }) - .detach(); + if let Some(workspace_id) = workspace_id { + cx.background_executor() + .spawn({ + let image_path = image_path.clone(); + async move { + IMAGE_VIEWER + .save_image_path(item_id, workspace_id, image_path) + .await + .log_err(); + } + }) + .detach(); + } } fn serialized_item_kind() -> Option<&'static str> { @@ -133,7 +135,7 @@ impl Item for ImageView { fn clone_on_split( &self, - _workspace_id: WorkspaceId, + _workspace_id: Option, cx: &mut ViewContext, ) -> Option> where diff --git a/crates/language_tools/src/syntax_tree_view.rs b/crates/language_tools/src/syntax_tree_view.rs index f4cd38f2ca..aef7f258d2 100644 --- a/crates/language_tools/src/syntax_tree_view.rs +++ b/crates/language_tools/src/syntax_tree_view.rs @@ -407,7 +407,7 @@ impl Item for SyntaxTreeView { fn clone_on_split( &self, - _: workspace::WorkspaceId, + _: Option, cx: &mut ViewContext, ) -> Option> where diff --git a/crates/recent_projects/src/recent_projects.rs b/crates/recent_projects/src/recent_projects.rs index 3c49fa3d96..9c1ce8b477 100644 --- a/crates/recent_projects/src/recent_projects.rs +++ b/crates/recent_projects/src/recent_projects.rs @@ -287,7 +287,7 @@ impl PickerDelegate for RecentProjectsDelegate { }; workspace .update(cx, |workspace, cx| { - if workspace.database_id() == *candidate_workspace_id { + if workspace.database_id() == Some(*candidate_workspace_id) { Task::ready(Ok(())) } else { match candidate_workspace_location { @@ -675,7 +675,7 @@ impl RecentProjectsDelegate { ) -> bool { if let Some(workspace) = self.workspace.upgrade() { let workspace = workspace.read(cx); - if workspace_id == workspace.database_id() { + if Some(workspace_id) == workspace.database_id() { return true; } } diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index f302fe3c49..d2d51868cf 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -456,7 +456,7 @@ impl Item for ProjectSearchView { fn clone_on_split( &self, - _workspace_id: WorkspaceId, + _workspace_id: Option, cx: &mut ViewContext, ) -> Option> where diff --git a/crates/semantic_index/src/project_index_debug_view.rs b/crates/semantic_index/src/project_index_debug_view.rs index 2ffd23aaf2..1b183c5169 100644 --- a/crates/semantic_index/src/project_index_debug_view.rs +++ b/crates/semantic_index/src/project_index_debug_view.rs @@ -283,7 +283,7 @@ impl Item for ProjectIndexDebugView { fn clone_on_split( &self, - _: workspace::WorkspaceId, + _: Option, cx: &mut ViewContext, ) -> Option> where diff --git a/crates/storybook/src/assets.rs b/crates/storybook/src/assets.rs index c8dbe9ec60..a2d57cebff 100644 --- a/crates/storybook/src/assets.rs +++ b/crates/storybook/src/assets.rs @@ -15,10 +15,11 @@ use rust_embed::RustEmbed; pub struct Assets; impl AssetSource for Assets { - fn load(&self, path: &str) -> Result> { + fn load(&self, path: &str) -> Result>> { Self::get(path) .map(|f| f.data) .ok_or_else(|| anyhow!("could not find asset at path \"{}\"", path)) + .map(|data| Some(data)) } fn list(&self, path: &str) -> Result> { diff --git a/crates/storybook/src/storybook.rs b/crates/storybook/src/storybook.rs index cb3498c179..9458ef4bd6 100644 --- a/crates/storybook/src/storybook.rs +++ b/crates/storybook/src/storybook.rs @@ -128,7 +128,10 @@ fn load_embedded_fonts(cx: &AppContext) -> gpui::Result<()> { let mut embedded_fonts = Vec::new(); for font_path in font_paths { if font_path.ends_with(".ttf") { - let font_bytes = cx.asset_source().load(&font_path)?; + let font_bytes = cx + .asset_source() + .load(&font_path)? + .expect("Should never be None in the storybook"); embedded_fonts.push(font_bytes); } } diff --git a/crates/terminal_view/src/terminal_panel.rs b/crates/terminal_view/src/terminal_panel.rs index 1084d54ab4..c37225d48b 100644 --- a/crates/terminal_view/src/terminal_panel.rs +++ b/crates/terminal_view/src/terminal_panel.rs @@ -221,7 +221,9 @@ impl TerminalPanel { let (panel, pane, items) = workspace.update(&mut cx, |workspace, cx| { let panel = cx.new_view(|cx| TerminalPanel::new(workspace, cx)); - let items = if let Some(serialized_panel) = serialized_panel.as_ref() { + let items = if let Some((serialized_panel, database_id)) = + serialized_panel.as_ref().zip(workspace.database_id()) + { panel.update(cx, |panel, cx| { cx.notify(); panel.height = serialized_panel.height.map(|h| h.round()); @@ -234,7 +236,7 @@ impl TerminalPanel { TerminalView::deserialize( workspace.project().clone(), workspace.weak_handle(), - workspace.database_id(), + database_id, *item_id, cx, ) diff --git a/crates/terminal_view/src/terminal_view.rs b/crates/terminal_view/src/terminal_view.rs index d2348eb96c..0bc0a609a0 100644 --- a/crates/terminal_view/src/terminal_view.rs +++ b/crates/terminal_view/src/terminal_view.rs @@ -91,7 +91,7 @@ pub struct TerminalView { blinking_paused: bool, blink_epoch: usize, can_navigate_to_selected_word: bool, - workspace_id: WorkspaceId, + workspace_id: Option, show_title: bool, _subscriptions: Vec, _terminal_subscriptions: Vec, @@ -142,7 +142,7 @@ impl TerminalView { pub fn new( terminal: Model, workspace: WeakView, - workspace_id: WorkspaceId, + workspace_id: Option, cx: &mut ViewContext, ) -> Self { let workspace_handle = workspace.clone(); @@ -458,15 +458,16 @@ fn subscribe_for_terminal_events( if terminal.task().is_none() { if let Some(cwd) = terminal.get_cwd() { let item_id = cx.entity_id(); - let workspace_id = this.workspace_id; - cx.background_executor() - .spawn(async move { - TERMINAL_DB - .save_working_directory(item_id.as_u64(), workspace_id, cwd) - .await - .log_err(); - }) - .detach(); + if let Some(workspace_id) = this.workspace_id { + cx.background_executor() + .spawn(async move { + TERMINAL_DB + .save_working_directory(item_id.as_u64(), workspace_id, cwd) + .await + .log_err(); + }) + .detach(); + } } } } @@ -853,7 +854,7 @@ impl Item for TerminalView { fn clone_on_split( &self, - _workspace_id: WorkspaceId, + _workspace_id: Option, _cx: &mut ViewContext, ) -> Option> { //From what I can tell, there's no way to tell the current working @@ -941,20 +942,18 @@ impl Item for TerminalView { project.create_terminal(cwd, None, window, cx) })??; pane.update(&mut cx, |_, cx| { - cx.new_view(|cx| TerminalView::new(terminal, workspace, workspace_id, cx)) + cx.new_view(|cx| TerminalView::new(terminal, workspace, Some(workspace_id), cx)) }) }) } fn added_to_workspace(&mut self, workspace: &mut Workspace, cx: &mut ViewContext) { if self.terminal().read(cx).task().is_none() { - cx.background_executor() - .spawn(TERMINAL_DB.update_workspace_id( - workspace.database_id(), - self.workspace_id, - cx.entity_id().as_u64(), - )) - .detach(); + if let Some((new_id, old_id)) = workspace.database_id().zip(self.workspace_id) { + cx.background_executor() + .spawn(TERMINAL_DB.update_workspace_id(new_id, old_id, cx.entity_id().as_u64())) + .detach(); + } self.workspace_id = workspace.database_id(); } } diff --git a/crates/theme/src/registry.rs b/crates/theme/src/registry.rs index 5a89ce4fc5..6e13df6045 100644 --- a/crates/theme/src/registry.rs +++ b/crates/theme/src/registry.rs @@ -1,5 +1,5 @@ -use std::path::Path; use std::sync::Arc; +use std::{fmt::Debug, path::Path}; use anyhow::{anyhow, Context, Result}; use collections::HashMap; @@ -226,7 +226,7 @@ impl ThemeRegistry { .filter(|path| path.ends_with(".json")); for path in theme_paths { - let Some(theme) = self.assets.load(&path).log_err() else { + let Some(theme) = self.assets.load(&path).log_err().flatten() else { continue; }; diff --git a/crates/theme_importer/src/assets.rs b/crates/theme_importer/src/assets.rs index 171912f6b8..e80150fbaf 100644 --- a/crates/theme_importer/src/assets.rs +++ b/crates/theme_importer/src/assets.rs @@ -11,10 +11,11 @@ use rust_embed::RustEmbed; pub struct Assets; impl AssetSource for Assets { - fn load(&self, path: &str) -> Result> { + fn load(&self, path: &str) -> Result>> { Self::get(path) .map(|f| f.data) .ok_or_else(|| anyhow!("could not find asset at path \"{}\"", path)) + .map(|result| Some(result)) } fn list(&self, path: &str) -> Result> { diff --git a/crates/welcome/src/welcome.rs b/crates/welcome/src/welcome.rs index 3ae07cda68..5145b8e264 100644 --- a/crates/welcome/src/welcome.rs +++ b/crates/welcome/src/welcome.rs @@ -313,7 +313,7 @@ impl Item for WelcomePage { fn clone_on_split( &self, - _workspace_id: WorkspaceId, + _workspace_id: Option, cx: &mut ViewContext, ) -> Option> { Some(cx.new_view(|cx| WelcomePage { diff --git a/crates/workspace/src/item.rs b/crates/workspace/src/item.rs index 68bae37e4e..5956fdd0f9 100644 --- a/crates/workspace/src/item.rs +++ b/crates/workspace/src/item.rs @@ -172,7 +172,7 @@ pub trait Item: FocusableView + EventEmitter { fn set_nav_history(&mut self, _: ItemNavHistory, _: &mut ViewContext) {} fn clone_on_split( &self, - _workspace_id: WorkspaceId, + _workspace_id: Option, _: &mut ViewContext, ) -> Option> where @@ -287,7 +287,7 @@ pub trait ItemHandle: 'static + Send { fn boxed_clone(&self) -> Box; fn clone_on_split( &self, - workspace_id: WorkspaceId, + workspace_id: Option, cx: &mut WindowContext, ) -> Option>; fn added_to_pane( @@ -437,7 +437,7 @@ impl ItemHandle for View { fn clone_on_split( &self, - workspace_id: WorkspaceId, + workspace_id: Option, cx: &mut WindowContext, ) -> Option> { self.update(cx, |item, cx| item.clone_on_split(workspace_id, cx)) @@ -528,7 +528,6 @@ impl ItemHandle for View { { pane } else { - log::error!("unexpected item event after pane was dropped"); return; }; @@ -883,7 +882,7 @@ pub mod test { } pub struct TestItem { - pub workspace_id: WorkspaceId, + pub workspace_id: Option, pub state: String, pub label: String, pub save_count: usize, @@ -964,7 +963,7 @@ pub mod test { pub fn new_deserialized(id: WorkspaceId, cx: &mut ViewContext) -> Self { let mut this = Self::new(cx); - this.workspace_id = id; + this.workspace_id = Some(id); this } @@ -1081,7 +1080,7 @@ pub mod test { fn clone_on_split( &self, - _workspace_id: WorkspaceId, + _workspace_id: Option, cx: &mut ViewContext, ) -> Option> where diff --git a/crates/workspace/src/shared_screen.rs b/crates/workspace/src/shared_screen.rs index a1b8c2eee3..63dc4ad84c 100644 --- a/crates/workspace/src/shared_screen.rs +++ b/crates/workspace/src/shared_screen.rs @@ -119,7 +119,7 @@ impl Item for SharedScreen { fn clone_on_split( &self, - _workspace_id: WorkspaceId, + _workspace_id: Option, cx: &mut ViewContext, ) -> Option> { let track = self.track.upgrade()?; diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 82be2e9194..d4989d0d58 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -588,7 +588,7 @@ pub struct Workspace { window_edited: bool, active_call: Option<(Model, Vec)>, leader_updates_tx: mpsc::UnboundedSender<(PeerId, proto::UpdateFollowers)>, - database_id: WorkspaceId, + database_id: Option, app_state: Arc, dispatching_keystrokes: Rc>>, _subscriptions: Vec, @@ -622,7 +622,7 @@ impl Workspace { const MAX_PADDING: f32 = 0.4; pub fn new( - workspace_id: WorkspaceId, + workspace_id: Option, project: Model, app_state: Arc, cx: &mut ViewContext, @@ -795,13 +795,15 @@ impl Workspace { if let Some(display) = cx.display() { if let Some(display_uuid) = display.uuid().log_err() { let window_bounds = cx.window_bounds(); - cx.background_executor() - .spawn(DB.set_window_open_status( - workspace_id, - SerializedWindowBounds(window_bounds), - display_uuid, - )) - .detach_and_log_err(cx); + if let Some(database_id) = workspace_id { + cx.background_executor() + .spawn(DB.set_window_open_status( + database_id, + SerializedWindowBounds(window_bounds), + display_uuid, + )) + .detach_and_log_err(cx); + } } } this.bounds_save_task_queued.take(); @@ -956,7 +958,12 @@ impl Workspace { let window = if let Some(window) = requesting_window { cx.update_window(window.into(), |_, cx| { cx.replace_root_view(|cx| { - Workspace::new(workspace_id, project_handle.clone(), app_state.clone(), cx) + Workspace::new( + Some(workspace_id), + project_handle.clone(), + app_state.clone(), + cx, + ) }); })?; window @@ -994,7 +1001,7 @@ impl Workspace { move |cx| { cx.new_view(|cx| { let mut workspace = - Workspace::new(workspace_id, project_handle, app_state, cx); + Workspace::new(Some(workspace_id), project_handle, app_state, cx); workspace.centered_layout = centered_layout; workspace }) @@ -3464,9 +3471,12 @@ impl Workspace { pub fn on_window_activation_changed(&mut self, cx: &mut ViewContext) { if cx.is_window_active() { self.update_active_view_for_followers(cx); - cx.background_executor() - .spawn(persistence::DB.update_timestamp(self.database_id())) - .detach(); + + if let Some(database_id) = self.database_id { + cx.background_executor() + .spawn(persistence::DB.update_timestamp(database_id)) + .detach(); + } } else { for pane in &self.panes { pane.update(cx, |pane, cx| { @@ -3506,7 +3516,7 @@ impl Workspace { } } - pub fn database_id(&self) -> WorkspaceId { + pub fn database_id(&self) -> Option { self.database_id } @@ -3566,6 +3576,10 @@ impl Workspace { } fn serialize_workspace_internal(&self, cx: &mut WindowContext) -> Task<()> { + let Some(database_id) = self.database_id() else { + return Task::ready(()); + }; + fn serialize_pane_handle(pane_handle: &View, cx: &WindowContext) -> SerializedPane { let (items, active) = { let pane = pane_handle.read(cx); @@ -3701,7 +3715,7 @@ impl Workspace { let docks = build_serialized_docks(self, cx); let window_bounds = Some(SerializedWindowBounds(cx.window_bounds())); let serialized_workspace = SerializedWorkspace { - id: self.database_id, + id: database_id, location, center_group, window_bounds, @@ -3944,9 +3958,11 @@ impl Workspace { pub fn toggle_centered_layout(&mut self, _: &ToggleCenteredLayout, cx: &mut ViewContext) { self.centered_layout = !self.centered_layout; - cx.background_executor() - .spawn(DB.set_centered_layout(self.database_id, self.centered_layout)) - .detach_and_log_err(cx); + if let Some(database_id) = self.database_id() { + cx.background_executor() + .spawn(DB.set_centered_layout(database_id, self.centered_layout)) + .detach_and_log_err(cx); + } cx.notify(); } diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index ae9e0bfc6b..fe93df3380 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -832,7 +832,7 @@ fn load_embedded_fonts(cx: &AppContext) { } scope.spawn(async { - let font_bytes = asset_source.load(font_path).unwrap(); + let font_bytes = asset_source.load(font_path).unwrap().unwrap(); embedded_fonts.lock().push(font_bytes); }); } diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 9b5f3179da..6150ca383f 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -3043,8 +3043,14 @@ mod tests { fn test_bundled_settings_and_themes(cx: &mut AppContext) { cx.text_system() .add_fonts(vec![ - Assets.load("fonts/zed-sans/zed-sans-extended.ttf").unwrap(), - Assets.load("fonts/zed-mono/zed-mono-extended.ttf").unwrap(), + Assets + .load("fonts/zed-sans/zed-sans-extended.ttf") + .unwrap() + .unwrap(), + Assets + .load("fonts/zed-mono/zed-mono-extended.ttf") + .unwrap() + .unwrap(), ]) .unwrap(); let themes = ThemeRegistry::default();