Use try_global() (#4112)

Joseph T. Lyons created

Use `try_global()` in places where we are using the "if global exists,
then give me the global" pattern.

Release Notes:

- N/A

Change summary

crates/auto_update/src/auto_update.rs         | 37 ++++++++++----------
crates/client/src/telemetry.rs                |  8 +--
crates/copilot/src/copilot.rs                 |  6 --
crates/feature_flags/src/feature_flags.rs     | 16 +++-----
crates/project_panel/src/file_associations.rs |  6 +-
crates/semantic_index/src/semantic_index.rs   |  7 +--
crates/vim/src/mode_indicator.rs              |  5 +-
crates/workspace/src/item.rs                  | 10 +---
crates/workspace/src/workspace.rs             | 11 ++---
crates/zed/src/main.rs                        | 16 +++++---
10 files changed, 52 insertions(+), 70 deletions(-)

Detailed changes

crates/auto_update/src/auto_update.rs 🔗

@@ -145,17 +145,16 @@ pub fn view_release_notes(_: &ViewReleaseNotes, cx: &mut AppContext) {
         let auto_updater = auto_updater.read(cx);
         let server_url = &auto_updater.server_url;
         let current_version = auto_updater.current_version;
-        if cx.has_global::<ReleaseChannel>() {
-            match cx.global::<ReleaseChannel>() {
-                ReleaseChannel::Dev => {}
-                ReleaseChannel::Nightly => {}
-                ReleaseChannel::Preview => {
-                    cx.open_url(&format!("{server_url}/releases/preview/{current_version}"))
-                }
-                ReleaseChannel::Stable => {
-                    cx.open_url(&format!("{server_url}/releases/stable/{current_version}"))
-                }
-            }
+
+        if let Some(release_channel) = cx.try_global::<ReleaseChannel>() {
+            let channel = match release_channel {
+                ReleaseChannel::Preview => "preview",
+                ReleaseChannel::Stable => "stable",
+                _ => return,
+            };
+            cx.open_url(&format!(
+                "{server_url}/releases/{channel}/{current_version}"
+            ))
         }
     }
 }
@@ -257,11 +256,13 @@ impl AutoUpdater {
             "{server_url}/api/releases/latest?token={ZED_SECRET_CLIENT_TOKEN}&asset=Zed.dmg"
         );
         cx.update(|cx| {
-            if cx.has_global::<ReleaseChannel>() {
-                if let Some(param) = cx.global::<ReleaseChannel>().release_query_param() {
-                    url_string += "&";
-                    url_string += param;
-                }
+            if let Some(param) = cx
+                .try_global::<ReleaseChannel>()
+                .map(|release_channel| release_channel.release_query_param())
+                .flatten()
+            {
+                url_string += "&";
+                url_string += param;
             }
         })?;
 
@@ -313,8 +314,8 @@ impl AutoUpdater {
         let (installation_id, release_channel, telemetry) = cx.update(|cx| {
             let installation_id = cx.global::<Arc<Client>>().telemetry().installation_id();
             let release_channel = cx
-                .has_global::<ReleaseChannel>()
-                .then(|| cx.global::<ReleaseChannel>().display_name());
+                .try_global::<ReleaseChannel>()
+                .map(|release_channel| release_channel.display_name());
             let telemetry = TelemetrySettings::get_global(cx).metrics;
 
             (installation_id, release_channel, telemetry)

crates/client/src/telemetry.rs 🔗

@@ -150,11 +150,9 @@ const FLUSH_INTERVAL: Duration = Duration::from_secs(60 * 5);
 
 impl Telemetry {
     pub fn new(client: Arc<dyn HttpClient>, cx: &mut AppContext) -> Arc<Self> {
-        let release_channel = if cx.has_global::<ReleaseChannel>() {
-            Some(cx.global::<ReleaseChannel>().display_name())
-        } else {
-            None
-        };
+        let release_channel = cx
+            .try_global::<ReleaseChannel>()
+            .map(|release_channel| release_channel.display_name());
 
         TelemetrySettings::register(cx);
 

crates/copilot/src/copilot.rs 🔗

@@ -308,11 +308,7 @@ impl EventEmitter<Event> for Copilot {}
 
 impl Copilot {
     pub fn global(cx: &AppContext) -> Option<Model<Self>> {
-        if cx.has_global::<Model<Self>>() {
-            Some(cx.global::<Model<Self>>().clone())
-        } else {
-            None
-        }
+        cx.try_global::<Model<Self>>().map(|model| model.clone())
     }
 
     fn start(

crates/feature_flags/src/feature_flags.rs 🔗

@@ -57,18 +57,14 @@ impl FeatureFlagAppExt for AppContext {
     }
 
     fn has_flag<T: FeatureFlag>(&self) -> bool {
-        if self.has_global::<FeatureFlags>() {
-            self.global::<FeatureFlags>().has_flag(T::NAME)
-        } else {
-            false
-        }
+        self.try_global::<FeatureFlags>()
+            .map(|flags| flags.has_flag(T::NAME))
+            .unwrap_or(false)
     }
 
     fn is_staff(&self) -> bool {
-        if self.has_global::<FeatureFlags>() {
-            return self.global::<FeatureFlags>().staff;
-        } else {
-            false
-        }
+        self.try_global::<FeatureFlags>()
+            .map(|flags| flags.staff)
+            .unwrap_or(false)
     }
 }

crates/project_panel/src/file_associations.rs 🔗

@@ -42,7 +42,7 @@ impl FileAssociations {
     }
 
     pub fn get_icon(path: &Path, cx: &AppContext) -> Option<Arc<str>> {
-        let this = cx.has_global::<Self>().then(|| cx.global::<Self>())?;
+        let this = cx.try_global::<Self>()?;
 
         // FIXME: Associate a type with the languages and have the file's language
         //        override these associations
@@ -58,7 +58,7 @@ impl FileAssociations {
     }
 
     pub fn get_folder_icon(expanded: bool, cx: &AppContext) -> Option<Arc<str>> {
-        let this = cx.has_global::<Self>().then(|| cx.global::<Self>())?;
+        let this = cx.try_global::<Self>()?;
 
         let key = if expanded {
             EXPANDED_DIRECTORY_TYPE
@@ -72,7 +72,7 @@ impl FileAssociations {
     }
 
     pub fn get_chevron_icon(expanded: bool, cx: &AppContext) -> Option<Arc<str>> {
-        let this = cx.has_global::<Self>().then(|| cx.global::<Self>())?;
+        let this = cx.try_global::<Self>()?;
 
         let key = if expanded {
             EXPANDED_CHEVRON_TYPE

crates/semantic_index/src/semantic_index.rs 🔗

@@ -275,11 +275,8 @@ pub struct SearchResult {
 
 impl SemanticIndex {
     pub fn global(cx: &mut AppContext) -> Option<Model<SemanticIndex>> {
-        if cx.has_global::<Model<Self>>() {
-            Some(cx.global::<Model<SemanticIndex>>().clone())
-        } else {
-            None
-        }
+        cx.try_global::<Model<Self>>()
+            .map(|semantic_index| semantic_index.clone())
     }
 
     pub fn authenticate(&mut self, cx: &mut AppContext) -> bool {

crates/vim/src/mode_indicator.rs 🔗

@@ -28,11 +28,10 @@ impl ModeIndicator {
 
     fn update_mode(&mut self, cx: &mut ViewContext<Self>) {
         // Vim doesn't exist in some tests
-        if !cx.has_global::<Vim>() {
+        let Some(vim) = cx.try_global::<Vim>() else {
             return;
-        }
+        };
 
-        let vim = Vim::read(cx);
         if vim.enabled {
             self.mode = Some(vim.state().mode);
         } else {

crates/workspace/src/item.rs 🔗

@@ -586,13 +586,9 @@ impl<T: Item> ItemHandle for View<T> {
     }
 
     fn to_followable_item_handle(&self, cx: &AppContext) -> Option<Box<dyn FollowableItemHandle>> {
-        if cx.has_global::<FollowableItemBuilders>() {
-            let builders = cx.global::<FollowableItemBuilders>();
-            let item = self.to_any();
-            Some(builders.get(&item.entity_type())?.1(&item))
-        } else {
-            None
-        }
+        let builders = cx.try_global::<FollowableItemBuilders>()?;
+        let item = self.to_any();
+        Some(builders.get(&item.entity_type())?.1(&item))
     }
 
     fn on_release(

crates/workspace/src/workspace.rs 🔗

@@ -616,8 +616,8 @@ impl Workspace {
         let modal_layer = cx.new_view(|_| ModalLayer::new());
 
         let mut active_call = None;
-        if cx.has_global::<Model<ActiveCall>>() {
-            let call = cx.global::<Model<ActiveCall>>().clone();
+        if let Some(call) = cx.try_global::<Model<ActiveCall>>() {
+            let call = call.clone();
             let mut subscriptions = Vec::new();
             subscriptions.push(cx.subscribe(&call, Self::on_active_call_event));
             active_call = Some((call, subscriptions));
@@ -3686,11 +3686,8 @@ impl WorkspaceStore {
         update: proto::update_followers::Variant,
         cx: &AppContext,
     ) -> Option<()> {
-        if !cx.has_global::<Model<ActiveCall>>() {
-            return None;
-        }
-
-        let room_id = ActiveCall::global(cx).read(cx).room()?.read(cx).id();
+        let active_call = cx.try_global::<Model<ActiveCall>>()?;
+        let room_id = active_call.read(cx).room()?.read(cx).id();
         let follower_ids: Vec<_> = self
             .followers
             .iter()

crates/zed/src/main.rs 🔗

@@ -102,13 +102,15 @@ fn main() {
     let open_listener = listener.clone();
     app.on_open_urls(move |urls, _| open_listener.open_urls(&urls));
     app.on_reopen(move |cx| {
-        if cx.has_global::<Weak<AppState>>() {
-            if let Some(app_state) = cx.global::<Weak<AppState>>().upgrade() {
-                workspace::open_new(&app_state, cx, |workspace, cx| {
-                    Editor::new_file(workspace, &Default::default(), cx)
-                })
-                .detach();
-            }
+        if let Some(app_state) = cx
+            .try_global::<Weak<AppState>>()
+            .map(|app_state| app_state.upgrade())
+            .flatten()
+        {
+            workspace::open_new(&app_state, cx, |workspace, cx| {
+                Editor::new_file(workspace, &Default::default(), cx)
+            })
+            .detach();
         }
     });