Serde JSON Stream Array Deserializer
Parse large JSON arrays incrementally with serde_json StreamDeserializer, yielding items as they arrive and isolating bad elements.
Code
use serde::Deserialize;
use serde_json::Deserializer;
use std::io::Cursor;
#[derive(Debug, Deserialize)]
struct Reading {
sensor: String,
celsius: f32,
}
fn parse_array_items(raw: &str) -> (Vec<Reading>, usize) {
// 逐元素反序列化:坏元素跳过并计数
let mut items = Vec::new();
let mut rejected = 0;
let mut de = Deserializer::from_str(trim_brackets(raw)).into_iter::<Reading>();
while let Some(result) = de.next() {
match result {
Ok(reading) => items.push(reading),
Err(_) => rejected += 1,
}
}
(items, rejected)
}
fn trim_brackets(raw: &str) -> &str {
let trimmed = raw.trim();
let body = trimmed
.strip_prefix('[')
.and_then(|s| s.strip_suffix(']'))
.unwrap_or(trimmed);
body
}
fn main() {
let payload = r#"[
{"sensor":"hall-1","celsius":21.4},
{"sensor":"hall-2","celsius":20.9},
{"sensor":"hall-3","celsius":"not-a-number"},
{"sensor":"hall-4","celsius":22.1}
]"#;
let (items, rejected) = parse_array_items(payload);
for reading in &items {
println!("{} -> {:.1}C", reading.sensor, reading.celsius);
}
println!("parsed: {}, rejected: {}", items.len(), rejected);
// Cursor 演示从 Reader 流式消费同一结构
let cursor = Cursor::new(trim_brackets(payload).as_bytes().to_vec());
let stream = Deserializer::from_reader(cursor).into_iter::<Reading>();
println!("reader-based count: {}", stream.filter_map(|r| r.ok()).count());
}Report a problem with this exampleOpens a pre-filled issue on GitHub.