JSON: Difference between revisions

2,740 bytes added ,  4 years ago
(Rename Perl 6 -> Raku, alphabetize, minor clean-up)
Line 3,465:
 
=={{header|Rust}}==
Serializing and deserializing JSON in Rust is done by libraries.
<lang rust>extern crate rustc_serialize;
{{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.
use rustc_serialize::json;
 
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.
#[derive(RustcDecodable, RustcEncodable)]
 
struct Penguin {
<lang rust>use serde::{Serialize, Deserialize};
name : String,
 
born : i16
#[derive(Serialize, Deserialize, Debug)]
}
struct Point {
fn main() {
x: i32,
let pengu = Penguin { name : "pengu".to_string(), born : 1999 };
y: i32,
println!("{}", json::encode(&pengu).unwrap());
}</lang>
let pingu : Penguin = json::decode(r##"{"name":"pingu","born":2001}"##).unwrap();
 
assert_eq!(&pingu.name, "pingu");
Said type could then be used as such:
assert_eq!(pingu.born, 2001);
 
<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}
<pre>{"name":"pengu","born":1999}</pre>
deserialized = Data { points: [Point { x: 1, y: 2 }, Point { x: 15, y: 32 }], metadata: {"triangle": Number(3), "square": Bool(false)} }
</pre>
 
=={{header|Scala}}==
Anonymous user