aboutsummaryrefslogtreecommitdiff
path: root/alacritty_config
diff options
context:
space:
mode:
authorChristian Duerr <contact@christianduerr.com>2024-01-02 14:34:57 +0100
committerGitHub <noreply@github.com>2024-01-02 13:34:57 +0000
commit5685ce8bf8cb919f454518f1206b7ebc52636378 (patch)
treee20dde7f70bb06ad4edc277f2faa2b25ccf8938c /alacritty_config
parent8f57367eadeca92706193fc40030081f40e81fbf (diff)
downloadalacritty-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.toml4
-rw-r--r--alacritty_config/src/lib.rs37
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 }));
+ }
+}