微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何解析字符串或对象的 JSON 数组?

如何解决如何解析字符串或对象的 JSON 数组?

我遇到的一个 API 的 JSON 结构很差。有人认为发回一个看起来像这样的列表是个好主意

features: [
  "First one","second one",{
    "feature": "third one","hasAdditionalImpact": true
  },"forth one"
]

我想出了一种方法来将这些数据放入一个结构体中,但这很有效:

struct MyStruct {
    SensibleData: String,SensibleTruthy: bool,features: serde_json::Value,}

这无助于我规范化和验证数据。

有没有什么好方法可以把第一个对象变成类似的东西

features: [
  {
    "feature": "First one","hasAdditionalImpact": false
  },{
    "feature": "second one","hasAdditonalImpact": false
  },{
    "feature": "forth one","hasAdditionalImpact": false
  }
]

我看到 type_name 可能可用于检查类型并在由 serde_json 解析后进行后处理,但我也看到 type_name 用于诊断目的,所以我'宁愿不将其用于此目的。

解决方法

看起来你的 JSON 中的特性有两种形式;一个明确的对象和一个简化的形式,其中一些字段是默认的或未命名的。您可以使用这样的 eum 对其进行建模:

#[derive(Deserialize,Debug)]
#[serde(untagged)]
enum Feature {
    Simple(String),Explicit {
        feature: String,#[serde(rename = "hasAdditionalImpact")]
        has_additional_impact: bool,}
}

(playground)

#[serde(untagged)] 属性意味着它将尝试按顺序反序列化为每个变体,直到成功为止。


如果枚举会很烦人,您可以将它们全部转换为相同的结构,使用默认值,使用 #[serde(from)] 并提供 From 转换:

#[derive(Deserialize,Debug)]
#[serde(untagged)]
enum FeatureSource {
    Simple(String),},}

#[derive(Deserialize,Debug)]
#[serde(from = "FeatureSource")]
struct Feature {
    feature: String,has_additional_impact: bool,}

impl From<FeatureSource> for Feature {
    fn from(other: FeatureSource) -> Feature {
        match other {
            FeatureSource::Simple(feature) => Feature {
                feature,has_additional_impact: false,FeatureSource::Explicit {
                feature,has_additional_impact,} => Feature {
                feature,}
    }
}

(playground)

FeatureSource 仅用作中间表示,并在您的其余代码看到它之前转换为 Feature

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。