preroll/middleware/extension_types/
request_id.rs

1use std::fmt::{self, Display};
2use std::str::FromStr;
3
4use log::kv::{ToValue, Value};
5use serde::de::{Error as DeError, Unexpected, Visitor};
6use serde::{Deserialize, Deserializer, Serialize, Serializer};
7use uuid::Uuid;
8
9#[derive(Debug, Clone)]
10pub struct RequestId {
11    id: Uuid,
12    string_id: String,
13}
14
15impl RequestId {
16    #[allow(clippy::new_without_default)]
17    #[cfg(not(feature = "test"))]
18    pub fn new() -> Self {
19        Uuid::new_v4().into()
20    }
21
22    pub fn as_str(&self) -> &str {
23        &self.string_id
24    }
25
26    #[cfg(feature = "honeycomb")]
27    #[cfg_attr(feature = "docs", doc(cfg(feature = "honeycomb")))]
28    pub fn as_u128(&self) -> u128 {
29        self.id.as_u128()
30    }
31}
32
33impl Display for RequestId {
34    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
35        write!(f, "{}", self.id)
36    }
37}
38
39impl From<Uuid> for RequestId {
40    fn from(uuid: Uuid) -> Self {
41        let buf = &mut [0; 36];
42        let human_id = uuid.to_hyphenated().encode_lower(buf);
43        Self {
44            id: uuid,
45            string_id: human_id.to_string(),
46        }
47    }
48}
49
50impl FromStr for RequestId {
51    type Err = uuid::Error;
52
53    fn from_str(string: &str) -> Result<Self, uuid::Error> {
54        Ok(Self {
55            id: Uuid::parse_str(string)?,
56            string_id: string.to_string(),
57        })
58    }
59}
60
61struct RequestIdVisitor;
62
63impl<'de> Visitor<'de> for RequestIdVisitor {
64    type Value = RequestId;
65
66    fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
67        write!(formatter, "a UUID &str")
68    }
69
70    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
71    where
72        E: DeError,
73    {
74        match RequestId::from_str(v) {
75            Ok(method) => Ok(method),
76            Err(_) => Err(DeError::invalid_value(Unexpected::Str(v), &self)),
77        }
78    }
79}
80
81impl<'de> Deserialize<'de> for RequestId {
82    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
83    where
84        D: Deserializer<'de>,
85    {
86        deserializer.deserialize_str(RequestIdVisitor)
87    }
88}
89
90impl Serialize for RequestId {
91    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
92    where
93        S: Serializer,
94    {
95        serializer.serialize_str(self.as_str())
96    }
97}
98
99impl<'v> ToValue for RequestId {
100    fn to_value(&self) -> Value<'_> {
101        Value::from(self.as_str())
102    }
103}