top | item 27026480

(no title)

coolreader18 | 4 years ago

Because ideally your JSON schema validator would turn it into a type that mirrors the structure of the data. "Parse, don't validate"[0]

[0]: https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-va...

discuss

order

linkdd|4 years ago

But the Rust type system cannot fully express a JSON Schema:

  {
    "type": "object",
    "oneOf": [{
      "required": ["kind", "foobar"],
      "properties": {
        "kind": {"enum": ["foo"]},
        "foobar": {"type": "string"}
      }
    }, {
      "required": ["kind", "barbaz"],
      "properties": {
        "kind": {"enum": ["bar"]},
        "foobar": {"type": "number"},
        "barbaz": {"type": "string"}
      }
    }]
  }
Or am I wrong?

masklinn|4 years ago

I'm sure you can design schemas screwy enough that Rust can not even express them[0] but that one seems straightforward enough:

    #[derive(Serialize, Deserialize)]
    #[serde(tag = "kind", rename_all = "lowercase")]
    enum X {
        Foo { foobar: String },
        Bar {
            #[serde(skip_serializing_if = "Option::is_none")]
            foobar: Option<f64>, 
            barbaz: String
        }
    }
[0] an enum of numbers would be an issue for instance, though I guess you could always use a `repr(C)` enum it might look a bit odd and naming would be difficult.

remexre|4 years ago

In general, JSON Schemas are (wrongly, in my view...) validation-oriented rather than type-oriented (for notions of types that would be familiar to Haskell, Rust, or Common Lisp programmers).

I think that schema in particular could be represented, though, as:

    enum Thing {
        foo { foobar: String },
        bar { foobar: Option<f32>, barbaz: String },
    }

willtim|4 years ago

Unfortunately Rust is currently lacking structural records/structs and enums. I think they removed them early on in the design. So you'd have to name the all the types. I hope they do add them back one day.