diff options
author | Christian Duerr <contact@christianduerr.com> | 2024-01-02 14:34:57 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-02 13:34:57 +0000 |
commit | 5685ce8bf8cb919f454518f1206b7ebc52636378 (patch) | |
tree | e20dde7f70bb06ad4edc277f2faa2b25ccf8938c /alacritty_config | |
parent | 8f57367eadeca92706193fc40030081f40e81fbf (diff) | |
download | alacritty-5685ce8bf8cb919f454518f1206b7ebc52636378.tar.gz alacritty-5685ce8bf8cb919f454518f1206b7ebc52636378.zip |
Fix replacing optional fields
This fixes an issue with the default `SerdeReplace` implementation where
it would never recurse through options but always replace the entire
option with the new value.
Closes #7518.
Diffstat (limited to 'alacritty_config')
-rw-r--r-- | alacritty_config/Cargo.toml | 4 | ||||
-rw-r--r-- | alacritty_config/src/lib.rs | 37 |
2 files changed, 39 insertions, 2 deletions
diff --git a/alacritty_config/Cargo.toml b/alacritty_config/Cargo.toml index 985da0e3..28875c3b 100644 --- a/alacritty_config/Cargo.toml +++ b/alacritty_config/Cargo.toml @@ -12,3 +12,7 @@ rust-version = "1.70.0" log = { version = "0.4.17", features = ["serde"] } serde = "1.0.163" toml = "0.8.2" + +[dev-dependencies] +alacritty_config_derive = { path = "../alacritty_config_derive" } +serde = { version = "1.0.163", features = ["derive"] } diff --git a/alacritty_config/src/lib.rs b/alacritty_config/src/lib.rs index c5a43b87..81e43bb8 100644 --- a/alacritty_config/src/lib.rs +++ b/alacritty_config/src/lib.rs @@ -1,5 +1,6 @@ use std::collections::HashMap; use std::error::Error; +use std::path::PathBuf; use log::LevelFilter; use serde::Deserialize; @@ -9,6 +10,7 @@ pub trait SerdeReplace { fn replace(&mut self, value: Value) -> Result<(), Box<dyn Error>>; } +#[macro_export] macro_rules! impl_replace { ($($ty:ty),*$(,)*) => { $( @@ -29,6 +31,7 @@ impl_replace!( bool, char, String, + PathBuf, LevelFilter, ); @@ -47,9 +50,12 @@ impl<'de, T: Deserialize<'de>> SerdeReplace for Vec<T> { } } -impl<'de, T: Deserialize<'de>> SerdeReplace for Option<T> { +impl<'de, T: SerdeReplace + Deserialize<'de>> SerdeReplace for Option<T> { fn replace(&mut self, value: Value) -> Result<(), Box<dyn Error>> { - replace_simple(self, value) + match self { + Some(inner) => inner.replace(value), + None => replace_simple(self, value), + } } } @@ -58,3 +64,30 @@ impl<'de, T: Deserialize<'de>> SerdeReplace for HashMap<String, T> { replace_simple(self, value) } } + +#[cfg(test)] +mod tests { + use super::*; + + use crate as alacritty_config; + use alacritty_config_derive::ConfigDeserialize; + + #[test] + fn replace_option() { + #[derive(ConfigDeserialize, Default, PartialEq, Eq, Debug)] + struct ReplaceOption { + a: usize, + b: usize, + } + + let mut subject: Option<ReplaceOption> = None; + + let value: Value = toml::from_str("a=1").unwrap(); + SerdeReplace::replace(&mut subject, value).unwrap(); + + let value: Value = toml::from_str("b=2").unwrap(); + SerdeReplace::replace(&mut subject, value).unwrap(); + + assert_eq!(subject, Some(ReplaceOption { a: 1, b: 2 })); + } +} |