Create a DapSettingsContent type and remove optionals from DapSettings

Anthony created

I did to fix the todo! for the DapSettings and make it more consistent
with how the rest of settings are now defined

Change summary

crates/language_models/src/provider/vercel.rs   |  2 
crates/language_models/src/settings.rs          |  1 
crates/project/src/debugger/dap_store.rs        | 12 ++++--
crates/project/src/project_settings.rs          | 33 ++++++++++++++++--
crates/settings/src/settings_content/project.rs |  6 +-
5 files changed, 40 insertions(+), 14 deletions(-)

Detailed changes

crates/language_models/src/provider/vercel.rs 🔗

@@ -29,7 +29,7 @@ const PROVIDER_NAME: LanguageModelProviderName = LanguageModelProviderName::new(
 const API_KEY_ENV_VAR_NAME: &str = "VERCEL_API_KEY";
 static API_KEY_ENV_VAR: LazyLock<EnvVar> = env_var!(API_KEY_ENV_VAR_NAME);
 
-#[derive(Default, Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq)]
 pub struct VercelSettings {
     pub api_url: String,
     pub available_models: Vec<AvailableModel>,

crates/language_models/src/settings.rs 🔗

@@ -18,7 +18,6 @@ pub fn init_settings(cx: &mut App) {
     AllLanguageModelSettings::register(cx);
 }
 
-#[derive(Default)]
 pub struct AllLanguageModelSettings {
     pub anthropic: AnthropicSettings,
     pub bedrock: AmazonBedrockSettings,

crates/project/src/debugger/dap_store.rs 🔗

@@ -5,8 +5,10 @@ use super::{
     session::{self, Session, SessionStateEvent},
 };
 use crate::{
-    InlayHint, InlayHintLabel, ProjectEnvironment, ResolveState, debugger::session::SessionQuirks,
-    project_settings::ProjectSettings, worktree_store::WorktreeStore,
+    InlayHint, InlayHintLabel, ProjectEnvironment, ResolveState,
+    debugger::session::SessionQuirks,
+    project_settings::{DapBinary, ProjectSettings},
+    worktree_store::WorktreeStore,
 };
 use anyhow::{Context as _, Result, anyhow};
 use async_trait::async_trait;
@@ -209,8 +211,10 @@ impl DapStore {
                 let dap_settings = ProjectSettings::get(Some(settings_location), cx)
                     .dap
                     .get(&adapter.name());
-                let user_installed_path =
-                    dap_settings.and_then(|s| s.binary.as_ref().map(PathBuf::from));
+                let user_installed_path = dap_settings.and_then(|s| match &s.binary {
+                    DapBinary::Default => None,
+                    DapBinary::Custom(binary) => Some(PathBuf::from(binary)),
+                });
                 let user_args = dap_settings.map(|s| s.args.clone());
 
                 let delegate = self.delegate(worktree, console, cx);

crates/project/src/project_settings.rs 🔗

@@ -20,8 +20,8 @@ use serde::{Deserialize, Serialize};
 pub use settings::DirenvSettings;
 pub use settings::LspSettings;
 use settings::{
-    InvalidSettingsError, LocalSettingsKind, Settings, SettingsLocation, SettingsStore, SettingsUi,
-    parse_json_with_comments, watch_config_file,
+    DapSettingsContent, InvalidSettingsError, LocalSettingsKind, Settings, SettingsLocation,
+    SettingsStore, SettingsUi, parse_json_with_comments, watch_config_file,
 };
 use std::{
     path::{Path, PathBuf},
@@ -54,7 +54,7 @@ pub struct ProjectSettings {
     pub global_lsp_settings: GlobalLspSettings,
 
     /// Configuration for Debugger-related features
-    pub dap: HashMap<DebugAdapterName, settings::DapSettings>,
+    pub dap: HashMap<DebugAdapterName, DapSettings>,
 
     /// Settings for context servers used for AI-related features.
     pub context_servers: HashMap<Arc<str>, ContextServerSettings>,
@@ -494,7 +494,7 @@ impl Settings for ProjectSettings {
                 .dap
                 .clone()
                 .into_iter()
-                .map(|(key, value)| (DebugAdapterName(key.into()), value))
+                .map(|(key, value)| (DebugAdapterName(key.into()), DapSettings::from(value)))
                 .collect(),
             diagnostics: DiagnosticsSettings {
                 button: diagnostics.button.unwrap(),
@@ -534,7 +534,7 @@ impl Settings for ProjectSettings {
                 .dap
                 .clone()
                 .into_iter()
-                .map(|(key, value)| (DebugAdapterName(key.into()), value)),
+                .map(|(key, value)| (DebugAdapterName(key.into()), DapSettings::from(value))),
         );
         if let Some(diagnostics) = content.diagnostics.as_ref() {
             if let Some(inline) = &diagnostics.inline {
@@ -1326,3 +1326,26 @@ pub fn local_settings_kind_to_proto(kind: LocalSettingsKind) -> proto::LocalSett
         LocalSettingsKind::Debug => proto::LocalSettingsKind::Debug,
     }
 }
+
+#[derive(Debug, Clone)]
+pub struct DapSettings {
+    pub binary: DapBinary,
+    pub args: Vec<String>,
+}
+
+impl From<DapSettingsContent> for DapSettings {
+    fn from(content: DapSettingsContent) -> Self {
+        DapSettings {
+            binary: content
+                .binary
+                .map_or_else(|| DapBinary::Default, |binary| DapBinary::Custom(binary)),
+            args: content.args.unwrap_or_default(),
+        }
+    }
+}
+
+#[derive(Debug, Clone)]
+pub enum DapBinary {
+    Default,
+    Custom(String),
+}

crates/settings/src/settings_content/project.rs 🔗

@@ -30,7 +30,7 @@ pub struct ProjectSettingsContent {
 
     /// Configuration for Debugger-related features
     #[serde(default)]
-    pub dap: HashMap<Arc<str>, DapSettings>,
+    pub dap: HashMap<Arc<str>, DapSettingsContent>,
 
     /// Settings for context servers used for AI-related features.
     #[serde(default)]
@@ -141,10 +141,10 @@ pub struct GlobalLspSettingsContent {
 #[skip_serializing_none]
 #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
 #[serde(rename_all = "snake_case")]
-pub struct DapSettings {
+pub struct DapSettingsContent {
     pub binary: Option<String>,
     #[serde(default)]
-    pub args: Vec<String>,
+    pub args: Option<Vec<String>>,
 }
 
 #[skip_serializing_none]