@@ -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 ) ]
11591168pub 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
11691193impl 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
11781202impl 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
0 commit comments