graphql_starter/
request_id.rs1use std::{
4 fmt,
5 task::{Context, Poll},
6};
7
8use http::Request;
9use tower::{Layer, Service};
10use ulid::Ulid;
11use uuid::Uuid;
12
13#[derive(Clone, Copy, Debug)]
15pub struct RequestId(Ulid);
16
17impl RequestId {
18 fn new() -> Self {
19 Self(Ulid::new())
20 }
21}
22
23impl From<RequestId> for Ulid {
24 fn from(value: RequestId) -> Self {
25 value.0
26 }
27}
28
29impl From<RequestId> for Uuid {
30 fn from(value: RequestId) -> Self {
31 Uuid::from_u128(value.0 .0)
32 }
33}
34
35impl AsRef<Ulid> for &RequestId {
36 fn as_ref(&self) -> &Ulid {
37 &self.0
38 }
39}
40
41impl fmt::Display for RequestId {
42 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
43 let mut buffer = [0; ulid::ULID_LEN];
44 write!(f, "{}", self.0.array_to_str(&mut buffer))
45 }
46}
47
48#[derive(Clone, Debug)]
50pub struct RequestIdService<S> {
51 inner: S,
52}
53
54impl<S> RequestIdService<S> {
55 fn new(inner: S) -> Self {
56 Self { inner }
57 }
58}
59
60impl<B, S> Service<Request<B>> for RequestIdService<S>
61where
62 S: Service<Request<B>>,
63{
64 type Error = S::Error;
65 type Future = S::Future;
66 type Response = S::Response;
67
68 #[inline]
69 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
70 self.inner.poll_ready(cx)
71 }
72
73 fn call(&mut self, mut req: Request<B>) -> Self::Future {
74 let id = RequestId::new();
75 req.extensions_mut().insert(id);
76 self.inner.call(req)
77 }
78}
79
80#[derive(Clone, Debug)]
82pub struct RequestIdLayer;
83
84impl<S> Layer<S> for RequestIdLayer {
85 type Service = RequestIdService<S>;
86
87 fn layer(&self, inner: S) -> Self::Service {
88 RequestIdService::new(inner)
89 }
90}