Anonymous user
JSON: Difference between revisions
→{{header|Rust}}
Thundergnat (talk | contribs) (Rename Perl 6 -> Raku, alphabetize, minor clean-up) |
|||
Line 3,465:
=={{header|Rust}}==
Serializing and deserializing JSON in Rust is done by libraries.
{{works with|Rust|1.31}}
{{libheader|Serde|1.0}}
<lang toml>[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"</lang>
Serde is a general serialization/deserialization library. Serde-JSON implements JSON serialization for Serde.
Using said library is quite straight forward, one simply derives <code>Serialize</code>/<code>Deserialize</code> onto the types they want to convert into and from JSON strings.
<lang rust>use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, Debug)]
struct Point {
x: i32,
y: i32,
}</lang>
Said type could then be used as such:
<lang rust>fn main() {
let point = Point { x: 1, y: 2 };
let serialized = serde_json::to_string(&point).unwrap();
let deserialized: Point = serde_json::from_str(&serialized).unwrap();
println!("serialized = {}", serialized);
println!("deserialized = {:?}", deserialized);
}</lang>
The result of which is type-checked JSON (where extra entries get ignored), without need of a key-value container.
{{out}}
<pre>serialized = {"x":1,"y":2}
deserialized = Point { x: 1, y: 2 }</pre>
It also handles more Rust specific types like enums, tuples, struct tuples, and zero-sized types.
<lang rust>#[derive(Serialize, Deserialize)]
struct W { a: i32, b: i32 } // => { "a": 0, "b": 0 }
#[derive(Serialize, Deserialize)]
struct X(i32, i32); // => [0, 0]
#[derive(Serialize, Deserialize)]
struct Y(i32); // => 0
#[derive(Serialize, Deserialize)]
struct Z; // => null
#[derive(Serialize, Deserialize)]
enum E {
W { a: i32, b: i32 }, // => { "W": { "a": 0, "b": 0 } }
X(i32, i32), // => { "X": [0, 0] }
Y(i32), // => { "Y": 0 }
Z, // => { "Z" }
}</lang>
The traits are also implemented for <code>HashMap</code> and <code>Vec</code> which can be used as conventional objects/arrays, on top of macros and <code>serde_json::Value</code> to handle all other potentially weird edge cases.
<lang rust>use std::collections::HashMap;
use serde_json::Value;
#[derive(Serialize, Deserialize)]
struct Data {
points: Vec<Points>,
#[serde(flatten)]
metadata: HashMap<String, Value>,
}</lang>
In this example <code>metadata</code> would simply capture all other additional entries, for example:
<lang rust>fn main() {
let data = {
let mut metadata = HashMap::new();
metadata.insert("triangle".to_string(), Value::Number(3.into()));
metadata.insert("square".to_string(), Value::Bool(false));
Data {
points: vec![Point { x: 1, y: 2 }, Point { x: 15, y: 32 }],
metadata,
}
};
let serialized = serde_json::to_string(&data).unwrap();
let deserialized: Data = serde_json::from_str(&serialized).unwrap();
println!("serialized = {}", serialized);
println!("deserialized = {:?}", deserialized);
}</lang>
{{out}}
<pre>serialized = {"points":[{"x":1,"y":2},{"x":15,"y":32}],"square":false,"triangle":3}
deserialized = Data { points: [Point { x: 1, y: 2 }, Point { x: 15, y: 32 }], metadata: {"triangle": Number(3), "square": Bool(false)} }
</pre>
=={{header|Scala}}==
|