diff options
Diffstat (limited to 'src/header.rs')
| -rw-r--r-- | src/header.rs | 47 |
1 files changed, 30 insertions, 17 deletions
diff --git a/src/header.rs b/src/header.rs index 61cc561..683c1f9 100644 --- a/src/header.rs +++ b/src/header.rs @@ -1,16 +1,22 @@ +use std::ops::Deref; + use axum::{ extract::FromRequestParts, http::{request::Parts, HeaderName, HeaderValue}, }; use axum_extra::typed_header::TypedHeader; +use serde::{de::DeserializeOwned, Serialize}; /// A typed header. When used as a bare extractor, reads from the /// `Last-Event-Id` HTTP header. -pub struct LastEventId(pub String); +pub struct LastEventId<T>(pub T); static LAST_EVENT_ID: HeaderName = HeaderName::from_static("last-event-id"); -impl headers::Header for LastEventId { +impl<T> headers::Header for LastEventId<T> +where + T: Serialize + DeserializeOwned, +{ fn name() -> &'static HeaderName { &LAST_EVENT_ID } @@ -20,11 +26,9 @@ impl headers::Header for LastEventId { I: Iterator<Item = &'i HeaderValue>, { let value = values.next().ok_or_else(headers::Error::invalid)?; - if let Ok(value) = value.to_str() { - Ok(Self(value.into())) - } else { - Err(headers::Error::invalid()) - } + let value = value.to_str().map_err(|_| headers::Error::invalid())?; + let value = serde_json::from_str(value).map_err(|_| headers::Error::invalid())?; + Ok(Self(value)) } fn encode<E>(&self, values: &mut E) @@ -33,16 +37,18 @@ impl headers::Header for LastEventId { { let Self(value) = self; // Must panic or suppress; the trait provides no other options. - let value = HeaderValue::from_str(value).expect("LastEventId is a valid header value"); + let value = serde_json::to_string(value).expect("value can be encoded as JSON"); + let value = HeaderValue::from_str(&value).expect("LastEventId is a valid header value"); values.extend(std::iter::once(value)); } } #[async_trait::async_trait] -impl<S> FromRequestParts<S> for LastEventId +impl<S, T> FromRequestParts<S> for LastEventId<T> where S: Send + Sync, + T: Serialize + DeserializeOwned, { type Rejection = <TypedHeader<Self> as FromRequestParts<S>>::Rejection; @@ -57,17 +63,24 @@ where } } -impl From<String> for LastEventId { - fn from(header: String) -> Self { - Self(header) - } -} - -impl std::ops::Deref for LastEventId { - type Target = str; +impl<T> Deref for LastEventId<T> { + type Target = T; fn deref(&self) -> &Self::Target { let Self(header) = self; header } } + +impl<T> From<T> for LastEventId<T> { + fn from(value: T) -> Self { + Self(value) + } +} + +impl<T> LastEventId<T> { + pub fn into_inner(self) -> T { + let Self(value) = self; + value + } +} |
