log4rs icon indicating copy to clipboard operation
log4rs copied to clipboard

Modifying serialization mode

Open MaxKingPor opened this issue 3 years ago • 2 comments

I found that there are many log4rs::config::raw::Deserialize implementation. We can use #[serde(flatten)] and #[serde(tag = "type")] to modify the configuration structure. Example: LocalAppenders Enum Appender is used to distinguish user and local configurations. Note: Appender needs to add the #[serde(untagged)] attribute.

Example

#[derive(Deserialize, Serialize, Debug)]
pub struct ConsoleAppenderConfig {
    // target: Option<ConfigTarget>,
    // encoder: Option<EncoderConfig>,
    tty_only: Option<bool>,
}

// Note: Tuple structures cannot be used
#[derive(Deserialize, Serialize, Debug)]
#[serde(tag = "kind")]
enum LocalAppenders {
    #[cfg(feature = "console_appender")]
    #[serde(rename = "console")]
    ConsoleAppender(ConsoleAppenderConfig),
    // #[cfg(feature = "file_appender")]
    // FileAppender(FileAppenderConfig),
    // .....
}
#[derive(Deserialize, Serialize, Debug)]
struct UserAppenders{
    kind:String,
    #[serde(flatten)]
    config:serde_value::Value
}

#[derive(Deserialize, Serialize, Debug)]
#[serde(untagged)]
enum Appender {
    Local(LocalAppenders),
    User(UserAppenders),
}

#[derive(Deserialize, Serialize, Debug)]
struct AppenderConfig {
    // filters: Vec<Filter>,
    #[serde(flatten)]
    config: Appender,
}

#[derive(Deserialize, Serialize, Debug)]
pub struct RawConfig {
    // #[serde(deserialize_with = "de_duration", default)]
    refresh_rate: Option<u32>,

    // #[serde(default)]
    // root: Root,
    #[serde(default)]
    appenders: HashMap<String, AppenderConfig>,
    // #[serde(default)]
    // loggers: HashMap<String, Logger>,
}
use std::collections::BTreeMap;
fn main() {
    let a = AppenderConfig {
        config: Appender::Local(LocalAppenders::ConsoleAppender(ConsoleAppenderConfig{ tty_only: Some(false) }))  ,
    };
    let mut map = HashMap::new();
    map.insert("console_appender".into(), a);

    let mut cfg = RawConfig {
        appenders: map,
        refresh_rate: Some(99),
    };
    let s = toml::to_string(&cfg).unwrap();
    println!("{}", s);

    let s = r##"
refresh_rate = 99
[appenders.test]
kind = "test"
tty_only = true
    "##;
    cfg = toml::from_str(s).unwrap();

    println!("{:?}", cfg);
}

out

refresh_rate = 99
[appenders.console_appender]
kind = "console"
tty_only = false

RawConfig { refresh_rate: Some(99), appenders: {"test": AppenderConfig { config: User(UserAppenders { kind: "test", config: Map({String("tty_only"): Bool(true)}) }) }} }

MaxKingPor avatar Jul 13 '22 03:07 MaxKingPor

Can you please write a summary of your issue?

estk avatar Jul 13 '22 16:07 estk

Can you please write a summary of your issue?

0DE94107

MaxKingPor avatar Jul 14 '22 02:07 MaxKingPor

I'm sorry, i dont understand the question or request, I'm closing this for now. If this is a code suggestion please open a PR.

estk avatar Sep 01 '22 21:09 estk