Skip to content

Commit dd5b969

Browse files
committed
clean
1 parent bf56b3a commit dd5b969

File tree

5 files changed

+118
-80
lines changed

5 files changed

+118
-80
lines changed

crates/project/src/project_settings.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,7 @@ impl SettingsObserver {
728728
cx.update_global(|settings_store: &mut SettingsStore, cx| {
729729
settings_store
730730
.set_user_settings(&envelope.payload.contents, cx)
731-
._result()
731+
.result()
732732
.context("setting new user settings")?;
733733
anyhow::Ok(())
734734
})??;

crates/settings/src/settings.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ pub use serde_helper::*;
2525
pub use settings_file::*;
2626
pub use settings_json::*;
2727
pub use settings_store::{
28-
InvalidSettingsError, LocalSettingsKind, Settings, SettingsFile, SettingsJsonSchemaParams,
29-
SettingsKey, SettingsLocation, SettingsStore,
28+
InvalidSettingsError, LocalSettingsKind, MigrationStatus, ParseStatus, Settings, SettingsFile,
29+
SettingsJsonSchemaParams, SettingsKey, SettingsLocation, SettingsStore,
3030
};
3131

3232
pub use vscode_import::{VsCodeSettings, VsCodeSettingsSource};

crates/settings/src/settings_store.rs

Lines changed: 96 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -629,12 +629,12 @@ impl SettingsStore {
629629
}
630630

631631
#[inline(always)]
632-
fn parse_zed_settings<SettingsContentType: serde::de::DeserializeOwned>(
632+
fn parse_and_migrate_zed_settings<SettingsContentType: serde::de::DeserializeOwned>(
633633
&mut self,
634634
user_settings_content: &str,
635635
file: SettingsFile,
636636
) -> (Option<SettingsContentType>, SettingsParseResult) {
637-
let mut migration_result = Ok(false);
637+
let mut migration_status = MigrationStatus::NotNeeded;
638638
let settings: SettingsContentType = if user_settings_content.is_empty() {
639639
parse_json_with_comments("{}").expect("Empty settings should always be valid")
640640
} else {
@@ -645,15 +645,21 @@ impl SettingsStore {
645645
Err(_) => user_settings_content,
646646
};
647647
let parse_result = parse_json_with_comments(content);
648-
migration_result = migration_res
649-
.map(|migrated| migrated.is_some())
650-
.map_err(|err| err.to_string());
648+
migration_status = match migration_res {
649+
Ok(Some(_)) => MigrationStatus::Succeeded,
650+
Ok(None) => MigrationStatus::NotNeeded,
651+
Err(err) => MigrationStatus::Failed {
652+
error: err.to_string(),
653+
},
654+
};
651655
match parse_result {
652656
Ok(settings) => settings,
653657
Err(err) => {
654658
let result = SettingsParseResult {
655-
migration_result,
656-
parse_result: Err(err.to_string()),
659+
parse_status: ParseStatus::Failed {
660+
error: err.to_string(),
661+
},
662+
migration_status,
657663
};
658664
self.file_errors.insert(file, result.clone());
659665
return (None, result);
@@ -662,8 +668,8 @@ impl SettingsStore {
662668
};
663669

664670
let result = SettingsParseResult {
665-
migration_result,
666-
parse_result: Ok(()),
671+
parse_status: ParseStatus::Success,
672+
migration_status,
667673
};
668674
self.file_errors.insert(file, result.clone());
669675
return (Some(settings), result);
@@ -679,8 +685,8 @@ impl SettingsStore {
679685
self.file_errors.insert(
680686
file,
681687
SettingsParseResult {
682-
migration_result: Ok(false),
683-
parse_result: Err(message),
688+
parse_status: ParseStatus::Failed { error: message },
689+
migration_status: MigrationStatus::NotNeeded,
684690
},
685691
);
686692
} else {
@@ -692,7 +698,7 @@ impl SettingsStore {
692698
pub fn error_for_file(&self, file: SettingsFile) -> Option<SettingsParseResult> {
693699
self.file_errors
694700
.get(&file)
695-
.filter(|parse_result| parse_result.was_imperfect())
701+
.filter(|parse_result| parse_result.requires_user_action())
696702
.cloned()
697703
}
698704
}
@@ -769,8 +775,10 @@ impl SettingsStore {
769775
user_settings_content: &str,
770776
cx: &mut App,
771777
) -> SettingsParseResult {
772-
let (settings, parse_result) = self
773-
.parse_zed_settings::<UserSettingsContent>(user_settings_content, SettingsFile::User);
778+
let (settings, parse_result) = self.parse_and_migrate_zed_settings::<UserSettingsContent>(
779+
user_settings_content,
780+
SettingsFile::User,
781+
);
774782

775783
if let Some(settings) = settings {
776784
self.user_settings = Some(settings);
@@ -786,8 +794,10 @@ impl SettingsStore {
786794
global_settings_content: &str,
787795
cx: &mut App,
788796
) -> SettingsParseResult {
789-
let (settings, parse_result) = self
790-
.parse_zed_settings::<SettingsContent>(global_settings_content, SettingsFile::Global);
797+
let (settings, parse_result) = self.parse_and_migrate_zed_settings::<SettingsContent>(
798+
global_settings_content,
799+
SettingsFile::Global,
800+
);
791801

792802
if let Some(settings) = settings {
793803
self.global_settings = Some(Box::new(settings));
@@ -804,10 +814,7 @@ impl SettingsStore {
804814
let settings: Option<SettingsContent> = if server_settings_content.is_empty() {
805815
None
806816
} else {
807-
self.handle_potential_file_error(
808-
SettingsFile::Server,
809-
parse_json_with_comments(server_settings_content),
810-
)?
817+
parse_json_with_comments(server_settings_content)?
811818
};
812819

813820
// Rewrite the server settings into a content type
@@ -866,16 +873,17 @@ impl SettingsStore {
866873
}
867874
(LocalSettingsKind::Settings, Some(settings_contents)) => {
868875
let (new_settings, parse_result) = self
869-
.parse_zed_settings::<ProjectSettingsContent>(
876+
.parse_and_migrate_zed_settings::<ProjectSettingsContent>(
870877
settings_contents,
871878
SettingsFile::Project((root_id, directory_path.clone())),
872879
);
873-
parse_result
874-
.parse_result
875-
.map_err(|e| InvalidSettingsError::LocalSettings {
880+
match parse_result.parse_status {
881+
ParseStatus::Success => Ok(()),
882+
ParseStatus::Failed { error } => Err(InvalidSettingsError::LocalSettings {
876883
path: directory_path.join(local_settings_file_relative_path()),
877-
message: e.to_string(),
878-
})?;
884+
message: error,
885+
}),
886+
}?;
879887
if let Some(new_settings) = new_settings {
880888
match self.local_settings.entry((root_id, directory_path.clone())) {
881889
btree_map::Entry::Vacant(v) => {
@@ -1155,68 +1163,93 @@ impl SettingsStore {
11551163
// was the migration successful?
11561164
// was settings parsing successful?
11571165
// todo! can this type be improved?
1158-
#[derive(Clone)]
1166+
/// The result of parsing settings, including any migration attempts
1167+
#[derive(Debug, Clone, PartialEq, Eq)]
11591168
pub struct SettingsParseResult {
1160-
/// Ok(false) -> no migration was performed
1161-
///
1162-
/// Ok(true) -> migration was performed
1163-
///
1164-
/// Err(_) -> migration was attempted but failed
1165-
pub migration_result: Result<bool, String>,
1166-
pub parse_result: Result<(), String>,
1169+
/// The result of parsing the settings file (possibly after migration)
1170+
pub parse_status: ParseStatus,
1171+
/// The result of attempting to migrate the settings file
1172+
pub migration_status: MigrationStatus,
1173+
}
1174+
1175+
#[derive(Debug, Clone, PartialEq, Eq)]
1176+
pub enum ParseStatus {
1177+
/// Settings were parsed successfully
1178+
Success,
1179+
/// Settings failed to parse
1180+
Failed { error: String },
1181+
}
1182+
1183+
#[derive(Debug, Clone, PartialEq, Eq)]
1184+
pub enum MigrationStatus {
1185+
/// No migration was needed - settings are up to date
1186+
NotNeeded,
1187+
/// Settings were automatically migrated in memory, but the file needs to be updated
1188+
Succeeded,
1189+
/// Migration was attempted but failed. Original settings were parsed instead.
1190+
Failed { error: String },
11671191
}
11681192

11691193
impl Default for SettingsParseResult {
11701194
fn default() -> Self {
11711195
Self {
1172-
migration_result: Ok(false),
1173-
parse_result: Ok(()),
1196+
parse_status: ParseStatus::Success,
1197+
migration_status: MigrationStatus::NotNeeded,
11741198
}
11751199
}
11761200
}
11771201

11781202
impl SettingsParseResult {
11791203
pub fn unwrap(self) -> bool {
1180-
self._result().unwrap()
1204+
self.result().unwrap()
11811205
}
11821206

11831207
pub fn expect(self, message: &str) -> bool {
1184-
self._result().expect(message)
1208+
self.result().expect(message)
11851209
}
11861210

1187-
pub fn _result(self) -> Result<bool> {
1188-
match (
1189-
self.migration_result
1190-
.map_err(|err| anyhow::format_err!(err))
1191-
.context("Failed to migrate settings"),
1192-
self.parse_result
1193-
.map_err(|err| anyhow::format_err!(err))
1194-
.context("Failed to parse settings"),
1195-
) {
1196-
(migration_result @ Ok(_), Ok(_)) => migration_result,
1197-
(Err(migration_err), Err(parse_err)) => {
1198-
Err(anyhow::anyhow!("{} and {}", migration_err, parse_err))
1211+
/// Formats the ParseResult as a Result type. This is a lossy conversion
1212+
pub fn result(self) -> Result<bool> {
1213+
let migration_result = match self.migration_status {
1214+
MigrationStatus::NotNeeded => Ok(false),
1215+
MigrationStatus::Succeeded => Ok(true),
1216+
MigrationStatus::Failed { error } => {
1217+
Err(anyhow::format_err!(error)).context("Failed to migrate settings")
1218+
}
1219+
};
1220+
1221+
let parse_result = match self.parse_status {
1222+
ParseStatus::Success => Ok(()),
1223+
ParseStatus::Failed { error } => {
1224+
Err(anyhow::format_err!(error)).context("Failed to parse settings")
11991225
}
1200-
(Err(migration_err), Ok(_)) => Err(migration_err),
1201-
(Ok(_), Err(parse_err)) => Err(parse_err),
1226+
};
1227+
1228+
match (migration_result, parse_result) {
1229+
(migration_result @ Ok(_), Ok(())) => migration_result,
1230+
(Err(migration_err), Ok(())) => Err(migration_err),
1231+
(_, Err(parse_err)) => Err(parse_err),
12021232
}
12031233
}
12041234

1205-
// todo! rename
1206-
pub fn was_imperfect(&self) -> bool {
1207-
let tried_to_migrate = *self.migration_result.as_ref().unwrap_or(&true);
1208-
let failed_to_parse = self.parse_result.is_err();
1209-
tried_to_migrate || failed_to_parse
1235+
/// Returns true if there parsing or migration failed, as well as if migration was required
1236+
pub fn requires_user_action(&self) -> bool {
1237+
matches!(self.parse_status, ParseStatus::Failed { .. })
1238+
|| matches!(
1239+
self.migration_status,
1240+
MigrationStatus::Succeeded | MigrationStatus::Failed { .. }
1241+
)
12101242
}
12111243

1212-
pub fn migrated(&self) -> bool {
1213-
self.migration_result
1214-
.as_ref()
1215-
.is_ok_and(|&migrated| migrated)
1244+
pub fn ok(self) -> Option<bool> {
1245+
self.result().ok()
12161246
}
12171247

1218-
pub fn ok(self) -> Option<bool> {
1219-
self._result().ok()
1248+
pub fn parse_error(&self) -> Option<String> {
1249+
match &self.parse_status {
1250+
ParseStatus::Failed { error } => Some(error.clone()),
1251+
ParseStatus::Success => None,
1252+
}
12201253
}
12211254
}
12221255

crates/settings_ui/src/settings_ui.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2701,22 +2701,23 @@ impl SettingsWindow {
27012701
})),
27022702
)
27032703
}
2704-
let parse_failed = error.parse_result.is_err();
2704+
let parse_error = error.parse_error();
2705+
let parse_failed = parse_error.is_some();
27052706
warning_banner = v_flex()
27062707
.pb_4()
2707-
.when_some(error.parse_result.err(), |this, err| {
2708+
.when_some(parse_error, |this, err| {
27082709
this.child(
27092710
banner("Your Settings File Is In An Invalid State. Setting Values May Be Incorrect, And Changes May Be Lost", err, &mut self.shown_errors, cx)
27102711
)
27112712
})
27122713
.map(|this| {
2713-
match error.migration_result {
2714-
Ok(true) => {
2714+
match &error.migration_status {
2715+
settings::MigrationStatus::Succeeded => {
27152716
this.child(
27162717
banner("Your Settings File Is Out Of Date, And Needs To Be Updated", "It May Be Possible To Automatically Migrate Your Settings File".to_string(), &mut self.shown_errors, cx)
27172718
)
27182719
},
2719-
Err(err) if !parse_failed => {
2720+
settings::MigrationStatus::Failed { error: err } if !parse_failed => {
27202721
this.child(
27212722
banner("Your Settings File Is Out Of Date, Automatic Migration Failed", err, &mut self.shown_errors, cx)
27222723
)

crates/zed/src/zed.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1306,12 +1306,16 @@ pub fn handle_settings_file_changes(
13061306

13071307
let id = NotificationId::Named("failed-to-migrate-settings".into());
13081308
// Apply migrations to both user and global settings
1309-
let content_migrated = match result.migration_result {
1310-
Ok(migrated) => {
1309+
let content_migrated = match result.migration_status {
1310+
settings::MigrationStatus::Succeeded => {
13111311
dismiss_app_notification(&id, cx);
1312-
migrated
1312+
true
13131313
}
1314-
Err(err) => {
1314+
settings::MigrationStatus::NotNeeded => {
1315+
dismiss_app_notification(&id, cx);
1316+
false
1317+
}
1318+
settings::MigrationStatus::Failed { error: err } => {
13151319
show_app_notification(id, cx, move |cx| {
13161320
cx.new(|cx| {
13171321
MessageNotification::new(
@@ -1334,16 +1338,16 @@ pub fn handle_settings_file_changes(
13341338
}
13351339
};
13361340

1337-
if let Err(err) = &result.parse_result {
1341+
if let settings::ParseStatus::Failed { error: err } = &result.parse_status {
13381342
let settings_type = if is_user { "user" } else { "global" };
13391343
log::error!("Failed to load {} settings: {err}", settings_type);
13401344
}
13411345

13421346
settings_changed(
1343-
result
1344-
.parse_result
1345-
.err()
1346-
.map(|err| anyhow::format_err!(err)),
1347+
match result.parse_status {
1348+
settings::ParseStatus::Failed { error } => Some(anyhow::format_err!(error)),
1349+
settings::ParseStatus::Success => None,
1350+
},
13471351
cx,
13481352
);
13491353

0 commit comments

Comments
 (0)