簡體   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