@@ -27,14 +27,18 @@ impl SettingsSet {
2727}
2828
2929pub fn set ( mut key : & str , value : & str , add : bool , local : bool ) -> Result < ( ) > {
30- let value = if let Some ( meta) = SETTINGS_META . get ( key) {
30+ let raw = value;
31+
32+ let toml_value = if let Some ( meta) = SETTINGS_META . get ( key) {
3133 match meta. type_ {
32- SettingsType :: Bool => parse_bool ( value) ?,
33- SettingsType :: Integer => parse_i64 ( value) ?,
34- SettingsType :: Duration => parse_duration ( value) ?,
35- SettingsType :: Url | SettingsType :: Path | SettingsType :: String => value. into ( ) ,
36- SettingsType :: ListString => parse_list_by_comma ( value) ?,
37- SettingsType :: ListPath => parse_list_by_colon ( value) ?,
34+ SettingsType :: Bool => parse_bool ( raw) ?,
35+ SettingsType :: Integer => parse_i64 ( raw) ?,
36+ SettingsType :: Duration => parse_duration ( raw) ?,
37+ SettingsType :: Url
38+ | SettingsType :: Path
39+ | SettingsType :: String => raw. into ( ) ,
40+ SettingsType :: ListString => parse_list_by_comma ( raw) ?,
41+ SettingsType :: ListPath => parse_list_by_colon ( raw) ?,
3842 }
3943 } else {
4044 bail ! ( "Unknown setting: {}" , key) ;
@@ -46,16 +50,20 @@ pub fn set(mut key: &str, value: &str, add: bool, local: bool) -> Result<()> {
4650 config:: global_config_path ( )
4751 } ;
4852 file:: create_dir_all ( path. parent ( ) . unwrap ( ) ) ?;
49- let raw = file:: read_to_string ( & path) . unwrap_or_default ( ) ;
50- let mut config: DocumentMut = raw. parse ( ) ?;
51- if !config. contains_key ( "settings" ) {
52- config[ "settings" ] = toml_edit:: Item :: Table ( toml_edit:: Table :: new ( ) ) ;
53+
54+ let raw_toml = file:: read_to_string ( & path) . unwrap_or_default ( ) ;
55+ let mut document: DocumentMut = raw_toml. parse ( ) ?;
56+
57+ if !document. contains_key ( "settings" ) {
58+ document[ "settings" ] = toml_edit:: Item :: Table ( toml_edit:: Table :: new ( ) ) ;
5359 }
54- if let Some ( mut settings) = config[ "settings" ] . as_table_mut ( ) {
55- if let Some ( ( parent_key, child_key) ) = key. split_once ( '.' ) {
56- key = child_key;
60+
61+ // 6)insert/merge under that table
62+ if let Some ( mut settings) = document[ "settings" ] . as_table_mut ( ) {
63+ if let Some ( ( parent, child) ) = key. split_once ( '.' ) {
64+ key = child;
5765 settings = settings
58- . entry ( parent_key )
66+ . entry ( parent )
5967 . or_insert ( {
6068 let mut t = toml_edit:: Table :: new ( ) ;
6169 t. set_implicit ( true ) ;
@@ -65,26 +73,34 @@ pub fn set(mut key: &str, value: &str, add: bool, local: bool) -> Result<()> {
6573 . unwrap ( ) ;
6674 }
6775
68- let value = match settings. get ( key) . map ( |c| c. as_array ( ) ) {
69- Some ( Some ( array) ) if add => {
70- let mut array = array. clone ( ) ;
71- if !array
72- . iter ( )
73- . any ( |item| item. as_str ( ) == Some ( value. as_str ( ) . unwrap ( ) ) )
74- {
75- array. extend ( value. as_array ( ) . unwrap ( ) . iter ( ) . cloned ( ) ) ;
76+ let new_item: toml_edit:: Value = if add {
77+ if let Some ( existing_arr) = settings
78+ . get ( key)
79+ . and_then ( |it| it. as_array ( ) )
80+ . cloned ( )
81+ {
82+ let mut arr = existing_arr;
83+
84+ // only push `raw` if not already in the list
85+ if !arr. iter ( ) . any ( |item| item. as_str ( ) == Some ( raw) ) {
86+ arr. push ( raw. into ( ) ) ;
7687 }
77- array. into ( )
88+ toml_edit:: Value :: Array ( arr)
89+ } else {
90+ toml_value. clone ( )
7891 }
79- _ => value,
92+ } else {
93+ toml_value. clone ( )
8094 } ;
81- settings. insert ( key, value. into ( ) ) ;
95+
96+ settings. insert ( key, new_item. into ( ) ) ;
8297
8398 // validate
84- let _: SettingsFile = toml:: from_str ( & config . to_string ( ) ) ?;
99+ let _: SettingsFile = toml:: from_str ( & document . to_string ( ) ) ?;
85100
86- file:: write ( path, config . to_string ( ) ) ?;
101+ file:: write ( & path, document . to_string ( ) ) ?;
87102 }
103+
88104 Ok ( ( ) )
89105}
90106
0 commit comments