繁体   English   中英

如何使用枚举将 json object 反序列化为 rust 可理解的代码?

[英]How to deserialize a json object into rust understandable code using enums?

我需要反序列化(以及稍后序列化)一段具有这种结构的数据:

{
  "type": "TypeApplication",
  "val": {
    "con": {
      "type": "TypeConstructor",
      "val": [
        "Builtin",
        "Record"
      ]
    },
    "arg": {
      "type": "RowCons",
      "val": {
        "label": "953e3dd6-826e-1985-cb99-fd4ed4da754e",
        "type": {
          "type": "TypeApplication",
          "val": {
            "con": {
              "type": "TypeConstructor",
              "val": [
                "Builtin",
                "List"
              ]
            },
            "arg": {
              "type": "Element",
              "meta": {
                "multiLine": true
              }
            }
          },
          "system": {
            "label": "nullam-senectus-port - Text",
            "isBindable": true,
            "defaultValue": [
              {
                "id": "4a05486f-f24d-45f8-ae13-ab05f824d74d",
                "type": "String",
                "pluginType": "Basic",
                "data": {
                  "value": "Nullam senectus porttitor in eget. Eget rutrum leo interdum."
                },
                "children": [],
                "text": true
              }
            ],
            "isUnlinked": false,
            "isDefault": false
          }
        },
        "tail": {
          "type": "RowCons",
          "val": {
            "label": "94f603df-d585-b45a-4252-9ec77cf5b13c",
            "type": {
              "type": "TypeApplication",
              "val": {
                "con": {
                  "type": "TypeConstructor",
                  "val": [
                    "Builtin",
                    "List"
                  ]
                },
                "arg": {
                  "type": "Element",
                  "meta": {
                    "multiLine": true
                  }
                }
              },
              "system": {
                "label": "best-services - Text",
                "isBindable": true,
                "defaultValue": [
                  {
                    "id": "6265ca45-3f69-4844-97e2-c05bbfb9fee5",
                    "type": "String",
                    "pluginType": "Basic",
                    "data": {
                      "value": "Best Services"
                    },
                    "children": [],
                    "text": true
                  }
                ]
              }
            },
            "tail": {
              "type": "RowEmpty"
            }
          }
        }
      }
    }
  }
}

我不知道这个数据到底是什么,但我知道这是试图表示一个函数/元素,它接受值和这些值的默认值作为参数/属性。

我想使用serde反序列化它,然后也序列化它。 到目前为止,我已经能够写出一些类似的作品,但不是真的:

#[skip_serializing_none]
#[derive(Deserialize, Serialize, Debug, Clone)]
#[serde(tag = "type", content = "val")]
pub enum WebflowPropDataType {
    TypeApplication {
        con: Box<WebflowPropDataType>, // Normally Passes the Type Constructor
        arg: Box<WebflowPropDataType>, // Normally Passes the Row Constructor
    },
    TypeConstructor(Vec<String>), // Stores Value of TypeConstructor
    RowCons {
        label: String, // Stores the label of the Row
        #[serde(rename = "type")]
        row_con_type: Box<WebflowPropDataType>, // Stores the type of the Row
        tail: Box<WebflowPropDataType>,
    },
    RowEmpty, // For Ending the recursive usage of rowConstructor
}

#[skip_serializing_none]
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct WebflowRowConDataType {
    #[serde(rename = "type")]
    val_type: String, // TypeApplication
    val: Box<WebflowPropDataType>,
} 

这适用于这样的结构:

{
    "type": "TypeApplication",
    "val":{
        "con": {
            "type": "TypeConstructor",
            "val": []
          },       
        "arg": {
            "type": "RowEmpty"
        }
    }
}

但如果我尝试使用初始示例,将会失败。 我知道这可能是由于缺少适当的arg类型,或者甚至TypeApplication Enum hand 格式不正确。

我确实看到一个相邻的类型解决方案在大多数情况下就足够了,但是在示例结构中看到的情况是存在第三个值称为system ,我无法确定哪种类型的方法可以帮助我实现这种类型结果。

我应该如何处理这个问题才能生成这种类型的代码。

我不是要任何人给我写一个解决方案,而是要给我建议我的方法应该是什么? 无论您是否知道这是什么类型的数据/如何生成它,或者即使有一些其他的库我也应该研究一下来操作这种类型的数据或者看看其他的方法。

PS : - 我的最终目标是能够从已经包含的函数/对象的属性和默认值知识中生成/序列化这种类型的 JSON 代码。

以下是我的建议:

  1. 只使用#[serde(tag = "type")]而不是#[serde(tag = "type", content = "val")] 您将不得不手动处理val (将当前枚举成员提取到单独的结构中),但这也允许您处理TypeApplication.systemElement.meta

    这也有减少所涉及的Box数量的小好处。

  2. 考虑WebflowPropDataType中的所有不同情况是否实际上可以在使用它的任何地方发生。 如果不是(也许Element只能在TypeApplication.val.arg下发生),那么您可能希望将枚举拆分为多个,以便在类型系统中反映出来。


#1 的示例:

use serde::{Serialize, Deserialize};

#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct TypeApplicationVal {
    con: WebflowPropDataType, // Normally Passes the Type Constructor
    arg: WebflowPropDataType, // Normally Passes the Row Constructor
}

// #[skip_serializing_none]
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct TypeApplicationSystem {
    label: String,
    #[serde(rename = "isBindable")]
    is_bindable: bool,

    // TODO: defaultValue

    #[serde(rename = "isUnlinked")]
    #[serde(skip_serializing_if = "Option::is_none")]
    is_unlinked: Option<bool>,
    #[serde(rename = "isDefault")]
    #[serde(skip_serializing_if = "Option::is_none")]
    is_default: Option<bool>,
}

#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct RowConsVal {
    label: String, // Stores the label of the Row
    #[serde(rename = "type")]
    typ: WebflowPropDataType, // Stores the type of the Row
    tail: WebflowPropDataType,
}

#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct ElementMeta {
    #[serde(rename = "multiLine")]
    multi_line: bool,
}

#[derive(Deserialize, Serialize, Debug, Clone)]
#[serde(tag = "type")]
pub enum WebflowPropDataType {
    TypeApplication {
        val: Box<TypeApplicationVal>,
        #[serde(skip_serializing_if = "Option::is_none")]
        system: Option<TypeApplicationSystem>,
    },
    TypeConstructor {
        val: Vec<String> // Stores Value of TypeConstructor
    },
    RowCons {
        val: Box<RowConsVal>,
    },
    Element {
        meta: ElementMeta,
    },
    RowEmpty, // For Ending the recursive usage of rowConstructor
}

操场

暂无
暂无

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

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