如何解析字符串或对象的 JSON 数组?
How can I parse a JSON array of either strings or objects?
我击中的 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": "third one",
"hasAdditionalImpact": true
},
{
"feature": "forth one",
"hasAdditionalImpact": false
}
]
我看到 type_name 可能可用于检查类型并在被 serde_json
解析后进行 post 处理,但我也看到 type_name
是出于诊断目的,所以我不想将其用于此目的。
您的 JSON 中的特征看起来有两种形式;一个明确的对象和一个简化的形式,其中一些字段是默认的或未命名的。您可以使用这样的 eum 对其进行建模:
#[derive(Deserialize, Debug)]
#[serde(untagged)]
enum Feature {
Simple(String),
Explicit {
feature: String,
#[serde(rename = "hasAdditionalImpact")]
has_additional_impact: bool,
}
}
#[serde(untagged)]
属性意味着它将尝试按顺序反序列化为每个变体,直到一个成功。
如果枚举很烦人,您可以使用 #[serde(from)]
并提供 From
转换将它们全部转换为具有默认值的相同结构:
#[derive(Deserialize, Debug)]
#[serde(untagged)]
enum FeatureSource {
Simple(String),
Explicit {
feature: String,
#[serde(rename = "hasAdditionalImpact")]
has_additional_impact: bool,
},
}
#[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,
has_additional_impact,
},
}
}
}
FeatureSource
仅用作中间表示,并在您的其余代码看到它之前转换为 Feature
。
我击中的 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": "third one",
"hasAdditionalImpact": true
},
{
"feature": "forth one",
"hasAdditionalImpact": false
}
]
我看到 type_name 可能可用于检查类型并在被 serde_json
解析后进行 post 处理,但我也看到 type_name
是出于诊断目的,所以我不想将其用于此目的。
您的 JSON 中的特征看起来有两种形式;一个明确的对象和一个简化的形式,其中一些字段是默认的或未命名的。您可以使用这样的 eum 对其进行建模:
#[derive(Deserialize, Debug)]
#[serde(untagged)]
enum Feature {
Simple(String),
Explicit {
feature: String,
#[serde(rename = "hasAdditionalImpact")]
has_additional_impact: bool,
}
}
#[serde(untagged)]
属性意味着它将尝试按顺序反序列化为每个变体,直到一个成功。
如果枚举很烦人,您可以使用 #[serde(from)]
并提供 From
转换将它们全部转换为具有默认值的相同结构:
#[derive(Deserialize, Debug)]
#[serde(untagged)]
enum FeatureSource {
Simple(String),
Explicit {
feature: String,
#[serde(rename = "hasAdditionalImpact")]
has_additional_impact: bool,
},
}
#[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,
has_additional_impact,
},
}
}
}
FeatureSource
仅用作中间表示,并在您的其余代码看到它之前转换为 Feature
。