Convert strings and maps into maps

Viewed 119

In Rust, how do I take the inputs "Some string" and {"Message":"Some string"} and turn them both into the JSON: {"Message": "Some string", "Source": "My app"}? I've tried doing this via the following macro, but it doesn't work.

macro_rules! my_logger {
    ($level:literal, $msg:tt) => {
        let mut jsonval = json!($msg);
        if let Map(m) = $msg {
            m.insert("app", "foobar");
        } else {
            let m = Map::new();
            m.insert("app", "foobar");
            jsonval = m;
        }

        println!("{}: {}", $level, jsonval.to_string());
    }
}

I'm trying to log my application data using JSON. I'd use tracing, but I need the logging macros my vendor provides to connect to the logging vendor (New Relic) and I don't know how do make tracing do that. :)

1 Answers

If it is ok for you to use a function, this should work:

#[derive(Deserialize, Debug)]
struct Message {
    #[serde(rename = "Message")]
    message: String,
}

fn concat_data(message: &str) -> serde_json::value::Value {
    let message: Message = serde_json::from_str(message)
        .unwrap_or_else(|_| Message {
            message: message.to_string()
        }
    );
    json!({ "Message": message.message, "Source": "My app" })
}

but it is not very pretty. The basic idea is to use serde_json::value::Value.

Here is a playground.

Related