0

With schemars, it is possible to generate a JSON schema from Rust code.

Consider this JSON example:

{
   "cause" : {
      "type" : "EVT1",
      "payload" : {
         "cause_id" : "ABC-123"
      }
   } 
}

and the Rust code used to generate the schema:

use schemar::JsonSchema;
use serde::Serialize;

#[derive(Serialize, JsonSchema)]
struct Cause {
    _type: EventType,
    payload: EventPayload,
}

#[derive(Serialize, JsonSchema)]
enum EventType {
    EVT1 { param1: String, param2: String },
    EVT2 { param1: String },
}

#[derive(Serialize, JsonSchema)]
enum EventPayload {
    // ?
}

EventType contains the type of event in the name of the variant, and the payload is specified by EventType as well. EventPayload is superfluous.

Is there any possibility to configure serde so that the name of the EventType variant will be used as type, the contents of it as payload? The payload depends on EventType.

What do I expect?

  • _type shall be restricted to the variants of EventType
  • the payload of cause is directly dependant of _type
  • Ideally, the schema generation would use the name of EventType variant as _type, and take the payload from the variants contents.
dtolnay
  • 9,621
  • 5
  • 41
  • 62
nomad
  • 131
  • 1
  • 8
  • From your question it is unclear to me as to what it produces vs what you were expecting. Perhaps you could elaborate and clarify? https://serde.rs/json.html – JGFMK Aug 25 '20 at 11:48
  • the json above is to be expected. I also update the questions. it boils down to use EventType enum to set `_type` and `payload` – nomad Aug 25 '20 at 11:53
  • I am in process of learning Rust myself. I looked at this section of the Github repo: https://github.com/serde-rs/json#getting-help .. Not sure if anything in here helps? https://users.rust-lang.org/t/deserializing-enum-json-field-with-serde-with-multiple-types/5424/2 – JGFMK Aug 25 '20 at 12:04
  • hmm could be an option to have a customer serializer function doing the job. Thanks for the link. – nomad Aug 25 '20 at 12:08
  • @nomad serde directly supports mapping enums: https://serde.rs/enum-representations.html here it looks to me like you want "internal tagging", but you may need to further annotate your structures and enums. You'll need to check if schemars supports internally tagged enums but it would seem insane that it would not. – Masklinn Aug 25 '20 at 12:32
  • yes, I'm also reading through serdes documentation, but again, `EventType` combines both. Maybe there is a need to split it up even further. Currently trying a few things. – nomad Aug 25 '20 at 12:36
  • The duplicates [applied to your situation](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=858bbb72ef5533e62bcece9fa2643891). Specifically, you want the [*adjacently tagged*](https://serde.rs/enum-representations.html#adjacently-tagged) representation. – Shepmaster Aug 25 '20 at 13:28
  • 1
    ahh nice! @shepmaster thank you for providing an example. Will do so in the future as well. I had a struct in between that has generated some confusion. – nomad Aug 25 '20 at 14:12

0 Answers0