relay_event_normalization/eap/
size.rs1use relay_event_schema::protocol::{Attribute, Attributes};
2use relay_protocol::{Annotated, Value};
3
4pub fn attributes_size(attributes: &Attributes) -> usize {
16 attributes
17 .0
18 .iter()
19 .map(|(k, v)| k.len() + attribute_size(v))
20 .sum()
21}
22
23pub fn attribute_size(v: &Annotated<Attribute>) -> usize {
28 v.value().map(|v| &v.value.value).map_or(0, value_size)
29}
30
31pub fn value_size(v: &Annotated<Value>) -> usize {
33 let Some(v) = v.value() else {
34 return 0;
35 };
36
37 match v {
38 Value::Bool(_) => 1,
39 Value::I64(_) => 8,
40 Value::U64(_) => 8,
41 Value::F64(_) => 8,
42 Value::String(v) => v.len(),
43 Value::Array(v) => v.iter().map(value_size).sum(),
44 Value::Object(v) => v.iter().map(|(k, v)| k.len() + value_size(v)).sum(),
45 }
46}
47
48#[cfg(test)]
49mod tests {
50 use relay_protocol::{Error, Object};
51
52 use super::*;
53
54 #[test]
55 fn test_value_size_basic() {
56 assert_eq!(value_size(&Value::Bool(true).into()), 1);
57 assert_eq!(value_size(&Value::Bool(false).into()), 1);
58 assert_eq!(value_size(&Value::I64(0).into()), 8);
59 assert_eq!(value_size(&Value::I64(i64::MIN).into()), 8);
60 assert_eq!(value_size(&Value::I64(i64::MAX).into()), 8);
61 assert_eq!(value_size(&Value::U64(0).into()), 8);
62 assert_eq!(value_size(&Value::U64(u64::MIN).into()), 8);
63 assert_eq!(value_size(&Value::U64(u64::MAX).into()), 8);
64 assert_eq!(value_size(&Value::F64(123.42).into()), 8);
65 assert_eq!(value_size(&Value::F64(f64::MAX).into()), 8);
66 assert_eq!(value_size(&Value::F64(f64::MIN).into()), 8);
67 assert_eq!(value_size(&Value::F64(f64::NAN).into()), 8);
68 assert_eq!(value_size(&Value::F64(f64::NEG_INFINITY).into()), 8);
69 assert_eq!(value_size(&Value::String("foobar".to_owned()).into()), 6);
70 assert_eq!(value_size(&Value::String("ඞ".to_owned()).into()), 3);
71 assert_eq!(value_size(&Value::String("".to_owned()).into()), 0);
72 }
73
74 #[test]
75 fn test_value_size_array() {
76 let array = Value::Array(vec![
77 Annotated::empty(),
78 Annotated::new(Value::Bool(true)),
79 Annotated::new(Value::Bool(false)),
80 Annotated::from_error(Error::invalid("oops"), Some(Value::U64(0))),
81 Annotated::new(Value::String("42".to_owned())),
82 Annotated::new(Value::Array(vec![])),
83 Annotated::new(Value::Array(vec![
84 Annotated::new(Value::Array(vec![Annotated::new(Value::Bool(false))])),
85 Annotated::new(Value::Object(Object::from([
86 ("ඞ".to_owned(), Annotated::new(Value::I64(3))),
87 ("empty_key".to_owned(), Annotated::empty()),
88 ]))),
89 Annotated::empty(),
90 ])),
91 ]);
92
93 assert_eq!(value_size(&array.into()), 25);
94 }
95
96 #[test]
97 fn test_value_size_object() {
98 let obj = Value::Object(Object::from([
99 ("".to_owned(), Annotated::new(Value::Bool(false))),
100 ("1".to_owned(), Annotated::new(Value::Bool(false))),
101 ("ඞ".to_owned(), Annotated::empty()),
102 (
103 "key".to_owned(),
104 Annotated::new(Value::Object(Object::from([
105 (
106 "foo".to_owned(),
107 Annotated::new(Value::Array(vec![
108 Annotated::new(Value::I64(21)),
109 Annotated::new(Value::F64(42.0)),
110 ])),
111 ),
112 ("bar".to_owned(), Annotated::empty()),
113 ]))),
114 ),
115 ]));
116
117 assert_eq!(value_size(&obj.into()), 31);
118 }
119
120 macro_rules! assert_calculated_size_of {
121 ($expected:expr, $json:expr) => {{
122 let json = $json;
123
124 let attrs = Annotated::<Attributes>::from_json(json)
125 .unwrap()
126 .into_value()
127 .unwrap();
128
129 let size = attributes_size(&attrs);
130 assert_eq!(size, $expected, "attrs: {json}");
131 }};
132 }
133
134 #[test]
135 fn test_attributes_size_full() {
136 assert_calculated_size_of!(
137 82,
138 r#"{
139 "k1": {
140 "value": "string value",
141 "type": "string"
142 },
143 "k2": {
144 "value": 18446744073709551615,
145 "type": "integer"
146 },
147 "k3": {
148 "value": 42.01234567891234567899,
149 "type": "double"
150 },
151 "k4": {
152 "value": false,
153 "type": "boolean"
154 },
155 "k5": {
156 "value": {
157 "nested": {
158 "array": [1.0, 2, -12, "7 bytes", false]
159 }
160 },
161 "type": "not yet supported"
162 }
163 }"#
164 );
165 }
166}