summaryrefslogtreecommitdiff
path: root/alacritty_config/src/lib.rs
blob: 5ed9e1a521964668a996de85e09c4dcd7e143471 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
use std::collections::HashMap;
use std::error::Error;

use log::LevelFilter;
use serde::Deserialize;
use serde_yaml::Value;

pub trait SerdeReplace {
    fn replace(&mut self, key: &str, value: Value) -> Result<(), Box<dyn Error>>;
}

macro_rules! impl_replace {
    ($($ty:ty),*$(,)*) => {
        $(
            impl SerdeReplace for $ty {
                fn replace(&mut self, key: &str, value: Value) -> Result<(), Box<dyn Error>> {
                    replace_simple(self, key, value)
                }
            }
        )*
    };
}

#[rustfmt::skip]
impl_replace!(
    usize, u8, u16, u32, u64, u128,
    isize, i8, i16, i32, i64, i128,
    f32, f64,
    bool,
    char,
    String,
    LevelFilter,
);

#[cfg(target_os = "macos")]
impl_replace!(winit::platform::macos::OptionAsAlt,);

fn replace_simple<'de, D>(data: &mut D, key: &str, value: Value) -> Result<(), Box<dyn Error>>
where
    D: Deserialize<'de>,
{
    if !key.is_empty() {
        let error = format!("Fields \"{key}\" do not exist");
        return Err(error.into());
    }
    *data = D::deserialize(value)?;

    Ok(())
}

impl<'de, T: Deserialize<'de>> SerdeReplace for Vec<T> {
    fn replace(&mut self, key: &str, value: Value) -> Result<(), Box<dyn Error>> {
        replace_simple(self, key, value)
    }
}

impl<'de, T: Deserialize<'de>> SerdeReplace for Option<T> {
    fn replace(&mut self, key: &str, value: Value) -> Result<(), Box<dyn Error>> {
        replace_simple(self, key, value)
    }
}

impl<'de, T: Deserialize<'de>> SerdeReplace for HashMap<String, T> {
    fn replace(&mut self, key: &str, value: Value) -> Result<(), Box<dyn Error>> {
        replace_simple(self, key, value)
    }
}