opentelemetry_proto/
common.rs1use super::proto::common::v1::{any_value::Value as PBValue, KeyValue};
2use bytes::Bytes;
3use ordered_float::NotNan;
4use vector_core::event::metric::TagValue;
5use vrl::value::{ObjectMap, Value};
6
7impl From<PBValue> for Value {
8 fn from(av: PBValue) -> Self {
9 match av {
10 PBValue::StringValue(v) => Value::Bytes(Bytes::from(v)),
11 PBValue::BoolValue(v) => Value::Boolean(v),
12 PBValue::IntValue(v) => Value::Integer(v),
13 PBValue::DoubleValue(v) => NotNan::new(v).map(Value::Float).unwrap_or(Value::Null),
14 PBValue::BytesValue(v) => Value::Bytes(Bytes::from(v)),
15 PBValue::ArrayValue(arr) => Value::Array(
16 arr.values
17 .into_iter()
18 .map(|av| av.value.map(Into::into).unwrap_or(Value::Null))
19 .collect::<Vec<Value>>(),
20 ),
21 PBValue::KvlistValue(arr) => kv_list_into_value(arr.values),
22 }
23 }
24}
25
26impl From<PBValue> for TagValue {
27 fn from(pb: PBValue) -> Self {
28 match pb {
29 PBValue::StringValue(s) => TagValue::from(s),
30 PBValue::BoolValue(b) => TagValue::from(b.to_string()),
31 PBValue::IntValue(i) => TagValue::from(i.to_string()),
32 PBValue::DoubleValue(f) => TagValue::from(f.to_string()),
33 PBValue::BytesValue(b) => TagValue::from(String::from_utf8_lossy(&b).to_string()),
34 _ => TagValue::from("null"),
35 }
36 }
37}
38
39pub fn kv_list_into_value(arr: Vec<KeyValue>) -> Value {
40 Value::Object(
41 arr.into_iter()
42 .filter_map(|kv| {
43 kv.value.map(|av| {
44 (
45 kv.key.into(),
46 av.value.map(Into::into).unwrap_or(Value::Null),
47 )
48 })
49 })
50 .collect::<ObjectMap>(),
51 )
52}
53
54pub fn to_hex(d: &[u8]) -> String {
55 if d.is_empty() {
56 return "".to_string();
57 }
58 hex::encode(d)
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64
65 #[test]
66 fn test_pb_double_value_nan_handling() {
67 let nan_value = PBValue::DoubleValue(f64::NAN);
69 let result = Value::from(nan_value);
70 assert_eq!(result, Value::Null);
71 }
72
73 #[test]
74 fn test_pb_double_value_infinity() {
75 let inf_value = PBValue::DoubleValue(f64::INFINITY);
77 let result = Value::from(inf_value);
78 match result {
79 Value::Float(f) => {
80 assert!(f.into_inner().is_infinite() && f.into_inner().is_sign_positive())
81 }
82 _ => panic!("Expected Float value, got {result:?}"),
83 }
84
85 let neg_inf_value = PBValue::DoubleValue(f64::NEG_INFINITY);
86 let result = Value::from(neg_inf_value);
87 match result {
88 Value::Float(f) => {
89 assert!(f.into_inner().is_infinite() && f.into_inner().is_sign_negative())
90 }
91 _ => panic!("Expected Float value, got {result:?}"),
92 }
93 }
94}