opentelemetry_spanprocessor_any/
common.rs

1#[cfg(feature = "serialize")]
2use serde::{Deserialize, Serialize};
3use std::borrow::Cow;
4use std::fmt;
5
6/// Key used for metric `AttributeSet`s and trace `Span` attributes.
7#[cfg_attr(feature = "serialize", derive(Deserialize, Serialize))]
8#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
9pub struct Key(Cow<'static, str>);
10
11impl Key {
12    /// Create a new `Key`.
13    pub fn new<S: Into<Cow<'static, str>>>(value: S) -> Self {
14        Key(value.into())
15    }
16
17    /// Create a new const `Key`.
18    pub const fn from_static_str(value: &'static str) -> Self {
19        Key(Cow::Borrowed(value))
20    }
21
22    /// Create a `KeyValue` pair for `bool` values.
23    pub fn bool<T: Into<bool>>(self, value: T) -> KeyValue {
24        KeyValue {
25            key: self,
26            value: Value::Bool(value.into()),
27        }
28    }
29
30    /// Create a `KeyValue` pair for `i64` values.
31    pub fn i64(self, value: i64) -> KeyValue {
32        KeyValue {
33            key: self,
34            value: Value::I64(value),
35        }
36    }
37
38    /// Create a `KeyValue` pair for `f64` values.
39    pub fn f64(self, value: f64) -> KeyValue {
40        KeyValue {
41            key: self,
42            value: Value::F64(value),
43        }
44    }
45
46    /// Create a `KeyValue` pair for `String` values.
47    pub fn string<T: Into<Cow<'static, str>>>(self, value: T) -> KeyValue {
48        KeyValue {
49            key: self,
50            value: Value::String(value.into()),
51        }
52    }
53
54    /// Create a `KeyValue` pair for arrays.
55    pub fn array<T: Into<Array>>(self, value: T) -> KeyValue {
56        KeyValue {
57            key: self,
58            value: Value::Array(value.into()),
59        }
60    }
61
62    /// Returns a reference to the underlying key name
63    pub fn as_str(&self) -> &str {
64        self.0.as_ref()
65    }
66}
67
68impl From<&'static str> for Key {
69    /// Convert a `&str` to a `Key`.
70    fn from(key_str: &'static str) -> Self {
71        Key(Cow::from(key_str))
72    }
73}
74
75impl From<String> for Key {
76    /// Convert a `String` to a `Key`.
77    fn from(string: String) -> Self {
78        Key(Cow::from(string))
79    }
80}
81
82impl From<Key> for String {
83    /// Converts `Key` instances into `String`.
84    fn from(key: Key) -> Self {
85        key.0.into_owned()
86    }
87}
88
89impl fmt::Display for Key {
90    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
91        self.0.fmt(fmt)
92    }
93}
94
95/// Array of homogeneous values
96#[cfg_attr(feature = "serialize", derive(Deserialize, Serialize))]
97#[derive(Clone, Debug, PartialEq)]
98pub enum Array {
99    /// Array of bools
100    Bool(Vec<bool>),
101    /// Array of integers
102    I64(Vec<i64>),
103    /// Array of floats
104    F64(Vec<f64>),
105    /// Array of strings
106    String(Vec<Cow<'static, str>>),
107}
108
109impl fmt::Display for Array {
110    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
111        match self {
112            Array::Bool(values) => display_array_str(values, fmt),
113            Array::I64(values) => display_array_str(values, fmt),
114            Array::F64(values) => display_array_str(values, fmt),
115            Array::String(values) => {
116                write!(fmt, "[")?;
117                for (i, t) in values.iter().enumerate() {
118                    if i > 0 {
119                        write!(fmt, ",")?;
120                    }
121                    write!(fmt, "{:?}", t)?;
122                }
123                write!(fmt, "]")
124            }
125        }
126    }
127}
128
129fn display_array_str<T: fmt::Display>(slice: &[T], fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
130    write!(fmt, "[")?;
131    for (i, t) in slice.iter().enumerate() {
132        if i > 0 {
133            write!(fmt, ",")?;
134        }
135        write!(fmt, "{}", t)?;
136    }
137    write!(fmt, "]")
138}
139
140macro_rules! into_array {
141    ($(($t:ty, $val:expr),)+) => {
142        $(
143            impl From<$t> for Array {
144                fn from(t: $t) -> Self {
145                    $val(t)
146                }
147            }
148        )+
149    }
150}
151
152into_array!(
153    (Vec<bool>, Array::Bool),
154    (Vec<i64>, Array::I64),
155    (Vec<f64>, Array::F64),
156    (Vec<Cow<'static, str>>, Array::String),
157);
158
159/// Value types for use in `KeyValue` pairs.
160#[cfg_attr(feature = "serialize", derive(Deserialize, Serialize))]
161#[derive(Clone, Debug, PartialEq)]
162pub enum Value {
163    /// bool values
164    Bool(bool),
165    /// i64 values
166    I64(i64),
167    /// f64 values
168    F64(f64),
169    /// String values
170    String(Cow<'static, str>),
171    /// Array of homogeneous values
172    Array(Array),
173}
174
175impl Value {
176    /// String representation of the `Value`
177    ///
178    /// This will allocate iff the underlying value is not a `String`.
179    pub fn as_str(&self) -> Cow<'_, str> {
180        match self {
181            Value::Bool(v) => format!("{}", v).into(),
182            Value::I64(v) => format!("{}", v).into(),
183            Value::F64(v) => format!("{}", v).into(),
184            Value::String(v) => Cow::Borrowed(v.as_ref()),
185            Value::Array(v) => format!("{}", v).into(),
186        }
187    }
188}
189
190macro_rules! from_values {
191   (
192        $(
193            ($t:ty, $val:expr);
194        )+
195    ) => {
196        $(
197            impl From<$t> for Value {
198                fn from(t: $t) -> Self {
199                    $val(t)
200                }
201            }
202        )+
203    }
204}
205
206from_values!(
207    (bool, Value::Bool);
208    (i64, Value::I64);
209    (f64, Value::F64);
210    (Cow<'static, str>, Value::String);
211);
212
213impl From<&'static str> for Value {
214    /// Convenience method for creating a `Value` from a `&'static str`.
215    fn from(s: &'static str) -> Self {
216        Value::String(s.into())
217    }
218}
219
220impl From<String> for Value {
221    /// Convenience method for creating a `Value` from a `String`.
222    fn from(s: String) -> Self {
223        Value::String(s.into())
224    }
225}
226
227impl fmt::Display for Value {
228    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
229        match self {
230            Value::Bool(v) => fmt.write_fmt(format_args!("{}", v)),
231            Value::I64(v) => fmt.write_fmt(format_args!("{}", v)),
232            Value::F64(v) => fmt.write_fmt(format_args!("{}", v)),
233            Value::String(v) => fmt.write_fmt(format_args!("{}", v)),
234            Value::Array(v) => fmt.write_fmt(format_args!("{}", v)),
235        }
236    }
237}
238
239/// `KeyValue` pairs are used by `AttributeSet`s and `Span` attributes.
240#[cfg_attr(feature = "serialize", derive(Deserialize, Serialize))]
241#[derive(Clone, Debug, PartialEq)]
242pub struct KeyValue {
243    /// Dimension or event key
244    pub key: Key,
245    /// Dimension or event value
246    pub value: Value,
247}
248
249impl KeyValue {
250    /// Create a new `KeyValue` pair.
251    pub fn new<K, V>(key: K, value: V) -> Self
252    where
253        K: Into<Key>,
254        V: Into<Value>,
255    {
256        KeyValue {
257            key: key.into(),
258            value: value.into(),
259        }
260    }
261}