xray_lite/
trace_id.rs

1use crate::{epoch::Seconds, hexbytes::Bytes};
2use rand::RngCore;
3use serde::{de, ser, Serializer};
4use std::fmt;
5/// Coorelates a string of spans together
6///
7/// Users need only refer to displability
8/// a factory for generating these is provided.
9///
10///
11#[derive(Debug, PartialEq, Clone)]
12pub enum TraceId {
13    #[doc(hidden)]
14    New(u64, [u8; 12]),
15    #[doc(hidden)]
16    Rendered(String),
17}
18
19impl TraceId {
20    /// Generate a new random trace ID
21    pub fn new() -> Self {
22        let mut buf = [0; 12];
23        rand::thread_rng().fill_bytes(&mut buf);
24        TraceId::New(Seconds::now().trunc(), buf)
25    }
26}
27
28impl Default for TraceId {
29    fn default() -> Self {
30        TraceId::new()
31    }
32}
33
34impl fmt::Display for TraceId {
35    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36        match self {
37            TraceId::New(seconds, bytes) => write!(f, "1-{:08x}-{:x}", seconds, Bytes(bytes)),
38            TraceId::Rendered(value) => write!(f, "{}", value),
39        }
40    }
41}
42
43struct TraceIdVisitor;
44
45impl<'de> de::Visitor<'de> for TraceIdVisitor {
46    type Value = TraceId;
47
48    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
49        formatter.write_str("a string value")
50    }
51    fn visit_str<E>(self, value: &str) -> Result<TraceId, E>
52    where
53        E: de::Error,
54    {
55        Ok(TraceId::Rendered(value.into()))
56    }
57}
58
59impl ser::Serialize for TraceId {
60    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
61    where
62        S: Serializer,
63    {
64        serializer.serialize_str(&format!("{}", self))
65    }
66}
67
68impl<'de> de::Deserialize<'de> for TraceId {
69    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
70    where
71        D: de::Deserializer<'de>,
72    {
73        deserializer.deserialize_str(TraceIdVisitor)
74    }
75}