use std::{
ops::{Deref, DerefMut},
task::{Context, Poll},
};
use tower_service::Service;
use crate::{task::Task, task::from_request::FromRequest};
#[derive(Debug, Clone, Copy)]
pub struct Data<T>(pub T);
impl<T> Data<T> {
pub fn new(inner: T) -> Self {
Self(inner)
}
}
impl<T> Deref for Data<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for Data<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<S, T> tower_layer::Layer<S> for Data<T>
where
T: Clone + Send + Sync + 'static,
{
type Service = AddExtension<S, T>;
fn layer(&self, inner: S) -> Self::Service {
AddExtension {
inner,
value: self.0.clone(),
}
}
}
#[derive(Clone, Copy, Debug)]
pub struct AddExtension<S, T> {
inner: S,
value: T,
}
impl<S, T, Args> Service<Task<Args>> for AddExtension<S, T>
where
S: Service<Task<Args>> + Send + 'static,
T: Clone + Send + Sync + 'static,
{
type Response = S::Response;
type Error = S::Error;
type Future = S::Future;
#[inline]
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.inner.poll_ready(cx)
}
fn call(&mut self, mut task: Task<Args>) -> Self::Future {
task.inject_data(self.value.clone());
self.inner.call(task)
}
}
#[derive(Debug, thiserror::Error, PartialEq)]
#[non_exhaustive]
pub enum MissingDataError {
#[error("the type for key `{0}` is not available")]
NotFound(String),
}
impl<T: Clone + Send + Sync + 'static, Args: Sync> FromRequest<Task<Args>> for Data<T> {
type Error = MissingDataError;
async fn from_request(task: &Task<Args>) -> Result<Self, Self::Error> {
task.data().get_checked().cloned().map(Self::new)
}
}