preroll/middleware/extension_types/
request_id.rs1use 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}