rama_net/user/layer/
username_parser.rs1use core::{fmt, marker::PhantomData};
2
3use crate::user::UserId;
4
5use rama_core::{
6 Layer, Service,
7 extensions::{Extensions, ExtensionsRef},
8 telemetry::tracing,
9 username::{UsernameLabelParser, parse_username},
10};
11#[derive(Default)]
25pub struct UsernameLabelParserLayer<P> {
26 _parser: PhantomData<fn() -> P>,
27}
28
29impl<P> UsernameLabelParserLayer<P> {
30 #[inline(always)]
31 #[must_use]
32 pub fn new() -> Self {
33 Self {
34 _parser: PhantomData,
35 }
36 }
37}
38
39impl<P> fmt::Debug for UsernameLabelParserLayer<P> {
40 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41 f.debug_struct("UsernameLabelParserLayer")
42 .field("parser", &core::any::type_name::<P>())
43 .finish()
44 }
45}
46
47impl<P> Clone for UsernameLabelParserLayer<P> {
48 fn clone(&self) -> Self {
49 Self {
50 _parser: PhantomData,
51 }
52 }
53}
54
55impl<S, P> Layer<S> for UsernameLabelParserLayer<P> {
56 type Service = UsernameLabelParserService<S, P>;
57
58 fn layer(&self, inner: S) -> Self::Service {
59 Self::Service {
60 inner,
61 _parser: PhantomData,
62 }
63 }
64}
65
66pub struct UsernameLabelParserService<S, P> {
71 inner: S,
72 _parser: PhantomData<fn() -> P>,
73}
74
75impl<S: fmt::Debug, P> fmt::Debug for UsernameLabelParserService<S, P> {
76 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77 f.debug_struct("UsernameLabelParserService")
78 .field("inner", &self.inner)
79 .field("parser", &core::any::type_name::<P>())
80 .finish()
81 }
82}
83
84impl<S: Clone, P> Clone for UsernameLabelParserService<S, P> {
85 fn clone(&self) -> Self {
86 Self {
87 inner: self.inner.clone(),
88 _parser: PhantomData,
89 }
90 }
91}
92
93impl<S, P, Input> Service<Input> for UsernameLabelParserService<S, P>
94where
95 S: Service<Input>,
96 P: UsernameLabelParser,
97 Input: ExtensionsRef,
98{
99 type Output = S::Output;
100 type Error = S::Error;
101
102 fn serve(
103 &self,
104 input: Input,
105 ) -> impl Future<Output = Result<Self::Output, Self::Error>> + Send + '_ {
106 let extensions = input.extensions();
107 match extensions.get_ref() {
108 Some(UserId::Username(username)) => {
109 let label_extensions = Extensions::new();
110 match parse_username(&label_extensions, P::default(), username) {
111 Ok(new_username) => {
112 tracing::debug!(
113 "username label parser: success: overwrite id username '{username}' with '{new_username}'"
114 );
115 extensions.insert(UserId::Username(new_username));
116 extensions.extend(&label_extensions);
117 }
118 Err(err) => {
119 tracing::debug!(
120 "failed to parse username labels, keep existing username: '{username}'; err = {err}"
121 );
122 }
123 }
124 }
125 Some(UserId::Token(_)) => {
126 tracing::debug!("no parsing to do, incompatible user id in input: token");
127 }
128 None | Some(UserId::Anonymous) => {
129 tracing::debug!("no parsing to do, incompatible user id in input: none/anonymous");
130 }
131 }
132
133 self.inner.serve(input)
134 }
135}