Skip to main content

trillium_api/
body.rs

1use crate::{ApiConnExt, TryFromConn};
2use serde::{Serialize, de::DeserializeOwned};
3use std::ops::{Deref, DerefMut};
4use trillium::{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
42impl<T> TryFromConn for Body<T>
43where
44    T: DeserializeOwned + Send + Sync + 'static,
45{
46    type Error = crate::Error;
47
48    async fn try_from_conn(conn: &mut Conn) -> Result<Self, Self::Error> {
49        conn.deserialize().await.map(Self)
50    }
51}
52
53impl<T> Handler for Body<T>
54where
55    T: Serialize + Send + Sync + 'static,
56{
57    async fn run(&self, mut conn: Conn) -> Conn {
58        match conn.serialize(&self.0).await {
59            Ok(()) => conn,
60            Err(e) => conn.with_state(e).halt(),
61        }
62    }
63
64    async fn before_send(&self, mut conn: Conn) -> Conn {
65        if let Some(error) = conn.take_state::<crate::Error>() {
66            error.before_send(conn).await
67        } else {
68            conn
69        }
70    }
71}