1use std::fmt::Display;
16
17use opentelemetry_proto::tonic::common::v1::any_value::Value::{
18 ArrayValue, BoolValue, BytesValue, DoubleValue, IntValue, KvlistValue, StringValue,
19};
20use opentelemetry_proto::tonic::common::v1::{AnyValue, KeyValue};
21use serde::ser::{SerializeMap, SerializeSeq};
22use serde::Serialize;
23
24use crate::otlp::utils::key_value_to_jsonb;
25
26#[derive(Clone, Debug)]
27pub struct OtlpAnyValue<'a>(&'a AnyValue);
28
29impl<'a> From<&'a AnyValue> for OtlpAnyValue<'a> {
30 fn from(any_val: &'a AnyValue) -> Self {
31 Self(any_val)
32 }
33}
34
35impl OtlpAnyValue<'_> {
36 pub fn none() -> Self {
37 Self(&AnyValue { value: None })
38 }
39}
40
41impl Display for OtlpAnyValue<'_> {
43 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
44 if let Some(StringValue(v)) = &self.0.value {
45 write!(f, "{v}")
46 } else {
47 write!(f, "{}", serde_json::to_string(self).unwrap_or_default())
48 }
49 }
50}
51
52impl Serialize for OtlpAnyValue<'_> {
53 fn serialize<S>(&self, zer: S) -> Result<S::Ok, S::Error>
54 where
55 S: serde::Serializer,
56 {
57 match &self.0.value {
58 Some(val) => match &val {
59 StringValue(v) => zer.serialize_str(v),
60 BoolValue(v) => zer.serialize_bool(*v),
61 IntValue(v) => zer.serialize_i64(*v),
62 DoubleValue(v) => zer.serialize_f64(*v),
63 ArrayValue(v) => {
64 let mut seq = zer.serialize_seq(Some(v.values.len()))?;
65 for val in &v.values {
66 seq.serialize_element(&OtlpAnyValue::from(val))?;
67 }
68 seq.end()
69 }
70 KvlistValue(v) => {
71 let mut map = zer.serialize_map(Some(v.values.len()))?;
72 for kv in &v.values {
73 match &kv.value {
74 Some(val) => map.serialize_entry(&kv.key, &OtlpAnyValue::from(val))?,
75 None => map.serialize_entry(&kv.key, &OtlpAnyValue::none())?,
76 }
77 }
78 map.end()
79 }
80 BytesValue(v) => zer.serialize_bytes(v),
81 },
82 None => zer.serialize_none(),
83 }
84 }
85}
86
87#[derive(Debug, Clone)]
88pub struct Attributes(Vec<KeyValue>);
89
90impl Display for Attributes {
91 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
92 write!(f, "{}", serde_json::to_string(self).unwrap_or_default())
93 }
94}
95
96impl Serialize for Attributes {
97 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
98 where
99 S: serde::Serializer,
100 {
101 let mut map = serializer.serialize_map(Some(self.0.len()))?;
102 for attr in &self.0 {
103 match &attr.value {
104 Some(val) => map.serialize_entry(&attr.key, &OtlpAnyValue::from(val))?,
105 None => map.serialize_entry(&attr.key, &OtlpAnyValue::none())?,
106 }
107 }
108 map.end()
109 }
110}
111
112impl From<Vec<KeyValue>> for Attributes {
113 fn from(attrs: Vec<KeyValue>) -> Self {
114 Self(attrs)
115 }
116}
117
118impl From<&[KeyValue]> for Attributes {
119 fn from(attrs: &[KeyValue]) -> Self {
120 Self(attrs.to_vec())
121 }
122}
123
124impl From<Attributes> for jsonb::Value<'static> {
125 fn from(attrs: Attributes) -> jsonb::Value<'static> {
126 key_value_to_jsonb(attrs.0)
127 }
128}
129
130impl Attributes {
131 pub fn take(self) -> Vec<KeyValue> {
132 self.0
133 }
134
135 pub fn get_ref(&self) -> &Vec<KeyValue> {
136 &self.0
137 }
138
139 pub fn get_mut(&mut self) -> &mut Vec<KeyValue> {
140 &mut self.0
141 }
142}
143
144#[cfg(test)]
145mod tests {
146 use opentelemetry_proto::tonic::common::v1::any_value::Value;
147 use opentelemetry_proto::tonic::common::v1::{AnyValue, ArrayValue, KeyValue, KeyValueList};
148
149 use crate::otlp::trace::attributes::{Attributes, OtlpAnyValue};
150
151 #[test]
152 fn test_null_value() {
153 let otlp_value = OtlpAnyValue::from(&AnyValue { value: None });
154 assert_eq!("null", serde_json::to_string(&otlp_value).unwrap())
155 }
156
157 #[test]
158 fn test_otlp_any_value_display() {
159 let values = vec![
160 (
161 "string value",
162 Value::StringValue(String::from("string value")),
163 ),
164 ("true", Value::BoolValue(true)),
165 ("1", Value::IntValue(1)),
166 ("1.1", Value::DoubleValue(1.1)),
167 ("[1,2,3]", Value::BytesValue(vec![1, 2, 3])),
168 ];
169
170 for (expect, val) in values {
171 let any_value = AnyValue { value: Some(val) };
172 let otlp_value = OtlpAnyValue::from(&any_value);
173 assert_eq!(expect, otlp_value.to_string());
174 }
175 }
176
177 #[test]
178 fn test_any_value_primitive_type_serialize() {
179 let values = vec![
180 (
181 r#""string value""#,
182 Value::StringValue(String::from("string value")),
183 ),
184 ("true", Value::BoolValue(true)),
185 ("1", Value::IntValue(1)),
186 ("1.1", Value::DoubleValue(1.1)),
187 ("[1,2,3]", Value::BytesValue(vec![1, 2, 3])),
188 ];
189
190 for (expect, val) in values {
191 let any_val = AnyValue { value: Some(val) };
192 let otlp_value = OtlpAnyValue::from(&any_val);
193 assert_eq!(expect, serde_json::to_string(&otlp_value).unwrap());
194 }
195 }
196
197 #[test]
198 fn test_any_value_array_type_serialize() {
199 let values = vec![
200 ("[]", vec![]),
201 ("[null]", vec![AnyValue { value: None }]),
202 (
203 r#"["string1","string2","string3"]"#,
204 vec![
205 AnyValue {
206 value: Some(Value::StringValue(String::from("string1"))),
207 },
208 AnyValue {
209 value: Some(Value::StringValue(String::from("string2"))),
210 },
211 AnyValue {
212 value: Some(Value::StringValue(String::from("string3"))),
213 },
214 ],
215 ),
216 (
217 "[1,2,3]",
218 vec![
219 AnyValue {
220 value: Some(Value::IntValue(1)),
221 },
222 AnyValue {
223 value: Some(Value::IntValue(2)),
224 },
225 AnyValue {
226 value: Some(Value::IntValue(3)),
227 },
228 ],
229 ),
230 (
231 "[1.1,2.2,3.3]",
232 vec![
233 AnyValue {
234 value: Some(Value::DoubleValue(1.1)),
235 },
236 AnyValue {
237 value: Some(Value::DoubleValue(2.2)),
238 },
239 AnyValue {
240 value: Some(Value::DoubleValue(3.3)),
241 },
242 ],
243 ),
244 (
245 "[true,false,true]",
246 vec![
247 AnyValue {
248 value: Some(Value::BoolValue(true)),
249 },
250 AnyValue {
251 value: Some(Value::BoolValue(false)),
252 },
253 AnyValue {
254 value: Some(Value::BoolValue(true)),
255 },
256 ],
257 ),
258 (
259 r#"[1,1.1,"str_value",true,null]"#,
260 vec![
261 AnyValue {
262 value: Some(Value::IntValue(1)),
263 },
264 AnyValue {
265 value: Some(Value::DoubleValue(1.1)),
266 },
267 AnyValue {
268 value: Some(Value::StringValue("str_value".into())),
269 },
270 AnyValue {
271 value: Some(Value::BoolValue(true)),
272 },
273 AnyValue { value: None },
274 ],
275 ),
276 ];
277
278 for (expect, values) in values {
279 let any_val = AnyValue {
280 value: Some(Value::ArrayValue(ArrayValue { values })),
281 };
282 let otlp_value = OtlpAnyValue::from(&any_val);
283 assert_eq!(expect, serde_json::to_string(&otlp_value).unwrap());
284 }
285 }
286
287 #[test]
288 fn test_any_value_map_type_serialize() {
289 let cases = vec![
290 ("{}", vec![]),
291 (
292 r#"{"key1":null}"#,
293 vec![KeyValue {
294 key: "key1".into(),
295 value: None,
296 }],
297 ),
298 (
299 r#"{"key1":null}"#,
300 vec![KeyValue {
301 key: "key1".into(),
302 value: Some(AnyValue { value: None }),
303 }],
304 ),
305 (
306 r#"{"key1":"val1"}"#,
307 vec![KeyValue {
308 key: "key1".into(),
309 value: Some(AnyValue {
310 value: Some(Value::StringValue(String::from("val1"))),
311 }),
312 }],
313 ),
314 ];
315
316 for (expect, values) in cases {
317 let any_val = AnyValue {
318 value: Some(Value::KvlistValue(KeyValueList { values })),
319 };
320 let otlp_value = OtlpAnyValue::from(&any_val);
321 assert_eq!(expect, serde_json::to_string(&otlp_value).unwrap());
322 }
323 }
324
325 #[test]
326 fn test_attributes_serialize() {
327 let cases = vec![
328 ("{}", vec![]),
329 (
330 r#"{"key1":null}"#,
331 vec![KeyValue {
332 key: "key1".into(),
333 value: None,
334 }],
335 ),
336 (
337 r#"{"key1":null}"#,
338 vec![KeyValue {
339 key: "key1".into(),
340 value: Some(AnyValue { value: None }),
341 }],
342 ),
343 (
344 r#"{"key1":"val1"}"#,
345 vec![KeyValue {
346 key: "key1".into(),
347 value: Some(AnyValue {
348 value: Some(Value::StringValue(String::from("val1"))),
349 }),
350 }],
351 ),
352 ];
353
354 for (expect, values) in cases {
355 assert_eq!(expect, serde_json::to_string(&Attributes(values)).unwrap());
356 }
357 }
358}