Ich möchte Serde verwenden, um einige JSON als Teil einer HTTP-PATCH-Anfrage zu analysieren. Da PATCH-Anforderungen nicht das gesamte Objekt übergeben, sondern nur die relevanten zu aktualisierenden Daten, muss ich zwischen einem Wert, der nicht übergeben wurde, einem Wert, der explizit auf null
gesetzt wurde, und einem Wert, der vorhanden ist, unterscheiden.Wie kann ich unterscheiden zwischen einem deserialisierten Feld, das fehlt, und einem, das null ist?
Ich habe einen Wert Objekt mit mehreren Nullable-Felder:
struct Resource {
a: Option<i32>,
b: Option<i32>,
c: Option<i32>,
}
Wenn der Kunde diese JSON wie einreicht:
{"a": 42, "b": null}
Ich möchte a
-Some(42)
, b
-None
ändern, und lassen Sie c
unverändert.
Ich habe versucht, jedes Feld in einer weiteren Ebene von Option
Verpackung:
#[derive(Debug, Deserialize)]
struct ResourcePatch {
a: Option<Option<i32>>,
b: Option<Option<i32>>,
c: Option<Option<i32>>,
}
Aber das unterscheidet nicht zwischen b
und c
machen; beide sind None
aber ich hätte b
gewünscht, Some(None)
zu sein.
Ich bin nicht an diese Darstellung verschachtelt gebunden Option
s; Jede Lösung, die die 3 Fälle unterscheiden kann, wäre in Ordnung, wie eine, die eine benutzerdefinierte Aufzählung verwendet.
"Idealerweise würde die Implementierung von' Deserialize' für 'Patch' das komplett behandeln." Meine Annahme ist bisher, dass dies unmöglich ist. Von dem Moment an, in dem Sie versuchen, einen 'Patch' zu deserialisieren, erwarten Sie, dass der Wert in seiner serialisierten Form existiert. Im Gegensatz dazu existiert "Patch :: Missing" durch seine "Nichtexistenz" in unserem Container (Sie können "Patch :: Missing" nicht selbstständig zu JSON serialisieren). AFAIK a 'Serialize' kann nicht wählen, nicht serialisiert zu werden, noch kann es dem Container mitteilen, diesen Teil des Prozesses zu überspringen. –
Nun, eigentlich ist mein vorheriger Kommentar eher auf die Serialisierung und nicht auf die Deserialisierung anwendbar. Unabhängig davon ist die Logik etwas dual: 'Deserialize' kann dem' Deserializer' nicht erlauben, Werte zu deserialisieren, die er nicht finden kann. Wenn wir ein leeres Objekt '{}' haben, können die Implementierungen von 'Deserialize' nichts dagegen tun, aber der Deserializer kann, sobald er weiß, dass er einen Standard ausfüllt. –