server_fn/codec/
patch.rs

1use super::{Encoding, FromReq, FromRes, IntoReq, IntoRes};
2use crate::{
3    error::{FromServerFnError, IntoAppError, ServerFnErrorErr},
4    request::{ClientReq, Req},
5    response::{ClientRes, TryRes},
6    ContentType, Decodes, Encodes,
7};
8use std::marker::PhantomData;
9
10/// A codec that encodes the data in the patch body
11pub struct Patch<Codec>(PhantomData<Codec>);
12
13impl<Codec: ContentType> ContentType for Patch<Codec> {
14    const CONTENT_TYPE: &'static str = Codec::CONTENT_TYPE;
15}
16
17impl<Codec: ContentType> Encoding for Patch<Codec> {
18    const METHOD: http::Method = http::Method::PATCH;
19}
20
21impl<E, T, Encoding, Request> IntoReq<Patch<Encoding>, Request, E> for T
22where
23    Request: ClientReq<E>,
24    Encoding: Encodes<T>,
25    E: FromServerFnError,
26{
27    fn into_req(self, path: &str, accepts: &str) -> Result<Request, E> {
28        let data = Encoding::encode(&self).map_err(|e| {
29            ServerFnErrorErr::Serialization(e.to_string()).into_app_error()
30        })?;
31        Request::try_new_patch_bytes(
32            path,
33            accepts,
34            Encoding::CONTENT_TYPE,
35            data,
36        )
37    }
38}
39
40impl<E, T, Request, Encoding> FromReq<Patch<Encoding>, Request, E> for T
41where
42    Request: Req<E> + Send + 'static,
43    Encoding: Decodes<T>,
44    E: FromServerFnError,
45{
46    async fn from_req(req: Request) -> Result<Self, E> {
47        let data = req.try_into_bytes().await?;
48        let s = Encoding::decode(data).map_err(|e| {
49            ServerFnErrorErr::Deserialization(e.to_string()).into_app_error()
50        })?;
51        Ok(s)
52    }
53}
54
55impl<E, Response, Encoding, T> IntoRes<Patch<Encoding>, Response, E> for T
56where
57    Response: TryRes<E>,
58    Encoding: Encodes<T>,
59    E: FromServerFnError + Send,
60    T: Send,
61{
62    async fn into_res(self) -> Result<Response, E> {
63        let data = Encoding::encode(&self).map_err(|e| {
64            ServerFnErrorErr::Serialization(e.to_string()).into_app_error()
65        })?;
66        Response::try_from_bytes(Encoding::CONTENT_TYPE, data)
67    }
68}
69
70impl<E, Encoding, Response, T> FromRes<Patch<Encoding>, Response, E> for T
71where
72    Response: ClientRes<E> + Send,
73    Encoding: Decodes<T>,
74    E: FromServerFnError,
75{
76    async fn from_res(res: Response) -> Result<Self, E> {
77        let data = res.try_into_bytes().await?;
78        let s = Encoding::decode(data).map_err(|e| {
79            ServerFnErrorErr::Deserialization(e.to_string()).into_app_error()
80        })?;
81        Ok(s)
82    }
83}