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