diff options
| author | Owen Jacobson <owen@grimoire.ca> | 2024-09-25 01:05:38 -0400 |
|---|---|---|
| committer | Owen Jacobson <owen@grimoire.ca> | 2024-09-25 01:05:38 -0400 |
| commit | af7ece7dd5433051d67526ae15ad64f0f5b5e568 (patch) | |
| tree | 636b0e804ea1f0fbf5675ec6d60aa7972822e821 /src/header.rs | |
| parent | 0b89800d55c21aaa11d69c1dba89277cc4a46809 (diff) | |
Code organization changes considered during implementation of vector-of-sequence-numbers stream resume.
Diffstat (limited to 'src/header.rs')
| -rw-r--r-- | src/header.rs | 86 |
1 files changed, 0 insertions, 86 deletions
diff --git a/src/header.rs b/src/header.rs deleted file mode 100644 index 683c1f9..0000000 --- a/src/header.rs +++ /dev/null @@ -1,86 +0,0 @@ -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<T>(pub T); - -static LAST_EVENT_ID: HeaderName = HeaderName::from_static("last-event-id"); - -impl<T> headers::Header for LastEventId<T> -where - T: Serialize + DeserializeOwned, -{ - fn name() -> &'static HeaderName { - &LAST_EVENT_ID - } - - fn decode<'i, I>(values: &mut I) -> Result<Self, headers::Error> - where - I: Iterator<Item = &'i HeaderValue>, - { - let value = values.next().ok_or_else(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) - where - E: Extend<HeaderValue>, - { - let Self(value) = self; - // Must panic or suppress; the trait provides no other options. - 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, T> FromRequestParts<S> for LastEventId<T> -where - S: Send + Sync, - T: Serialize + DeserializeOwned, -{ - type Rejection = <TypedHeader<Self> as FromRequestParts<S>>::Rejection; - - async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> { - // This is purely for ergonomics: it allows `RequestedAt` to be extracted - // without having to wrap it in `Extension<>`. Callers _can_ still do that, - // but they aren't forced to. - let TypedHeader(requested_at) = - TypedHeader::<Self>::from_request_parts(parts, state).await?; - - Ok(requested_at) - } -} - -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 - } -} |
