use std::cell::Cell;
use anyhow::Result;
use serde::ser::Error;
use serde::{Serialize, Serializer};
use serde_context::{context_scope, serialize_with_context};
#[derive(Default)]
struct Total(Cell<i32>);
struct Int(i32);
impl Serialize for Int {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
context_scope(|cx| {
let total = cx.get::<Total>().map_err(S::Error::custom)?;
total.0.set(total.0.get() + self.0);
self.0.serialize(serializer)
})
}
}
#[derive(Serialize)]
struct MyInts {
serialized: Vec<Int>,
#[serde(skip)]
_skipped: Vec<Int>,
}
fn main() -> Result<()> {
let total = Total::default();
let value = MyInts {
serialized: vec![Int(1), Int(2), Int(3)],
_skipped: vec![Int(4), Int(5), Int(6)],
};
let mut bytes = Vec::<u8>::new();
let mut serializer = serde_json::Serializer::new(&mut bytes);
serialize_with_context(&value, &mut serializer, &total)?;
assert_eq!(bytes, br#"{"serialized":[1,2,3]}"#);
assert_eq!(total.0.get(), 6);
Ok(())
}