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