【问题标题】:Parsing JSON with multiple representation in the same attribute在同一属性中解析具有多个表示的 JSON
【发布时间】:2018-08-17 07:24:08
【问题描述】:

我对 Rust 比较陌生,对 Serde 更是如此,所以我很难确定这是否可行。我有一个 JSON 文件,它对同一个键有两种不同的表示:

"coordinates": [
  [
    [
      121.423364,
      24.9913596
    ],
    [
      121.4233327,
      24.9912977
    ],
  ]
]

还有这个:

"coordinates": [
  [
    121.4472492,
    25.0052053
  ],
  [
    121.4466457,
    25.0028547
  ]
]

在同一个属性中有一个二维数组和一个三维数组表示方式。这使得文件难以序列化。

这是我实现的代码:

#[derive(Serialize, Deserialize, Debug)]
struct Geometry {
    #[serde(deserialize_with = "string_or_number", rename = "type")]
    geometry_type: Value,
    #[serde(default, skip_serializing_if = "Vec::is_empty", rename = "coordinates")]
    geometry_coor: Vec<Coordinates>,
    #[serde(default, skip_serializing_if = "Vec::is_empty", rename = "coordinates")]
    geometry_coor2: Vec<Vec<Coordinates>>,
}

#[derive(Serialize, Deserialize, Debug)]
struct Coordinates {
    #[serde(deserialize_with = "string_or_number")]
    longitude: Value,
    #[serde(deserialize_with = "string_or_number")]
    latitude: Value,
}

fn string_or_number<'de, D>(de: D) -> Result<Value, D::Error>
where
    D: serde::Deserializer<'de>,
{
    let helper: Value = Deserialize::deserialize(de)?;

    match helper {
        Value::Number(n) => {
            println!("{:#?}", n.as_f64().unwrap().to_string());
            Ok(Value::Number(n))
        }
        Value::String(s) => Ok(json!(s)),
        _ => Ok(json!(null)),
    }
}

我在序列化坐标文件的struct Geometry 中遇到问题。

有什么办法可以处理这种表格吗?

【问题讨论】:

    标签: json rust serde


    【解决方案1】:

    我收到了help from the serde-rs developer:

    我建议使用untagged enum 来表示可以是 2d 或 3d 的坐标数组。 Playground link

    修改后的代码如下:

    #[derive(Serialize, Deserialize, Debug)]
    struct Geometry {
        #[serde(deserialize_with = "string_or_number", rename = "type")]
        geometry_type: Value,
        #[serde(default, skip_serializing_if = "Vec::is_empty", rename = "coordinates")]
        geometry_coor: Vec<Coordinates_form>,
    }
    
    #[derive(Serialize, Deserialize, Debug)]
    #[serde(untagged)]
    enum Coordinates_form {
        #[serde(skip_serializing)]
        OneD(Coordinates),
        #[serde(skip_serializing)]
        TwoD(Vec<Coordinates>),
        #[serde(skip_serializing)]
        ThreeD(Vec<Vec<Coordinates>>),
    }
    
    #[derive(Deserialize, Debug)]
    struct Coordinates {
        #[serde(deserialize_with = "string_or_number")]
        longitude: Value, 
        #[serde(deserialize_with = "string_or_number")]
        latitude: Value,
    }
    
    fn string_or_number<'de, D>(de: D) -> Result<Value, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let helper: Value = Deserialize::deserialize(de)?;
    
        match helper {
            Value::Number(n) => {
                println!("{:#?}", n.as_f64().unwrap().to_string());
                Ok(Value::Number(n))
            }
            Value::String(s) => Ok(json!(s)),
            _ => Ok(json!(null)),
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多