Rust
Option and default
Learn Option fields and default values.
Option and default
In real data some fields may be missing. Option<T> fields become None if missing; #[serde(default)] puts the type's default into a missing field. When writing, skip_serializing_if is used to skip None fields:
#[derive(Serialize, Deserialize)]
struct Profil {
ad: String,
#[serde(skip_serializing_if = "Option::is_none")]
sehir: Option<String>,
#[serde(default)]
puan: u32, // 0 if missing from the JSON
}
Skipping by hand
To build the same behaviour by hand, we collect the fields in a list and add only the filled ones:
fn json(&self) -> String {
let mut alanlar = vec![format!("\"ad\":\"{}\"", self.ad)];
if let Some(s) = &self.sehir {
alanlar.push(format!("\"sehir\":\"{}\"", s));
}
format!("{{{}}}", alanlar.join(","))
}
format!("{{{}}}", ..): the outer {{ and }} are literal braces, the middle {} is a placeholder.
Exercise Optional city
Write the json method above for Profil { ad: String, sehir: Option<String> }, skipping a None city. Print the profiles Ece (no city) and Can (İzmir) on separate lines.
Show example solution
struct Profil {
ad: String,
sehir: Option<String>,
}
impl Profil {
fn json(&self) -> String {
let mut alanlar = vec![format!("\"ad\":\"{}\"", self.ad)];
if let Some(s) = &self.sehir {
alanlar.push(format!("\"sehir\":\"{}\"", s));
}
format!("{{{}}}", alanlar.join(","))
}
}
fn main() {
let a = Profil { ad: "Ece".into(), sehir: None };
let b = Profil { ad: "Can".into(), sehir: Some("İzmir".into()) };
println!("{}", a.json());
println!("{}", b.json());
}
Test yourself
-
Without <code>skip_serializing_if</code>, how is <code>sehir: None</code> written?
- It errors
- "sehir":null
- It isn't written at all
- "sehir":""
Show answer
"sehir":null — serde turns None into JSON null; skipping the field entirely needs skip_serializing_if.
-
Default value
#[serde(____)]
puan: u32, // JSON'da yoksa 0
Show answer
#[serde(default)]
puan: u32, // JSON'da yoksa 0
-
Attribute and effect
- Option<T>
- None if missing
- #[serde(default)]
- Default if missing
- skip_serializing_if
- Skip by condition
- #[serde(skip)]
- Never write/read
Next lesson: Summary - Serde