1use serde_json::Value;
37use std::mem::size_of;
38
39const STRING_OVERHEAD: usize = size_of::<String>();
40const MAP_ENTRY_OVERHEAD: usize = size_of::<usize>() * 3;
41
42pub fn sizeof_val(v: &Value) -> usize {
43 size_of::<Value>()
44 + match v {
45 Value::Null => 0,
46 Value::Bool(_) => 0,
47 Value::Number(_) => 0, Value::String(s) => STRING_OVERHEAD + s.capacity(),
49 Value::Array(a) => a.iter().map(sizeof_val).sum(),
50 Value::Object(o) => o
51 .iter()
52 .map(|(k, v)| STRING_OVERHEAD + k.capacity() + sizeof_val(v) + MAP_ENTRY_OVERHEAD)
53 .sum(),
54 }
55}
56
57#[cfg(test)]
58
59mod tests {
60 use super::*;
61 use serde_json::json;
62
63 #[test]
64 fn test_sizeof_val_null() {
65 let val = json!(null);
66 assert_eq!(sizeof_val(&val), std::mem::size_of::<serde_json::Value>());
67 }
68
69 #[test]
70 fn test_sizeof_val_bool() {
71 let val = json!(true);
72 assert_eq!(sizeof_val(&val), std::mem::size_of::<serde_json::Value>());
73 }
74
75 #[test]
76 fn test_sizeof_val_number() {
77 let val = json!(42);
78 assert_eq!(sizeof_val(&val), std::mem::size_of::<serde_json::Value>());
79 }
80
81 #[test]
82 fn test_sizeof_val_string() {
83 let val = json!("Hello, world!");
84 let expected_size = std::mem::size_of::<serde_json::Value>()
85 + String::from("Hello, world!").capacity()
86 + STRING_OVERHEAD;
87 assert_eq!(sizeof_val(&val), expected_size);
88 }
89
90 #[test]
91 fn test_sizeof_val_array() {
92 let val = json!([1, 2, 3]);
93 let expected_size = std::mem::size_of::<serde_json::Value>()
94 + sizeof_val(&json!(1))
95 + sizeof_val(&json!(2))
96 + sizeof_val(&json!(3));
97 assert_eq!(sizeof_val(&val), expected_size);
98 }
99
100 #[test]
101 fn test_sizeof_val_object() {
102 let val = json!({"key": "value"});
103 let expected_size = std::mem::size_of::<serde_json::Value>()
104 + String::from("key").capacity()
105 + sizeof_val(&json!("value"))
106 + std::mem::size_of::<String>()
107 + std::mem::size_of::<usize>() * 3;
108 assert_eq!(sizeof_val(&val), expected_size);
109 }
110
111 #[test]
112 fn test_sizeof_val_complex_object() {
113 let val = json!({
114 "name": "json_size",
115 "details": {"year": 2022, "version": "v4"}
116 });
117 let expected_size = std::mem::size_of::<serde_json::Value>()
118 + String::from("name").capacity()
119 + sizeof_val(&json!("json_size"))
120 + String::from("details").capacity()
121 + sizeof_val(&json!({"year": 2022, "version": "v4"}))
122 + std::mem::size_of::<String>() * 2
123 + std::mem::size_of::<usize>() * 6; assert_eq!(sizeof_val(&val), expected_size);
125 }
126}