1use itertools::Itertools;
2use postcard::experimental::serialized_size;
3use rustc_hash::FxHashMap as HashMap;
4use serde::Serialize;
5
6pub trait SerializedSize: Serialize {
7 fn accumulate_size(&self, field: &[&'static str], into: &mut HashMap<Vec<&'static str>, usize>);
8
9 fn report_size(&self) {
10 let total_size = serialized_size(self).unwrap();
11 let mut into = HashMap::default();
12 self.accumulate_size(&[], &mut into);
13
14 for (name, size) in into
15 .iter()
16 .sorted_by_key(|(k, _)| (k.len(), k.last().unwrap_or(&"")))
17 {
18 let ratio = ((*size as f32 / total_size as f32) * 100.).round();
19 println!("{}: {} ({})", name.iter().join("."), size, ratio);
20 }
21 }
22}
23
24pub fn add_field<T: Serialize>(
25 outer_path: &[&'static str],
26 field_name: &'static str,
27 t: &T,
28 into: &mut HashMap<Vec<&'static str>, usize>,
29) {
30 let mut path = outer_path.to_vec();
31 path.push(field_name);
32 *into.entry(path).or_default() += postcard::experimental::serialized_size(t).unwrap();
33}