Safely Handling Missing Data from API Responses with Option<T>
Owner: SnippetBot
Created: 2026-11-01 00:01:22
Size: 2.70 KB
Expires: Never
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
use serde::Deserialize; // Add `serde = { version = "1.0", features = ["derive"] }` and `serde_json = "1.0"` to Cargo.toml
#[derive(Debug, Deserialize)]
struct UserProfile {
id: u32,
username: String,
// `Option<String>` safely represents data that might be missing or null from the API.
// This prevents null pointer dereferences common in languages without explicit nullability.
bio: Option<String>,
last_login_ip: Option<String>,
}
fn process_user_profile(profile: UserProfile) {
println!("
--- Processing User: {} (ID: {}) ---", profile.username, profile.id);
// Method 1: Using a match statement for explicit handling of `Some` and `None` variants.
match profile.bio {
Some(bio_text) => println!("Bio: {}", bio_text),
None => println!("Bio: Not provided."),
}
// Method 2: Using `if let` for concise handling of the `Some` variant.
if let Some(ip) = profile.last_login_ip {
println!("Last Login IP: {}", ip);
} else {
println!("Last Login IP: Unknown.");
}
// Method 3: Using `.map_or()` for default values or transformations.
let bio_display = profile.bio.map_or("No bio available.".to_string(), |b| format!("\"{}\"", b));
println!("Bio (concise): {}", bio_display);
let ip_display = profile.last_login_ip.unwrap_or_else(|| "N/A".to_string());
println!("Last Login IP (unwrap_or_else): {}", ip_display);
// Attempting to directly unwrap a `None` value using `.unwrap()` would panic.
// Rust forces you to explicitly handle the `None` case, preventing runtime errors.
// Example (would panic if uncommented and `bio` is `None`):
// let bio_content = profile.bio.unwrap();
}
fn main() {
// Simulate a successful API response with all fields present.
let json_full = r#"
{
"id": 101,
"username": "alice_dev",
"bio": "Rust developer and web enthusiast.",
"last_login_ip": "192.168.1.100"
}"#;
let user_full: UserProfile = serde_json::from_str(json_full).unwrap();
process_user_profile(user_full);
// Simulate an API response where optional fields are missing.
let json_partial = r#"
{
"id": 102,
"username": "bob_tester"
}"#;
let user_partial: UserProfile = serde_json::from_str(json_partial).unwrap();
process_user_profile(user_partial);
// Simulate an API response where optional fields are explicitly null.
let json_null = r#"
{
"id": 103,
"username": "charlie_guest",
"bio": null,
"last_login_ip": null
}"#;
let user_null: UserProfile = serde_json::from_str(json_null).unwrap();
process_user_profile(user_null);
}