use serde::de::{self, SeqAccess, Visitor}; use serde::{Deserialize, Deserializer}; use std::marker::PhantomData; use std::{cmp, fmt}; #[derive(Deserialize)] struct Outer { id: String, // Deserialize this field by computing the maximum value of a sequence // (JSON array) of values. #[serde(deserialize_with = "deserialize_max")] // Despite the struct field being named `max_value`, it is going to come // from a JSON field called `values`. #[serde(rename(deserialize = "values"))] max_value: u64, } /// Deserialize the maximum of a sequence of values. The entire sequence /// is not buffered into memory as it would be if we deserialize to Vec /// and then compute the maximum later. /// /// This function is generic over T which can be any type that implements /// Ord. Above, it is used with T=u64. fn deserialize_max<'de, T, D>(deserializer: D) -> Result where T: Deserialize<'de> + Ord, D: Deserializer<'de>, { struct MaxVisitor(PhantomData T>); impl<'de, T> Visitor<'de> for MaxVisitor where T: Deserialize<'de> + Ord, { /// Return type of this visitor. This visitor computes the max of a /// sequence of values of type T, so the type of the maximum is T. type Value = T; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("a nonempty sequence of numbers") } fn visit_seq(self, mut seq: S) -> Result where S: SeqAccess<'de>, { // Start with max equal to the first value in the seq. let mut max = seq.next_element()?.ok_or_else(|| // Cannot take the maximum of an empty seq. de::Error::custom("no values in seq when looking for maximum"))?; // Update the max while there are additional values. while let Some(value) = seq.next_element()? { max = cmp::max(max, value); } Ok(max) } } // Create the visitor and ask the deserializer to drive it. The // deserializer will call visitor.visit_seq() if a seq is present in // the input data. let visitor = MaxVisitor(PhantomData); deserializer.deserialize_seq(visitor) } fn main() { let j = r#" { "id": "demo-deserialize-max", "values": [ 256, 100, 384, 314, 271 ] } "#; let out: Outer = serde_json::from_str(j).unwrap(); // Prints "max value: 384" println!("max value: {}", out.max_value); }