1use api::v1::ColumnDataType;
16use api::v1::value::ValueData;
17use jsonb::{Number as JsonbNumber, Value as JsonbValue};
18use opentelemetry_proto::tonic::common::v1::{KeyValue, any_value};
19
20pub fn bytes_to_hex_string(bs: &[u8]) -> String {
21 hex::encode(bs)
22}
23
24pub fn any_value_to_jsonb(value: any_value::Value) -> JsonbValue<'static> {
25 match value {
26 any_value::Value::StringValue(s) => JsonbValue::String(s.into()),
27 any_value::Value::IntValue(i) => JsonbValue::Number(JsonbNumber::Int64(i)),
28 any_value::Value::DoubleValue(d) => JsonbValue::Number(JsonbNumber::Float64(d)),
29 any_value::Value::BoolValue(b) => JsonbValue::Bool(b),
30 any_value::Value::ArrayValue(a) => {
31 let values = a
32 .values
33 .into_iter()
34 .map(|v| match v.value {
35 Some(value) => any_value_to_jsonb(value),
36 None => JsonbValue::Null,
37 })
38 .collect();
39 JsonbValue::Array(values)
40 }
41 any_value::Value::KvlistValue(kv) => key_value_to_jsonb(kv.values),
42 any_value::Value::BytesValue(b) => JsonbValue::String(bytes_to_hex_string(&b).into()),
43 }
44}
45
46pub fn key_value_to_jsonb(key_values: Vec<KeyValue>) -> JsonbValue<'static> {
47 JsonbValue::Object(
48 key_values
49 .into_iter()
50 .map(|kv| {
51 (
52 kv.key,
53 kv.value
54 .and_then(|v| v.value)
55 .map_or(JsonbValue::Null, any_value_to_jsonb),
56 )
57 })
58 .collect(),
59 )
60}
61
62#[inline]
63pub(crate) fn make_string_column_data(
64 name: &str,
65 value: Option<String>,
66) -> (String, ColumnDataType, Option<ValueData>) {
67 make_column_data(
68 name,
69 ColumnDataType::String,
70 value.map(ValueData::StringValue),
71 )
72}
73
74#[inline]
75pub(crate) fn make_column_data(
76 name: &str,
77 data_type: ColumnDataType,
78 value: Option<ValueData>,
79) -> (String, ColumnDataType, Option<ValueData>) {
80 (name.to_string(), data_type, value)
81}