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