diff options
author | Christian Duerr <contact@christianduerr.com> | 2023-06-12 02:23:41 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-12 00:23:41 +0000 |
commit | bd4906722a1a026b01f06c94c33b13ff63a7e044 (patch) | |
tree | a2713a7b0a5fa23ec8b9055d7ed06f1cede62447 /alacritty_config_derive | |
parent | ea2c39e65d21728e0f04b0eafcec7153e4447cd5 (diff) | |
download | alacritty-bd4906722a1a026b01f06c94c33b13ff63a7e044.tar.gz alacritty-bd4906722a1a026b01f06c94c33b13ff63a7e044.zip |
Switch to TOML configuration format
This switches Alacritty's default configuration format from yaml to
toml. While yaml is still supported, it is done by converting it to toml
and should be removed entirely in the future.
All existing features were persisted based on my testing. Behavior
should not change much, though `--option` might have slightly different
behavior since the entire line is not interpreted as one line of toml.
A new `alacritty migrate` subcommand has been added which allows
automatic migration from yaml to toml. This also could be used as a
facility to automatically fix configuration file changes in the future.
Closes #6592.
Diffstat (limited to 'alacritty_config_derive')
-rw-r--r-- | alacritty_config_derive/Cargo.toml | 6 | ||||
-rw-r--r-- | alacritty_config_derive/src/config_deserialize/de_struct.rs | 26 | ||||
-rw-r--r-- | alacritty_config_derive/src/serde_replace.rs | 4 | ||||
-rw-r--r-- | alacritty_config_derive/tests/config.rs | 37 |
4 files changed, 44 insertions, 29 deletions
diff --git a/alacritty_config_derive/Cargo.toml b/alacritty_config_derive/Cargo.toml index d50b6b1d..12ef2169 100644 --- a/alacritty_config_derive/Cargo.toml +++ b/alacritty_config_derive/Cargo.toml @@ -12,15 +12,15 @@ rust-version = "1.65.0" proc-macro = true [dependencies] -syn = { version = "2.0.16", features = ["derive", "parsing", "proc-macro", "printing"], default-features = false } proc-macro2 = "1.0.24" quote = "1.0.7" +syn = { version = "2.0.16", features = ["derive", "parsing", "proc-macro", "printing"], default-features = false } [dev-dependencies.alacritty_config] path = "../alacritty_config" version = "0.1.2-dev" [dev-dependencies] -serde = { version = "1.0.117", features = ["derive"] } -serde_yaml = "0.8.14" log = "0.4.11" +serde = { version = "1.0.117", features = ["derive"] } +toml = "0.7.1" diff --git a/alacritty_config_derive/src/config_deserialize/de_struct.rs b/alacritty_config_derive/src/config_deserialize/de_struct.rs index 1846f925..d2a7dd82 100644 --- a/alacritty_config_derive/src/config_deserialize/de_struct.rs +++ b/alacritty_config_derive/src/config_deserialize/de_struct.rs @@ -42,20 +42,25 @@ pub fn derive_deserialize<T>( { let mut config = Self::Value::default(); - // NOTE: This could be used to print unused keys. - let mut unused = serde_yaml::Mapping::new(); + // Unused keys for flattening and warning. + let mut unused = toml::Table::new(); - while let Some((key, value)) = map.next_entry::<String, serde_yaml::Value>()? { + while let Some((key, value)) = map.next_entry::<String, toml::Value>()? { match key.as_str() { #match_assignments _ => { - unused.insert(serde_yaml::Value::String(key), value); + unused.insert(key, value); }, } } #flatten + // Warn about unused keys. + for key in unused.keys() { + log::warn!(target: #LOG_TARGET, "Unused config key: {}", key); + } + Ok(config) } } @@ -109,7 +114,12 @@ fn field_deserializer(field_streams: &mut FieldStreams, field: &Field) -> Result match serde::Deserialize::deserialize(value) { Ok(value) => config.#ident = value, Err(err) => { - log::error!(target: #LOG_TARGET, "Config error: {}: {}", #literal, err); + log::error!( + target: #LOG_TARGET, + "Config error: {}: {}", + #literal, + err.to_string().trim(), + ); }, } }; @@ -133,8 +143,10 @@ fn field_deserializer(field_streams: &mut FieldStreams, field: &Field) -> Result // Create the tokens to deserialize the flattened struct from the unused fields. field_streams.flatten.extend(quote! { - let unused = serde_yaml::Value::Mapping(unused); - config.#ident = serde::Deserialize::deserialize(unused).unwrap_or_default(); + // Drain unused fields since they will be used for flattening. + let flattened = std::mem::replace(&mut unused, toml::Table::new()); + + config.#ident = serde::Deserialize::deserialize(flattened).unwrap_or_default(); }); }, "deprecated" | "removed" => { diff --git a/alacritty_config_derive/src/serde_replace.rs b/alacritty_config_derive/src/serde_replace.rs index 4a0a6a99..7ca5ca7c 100644 --- a/alacritty_config_derive/src/serde_replace.rs +++ b/alacritty_config_derive/src/serde_replace.rs @@ -28,7 +28,7 @@ pub fn derive(input: TokenStream) -> TokenStream { pub fn derive_direct(ident: Ident, generics: Generics) -> TokenStream2 { quote! { impl <#generics> alacritty_config::SerdeReplace for #ident <#generics> { - fn replace(&mut self, key: &str, value: serde_yaml::Value) -> Result<(), Box<dyn std::error::Error>> { + fn replace(&mut self, key: &str, value: toml::Value) -> Result<(), Box<dyn std::error::Error>> { if !key.is_empty() { let error = format!("Fields \"{}\" do not exist", key); return Err(error.into()); @@ -53,7 +53,7 @@ pub fn derive_recursive<T>( quote! { #[allow(clippy::extra_unused_lifetimes)] impl <'de, #constrained> alacritty_config::SerdeReplace for #ident <#unconstrained> { - fn replace(&mut self, key: &str, value: serde_yaml::Value) -> Result<(), Box<dyn std::error::Error>> { + fn replace(&mut self, key: &str, value: toml::Value) -> Result<(), Box<dyn std::error::Error>> { if key.is_empty() { *self = serde::Deserialize::deserialize(value)?; return Ok(()); diff --git a/alacritty_config_derive/tests/config.rs b/alacritty_config_derive/tests/config.rs index bd449ff8..15bc62a9 100644 --- a/alacritty_config_derive/tests/config.rs +++ b/alacritty_config_derive/tests/config.rs @@ -86,20 +86,22 @@ fn config_deserialize() { log::set_logger(logger).unwrap(); log::set_max_level(log::LevelFilter::Warn); - let test: Test = serde_yaml::from_str( + let test: Test = toml::from_str( r#" - field1: 3 - field3: 32 - nesting: - field1: "testing" - field2: None - field3: 99 - aliased: 8 - flatty: 123 - enom_small: "one" - enom_big: "THREE" - enom_error: "HugaBuga" - gone: false + field1 = 3 + field3 = 32 + + flatty = 123 + enom_small = "one" + enom_big = "THREE" + enom_error = "HugaBuga" + gone = false + + [nesting] + field1 = "testing" + field2 = "None" + field3 = 99 + aliased = 8 "#, ) .unwrap(); @@ -121,15 +123,16 @@ fn config_deserialize() { // Verify all log messages are correct. let error_logs = logger.error_logs.lock().unwrap(); assert_eq!(error_logs.as_slice(), [ - "Config error: field1: invalid type: string \"testing\", expected usize", "Config error: enom_error: unknown variant `HugaBuga`, expected one of `One`, `Two`, \ `Three`", + "Config error: field1: invalid type: string \"testing\", expected usize", ]); let warn_logs = logger.warn_logs.lock().unwrap(); assert_eq!(warn_logs.as_slice(), [ "Config warning: field1 has been deprecated; use field2 instead", "Config warning: enom_error has been deprecated", "Config warning: gone has been removed; it's gone", + "Unused config key: field3", ]); } @@ -170,7 +173,7 @@ impl Log for Logger { fn field_replacement() { let mut test = Test::default(); - let value = serde_yaml::to_value(13).unwrap(); + let value = toml::Value::Integer(13); test.replace("nesting.field2", value).unwrap(); assert_eq!(test.nesting.field2, Some(13)); @@ -180,7 +183,7 @@ fn field_replacement() { fn replace_derive() { let mut test = Test::default(); - let value = serde_yaml::to_value(9).unwrap(); + let value = toml::Value::Integer(9); test.replace("nesting.newtype", value).unwrap(); assert_eq!(test.nesting.newtype, NewType(9)); @@ -190,7 +193,7 @@ fn replace_derive() { fn replace_flatten() { let mut test = Test::default(); - let value = serde_yaml::to_value(7).unwrap(); + let value = toml::Value::Integer(7); test.replace("flatty", value).unwrap(); assert_eq!(test.flatten.flatty, 7); |