100 % lokal — Ihre Daten verlassen nie Ihren Browser

JSON in Rust — serde-Structs, fertig zum Ableiten

Ein JSON-Beispiel in Rust-Structs mit serde-Derives verwandeln. Namen werden snake_case, der Originalschlüssel bleibt — from_str klappt beim ersten Mal.

Sofort Privat Null Cookies

JSON-Eingabe

Rust-Ausgabe

Was dieses Werkzeug tut

Aus einer JSON-Probe werden Rust-Structs mit serde-Ableitungen.

{ "id": 1, "firstName": "Ada", "address": { "city": "Paris" } }
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
pub struct Root {
    pub id: i64,
    #[serde(rename = "firstName")]
    pub first_name: String,
    pub address: Address,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Address {
    pub city: String,
}

Rust-Feldnamen stehen in snake_case, also wird firstName zu first_name — und #[serde(rename)] bewahrt den Schlüssel, denn ein Struct, das sein eigenes JSON nicht mehr liest, wäre schlimmer als ein unidiomatischer Name. Das rename erscheint nur dort, wo die beiden auseinandergehen.

Lesen Sie die Nutzlast nur, gibt Ihnen die Option ohne Serialize ein #[derive(Debug, Deserialize)] und einen Trait weniger zu erfüllen.

Schlüsselwörter, roh oder mit Unterstrich

{ "type": "user", "self": "/users/1" }
    pub r#type: String,
    #[serde(rename = "self")]
    pub self_: String,

r#type ist ein roher Bezeichner: serde serialisiert ihn ohnehin als type, ein Attribut braucht es nicht. self gehört zu den wenigen Wörtern, die Rust nicht einmal als rohen Bezeichner zulässt — self, Self, crate, super — und bekommt daher einen Unterstrich und ein rename.

Was aus serde_json kommt

null, unbekannte Werte, leere Arrays und gemischte Arrays landen alle bei serde_json::Value:

    pub nickname: Option<serde_json::Value>,
    pub tags: Vec<serde_json::Value>,

serde_json gehört also in Ihre Cargo.toml, neben serde mit dem Feature derive. Der Pfad steht vollständig da, statt importiert zu werden, was die Ausgabe gültig hält, wie Ihre Module auch aufgebaut sind.

Was eine Probe nicht sagen kann

Nur null erzeugt ein Option. Alles andere ist Pflicht, weil das Dokument einen Wert hatte — und „manchmal fehlend“ kann ein Dokument nicht zeigen. Ein Feld in Option<T> zu hüllen ist die eine Änderung; #[serde(default)] die andere, wenn Abwesenheit den Vorgabewert bedeuten soll statt eines Fehlers.

Zwei Schlüssel mit demselben snake_case — fooBar und foo_bar — bekommen ein Suffix statt verschmolzen zu werden, und jeder behält sein eigenes rename.

Datenschutz ab Werk

Alles läuft lokal in deinem Browser mit JavaScript. Deine Daten werden nie hochgeladen, wodurch das Tool auch für sensible Inhalte sicher ist und offline funktioniert.

Häufige Fragen

Was brauche ich in Cargo.toml?
`serde` mit dem Feature `derive`, und `serde_json`, sobald ein Feld einen unbekannten Wert trägt: `Option<serde_json::Value>` und `Vec<serde_json::Value>` stammen aus dieser Crate. Die Ausgabe benutzt den vollen Pfad, statt sie zu importieren, damit nichts bricht, wenn Sie sie anders benennen.
Wie wird ein Schlüssel namens `type` oder `self` behandelt?
`type` wird zum rohen Bezeichner `r#type`, den serde als `type` serialisiert — kein Attribut nötig. `self` kann überhaupt kein roher Bezeichner sein, also wird daraus `self_` mit `#[serde(rename = "self")]`, das den Schlüssel bewahrt. Beide Fälle stehen so da, wie der Compiler sie annimmt.
Warum ist meine zwanzigstellige Kennung ein `i64`?
Weil das Rusts natürliche Ganzzahl für JSON ist und bis etwa 9,2 × 10¹⁸ reicht. Eine längere passt nicht: serde_json meldet beim Deserialisieren einen Fehler, statt abzuschneiden. Ist das Feld eine Snowflake-ID, bringt `u64` ein Bit mehr, und `String` ist, was die meisten APIs ohnehin erwarten.

Ähnliche Konverter