micromegas_telemetry/
property.rs

1use sqlx::postgres::{PgHasArrayType, PgTypeInfo};
2use std::{collections::HashMap, sync::Arc};
3
4/// Represents a key-value property.
5///
6/// Properties are used to add context to telemetry events.
7/// Both key and value are stored as `Arc<String>` for efficient sharing.
8#[derive(Debug)]
9pub struct Property {
10    key: Arc<String>,
11    value: Arc<String>,
12}
13
14impl Property {
15    /// Creates a new `Property`.
16    pub fn new(key: Arc<String>, value: Arc<String>) -> Self {
17        Self { key, value }
18    }
19
20    /// Returns the key of the property as a string slice.
21    pub fn key_str(&self) -> &str {
22        self.key.as_str()
23    }
24
25    /// Returns the value of the property as a string slice.
26    pub fn value_str(&self) -> &str {
27        self.value.as_str()
28    }
29}
30
31impl ::sqlx::encode::Encode<'_, ::sqlx::Postgres> for Property {
32    fn encode_by_ref(
33        &self,
34        buf: &mut ::sqlx::postgres::PgArgumentBuffer,
35    ) -> std::result::Result<
36        sqlx::encode::IsNull,
37        std::boxed::Box<dyn std::error::Error + std::marker::Send + std::marker::Sync + 'static>,
38    > {
39        let mut encoder = ::sqlx::postgres::types::PgRecordEncoder::new(buf);
40        encoder.encode(self.key.as_str())?;
41        encoder.encode(self.value.as_str())?;
42        encoder.finish();
43        Ok(::sqlx::encode::IsNull::No)
44    }
45    fn size_hint(&self) -> ::std::primitive::usize {
46        2usize * (4 + 4)
47            + <String as ::sqlx::encode::Encode<::sqlx::Postgres>>::size_hint(&self.key)
48            + <String as ::sqlx::encode::Encode<::sqlx::Postgres>>::size_hint(&self.value)
49    }
50}
51
52impl ::sqlx::decode::Decode<'_, ::sqlx::Postgres> for Property {
53    fn decode(
54        value: ::sqlx::postgres::PgValueRef<'_>,
55    ) -> ::std::result::Result<
56        Self,
57        ::std::boxed::Box<
58            dyn ::std::error::Error + 'static + ::std::marker::Send + ::std::marker::Sync,
59        >,
60    > {
61        let mut decoder = ::sqlx::postgres::types::PgRecordDecoder::new(value)?;
62        let key = decoder.try_decode::<String>()?;
63        let value = decoder.try_decode::<String>()?;
64        ::std::result::Result::Ok(Property::new(Arc::new(key), Arc::new(value)))
65    }
66}
67#[automatically_derived]
68impl ::sqlx::Type<::sqlx::Postgres> for Property {
69    fn type_info() -> ::sqlx::postgres::PgTypeInfo {
70        ::sqlx::postgres::PgTypeInfo::with_name("micromegas_property")
71    }
72}
73
74// array support
75impl PgHasArrayType for Property {
76    fn array_type_info() -> PgTypeInfo {
77        PgTypeInfo::with_name("_micromegas_property")
78    }
79}
80
81/// Converts a `HashMap<String, String>` to a `Vec<Property>`.
82///
83/// This is a convenience function for creating a list of properties from a map.
84pub fn make_properties(map: &HashMap<String, String>) -> Vec<Property> {
85    map.iter()
86        .map(|(k, v)| Property::new(Arc::new(k.clone()), Arc::new(v.clone())))
87        .collect()
88}
89
90/// Converts a `Vec<Property>` to a `HashMap<String, String>`.
91///
92/// This is a convenience function for converting a list of properties back to a map.
93pub fn into_hashmap(properties: Vec<Property>) -> HashMap<String, String> {
94    let mut hashmap = HashMap::new();
95    for property in properties {
96        hashmap.insert((*property.key).clone(), (*property.value).clone());
97    }
98    hashmap
99}