繁体   English   中英

如何将以下from_str宏更改为from_json?

[英]How do I change the following from_str macro to from_json?

我有以下宏。 请注意, StringContent是一个枚举项。

#[macro_export]
macro_rules! from_str {  
    ($json:expr) => {         
        StringContent(String::from($json))
    }
}

这让我可以编写代码

from_str!(r#"{
    "appName": "Demo App",
    "appVersion": "1.0",
    "database": {
        "host": "dev.database.com",
        "port": 3000
    }
}"#)

现在我想要另一个宏from_json! 这让我可以摆脱r#""#就像这样

from_json!({
    "appName": "Demo App",
    "appVersion": "1.0",
    "database": {
        "host": "dev.database.com",
        "port": 3000
    }
})

我尝试了以下似乎不起作用

#[macro_export]
macro_rules! from_json {  
    ($t:tt) => {         
        StringContent(String::from(concat!(r#"r#""#, stringify!($t), r#"""# , r#"#"#)))
    }
}

我怎样才能让from_json工作?

你的宏不起作用,因为concat! 不能用于以语法合理的方式将标识符附加到彼此。 它改为将标识符连接成一个字符串。 您现在看起来像"r#\\" ~your JSON~ \\"#" ,其中r##是文字字符。

在稳定的,扩展的concat_idents!之前你的方法将无法工作concat_idents! 实施

您必须在宏中手动解析JSON语法。 如需灵感,请了解Serde是如何做到的

serde_json一般似乎很适合你的用例。 如果可能的话,我建议删除任何JSON解析的自定义实现,而不是使用serde_json,因为它是Rust中所有JSON事实的标准选择。

这是如何使用serde_json将JSON转换为原始字符串的最小示例:

#[macro_use]
extern crate serde_json;

fn main() {
    let as_json_value = json!({
        "appName": "Demo App",
        "appVersion": "1.0",
        "database": {
            "host": "dev.database.com",
            "port": 3000
        }
    });
    let as_string = format!("{}", as_json_value);
    println!("{}", as_string);
}

虽然你可能想要重写你的StringContent枚举来从serde_json::Value构建,因为它已经为你整齐地解析了。

我只使用serde_json提供json ,它使用您的确切语法:

#[macro_use]
extern crate serde_json;
extern crate serde;

fn main() {
    let x = json!({
        "appName": "Demo App",
        "appVersion": "1.0",
        "database": {
            "host": "dev.database.com",
            "port": 3000
        }
    });
}

这将创建一个Value结构。 如果由于某种原因你真的需要它作为一个字符串,你需要使用它的Display实现重新序列化它:

extern crate serde;
#[macro_use]
extern crate serde_json;

struct StringContent(String);

macro_rules! from_json {
    ($x:tt) => {{
        StringContent(json!($x).to_string())
    }}
}

fn main() {
    let x = from_json!({
            "appName": "Demo App",
            "appVersion": "1.0",
            "database": {
                "host": "dev.database.com",
                "port": 3000
            }
        });

    println!("{}", x.0)
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM