JSON parsing and serialization with Serde in Rust.
# Cargo.toml
[dependencies]
serde = { version = "1", features = ["derive"] }
serde_json = "1"
use serde::{Deserialize, Serialize};
#[derive(Debug, Deserialize)]
pub struct ExchangeInfo {
symbols: Vec<SymbolInfo>,
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")] // All fields: snake_case → camelCase
pub struct SymbolInfo {
symbol: String,
contract_type: String, // Matches "contractType" in JSON
#[serde(rename = "E")] // Specific field rename
event_time: u64,
}
#[derive(Debug, Deserialize)]
#[serde(tag = "filterType")] // Use "filterType" field as discriminator
pub enum Filter {
#[serde(rename = "PRICE_FILTER")]
PriceFilter {
#[serde(rename = "tickSize")]
tick_size: String,
},
#[serde(rename = "LOT_SIZE")]
LotSize {
#[serde(rename = "stepSize")]
step_size: String,
},
#[serde(other)] // Catch-all for unknown variants
Other,
}
⚠️ Note: Don't use
rename_allon enum variants with#[serde(other)]—it can cause conflicts. Use explicit#[serde(rename = "...")]instead.
Usually means:
Nested type missing Deserialize
#[derive(Deserialize)] // ← Add this!
struct Symbol { ... }
API returns different structure than expected
// Debug by printing raw response:
let text = response.text().await?;
println!("{}", text);
Optional field not marked as Option
#[serde(default)] // Use default if missing
description: String,
// OR
description: Option<String>, // None if missing