1use axum::{
2 extract::{
3 rejection::MatchedPathRejection, FromRequestParts, MatchedPath, OptionalFromRequestParts,
4 },
5 http::request::Parts,
6 RequestPartsExt,
7};
8
9#[derive(Debug, Clone, PartialEq, Eq)]
38pub struct Key(pub String);
39
40impl<S> FromRequestParts<S> for Key
41where
42 S: Send + Sync,
43{
44 type Rejection = MatchedPathRejection;
45
46 async fn from_request_parts(parts: &mut Parts, _: &S) -> Result<Self, Self::Rejection> {
47 let path = parts.extract::<MatchedPath>().await?.as_str().to_owned();
48 Ok(Key(path))
49 }
50}
51
52impl<S> OptionalFromRequestParts<S> for Key
53where
54 S: Send + Sync,
55{
56 type Rejection = <MatchedPath as OptionalFromRequestParts<S>>::Rejection;
57
58 async fn from_request_parts(
59 parts: &mut Parts,
60 state: &S,
61 ) -> Result<Option<Self>, Self::Rejection> {
62 let path =
63 <MatchedPath as OptionalFromRequestParts<S>>::from_request_parts(parts, state).await?;
64 Ok(path.map(|path| Key(path.as_str().to_owned())))
65 }
66}
67
68impl AsRef<str> for Key {
69 fn as_ref(&self) -> &str {
70 self.0.as_str()
71 }
72}
73
74impl From<String> for Key {
75 fn from(s: String) -> Self {
76 Self(s)
77 }
78}