Skip to main content

trillium_api/
body.rs

1use crate::{ApiConnExt, TryFromConn};
2use serde::{de::DeserializeOwned, Serialize};
3use std::ops::{Deref, DerefMut};
4use trillium::{async_trait, Conn, Handler};
5
6/// Body extractor
7#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)]
8pub struct Body<T>(pub T);
9
10impl<T> Body<T> {
11    /// construct a new Body
12    pub fn new(t: T) -> Self {
13        Self(t)
14    }
15
16    /// Unwrap this Body
17    pub fn into_inner(self) -> T {
18        self.0
19    }
20}
21
22impl<T> From<T> for Body<T> {
23    fn from(value: T) -> Self {
24        Self(value)
25    }
26}
27
28impl<T> Deref for Body<T> {
29    type Target = T;
30
31    fn deref(&self) -> &Self::Target {
32        &self.0
33    }
34}
35
36impl<T> DerefMut for Body<T> {
37    fn deref_mut(&mut self) -> &mut Self::Target {
38        &mut self.0
39    }
40}
41
42#[async_trait]
43impl<T> TryFromConn for Body<T>
44where
45    T: DeserializeOwned + Send + Sync + 'static,
46{
47    type Error = crate::Error;
48    async fn try_from_conn(conn: &mut Conn) -> Result<Self, Self::Error> {
49        conn.deserialize().await.map(Self)
50    }
51}
52
53#[async_trait]
54impl<T> Handler for Body<T>
55where
56    T: Serialize + Send + Sync + 'static,
57{
58    async fn run(&self, mut conn: Conn) -> Conn {
59        match conn.serialize(&self.0).await {
60            Ok(()) => conn,
61            Err(e) => conn.with_state(e).halt(),
62        }
63    }
64
65    async fn before_send(&self, mut conn: Conn) -> Conn {
66        if let Some(error) = conn.take_state::<crate::Error>() {
67            error.before_send(conn).await
68        } else {
69            conn
70        }
71    }
72}