1use std::pin::Pin;
2
3use serde::{Deserialize, Serialize, Serializer, ser::Error};
4
5use crate::{
6 endpoint::Endpoint,
7 request::Request,
8 response::Response,
9 schema::{SchemaDeserialize, SchemaSerialize},
10};
11
12#[derive(Debug)]
15pub struct SerdeAdapter<T>(pub T);
16
17impl<T> SerdeAdapter<T>
18where
19 T: SchemaSerialize,
20{
21 pub fn skip_serializing(&self) -> bool {
22 !self.0.is_present()
23 }
24}
25
26impl<T> Serialize for SerdeAdapter<T>
27where
28 T: SchemaSerialize,
29{
30 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
31 where
32 S: Serializer,
33 {
34 if !self.0.is_present() {
35 return Err(S::Error::custom("cannot serialize an absent value"));
36 }
37 self.0.schema_serialize(serializer)
38 }
39}
40
41impl<'de, T> Deserialize<'de> for SerdeAdapter<T>
42where
43 T: SchemaDeserialize,
44{
45 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
46 where
47 D: serde::Deserializer<'de>,
48 {
49 Ok(Self(T::schema_deserialize(deserializer)?))
50 }
51}
52
53#[derive(Clone)]
55pub struct AxumHandlerAdapter<E>(pub E);
56
57impl<V: 'static, S: 'static, E: Endpoint<S, V>> axum::handler::Handler<V, S>
58 for AxumHandlerAdapter<E>
59{
60 type Future = Pin<Box<dyn Future<Output = Response> + Send + 'static>>;
61
62 fn call(self, req: Request, state: S) -> Self::Future {
63 Box::pin(self.0.call(req, state))
64 }
65}
66
67impl<E, V> Endpoint<E, V> for AxumHandlerAdapter<E>
68where
69 E: Endpoint<E, V>,
70{
71 fn path(&self) -> std::borrow::Cow<'static, str> {
72 self.0.path()
73 }
74
75 fn method(&self) -> http::Method {
76 self.0.method()
77 }
78
79 fn openapi(&self, registry: &mut crate::Registry) -> crate::openapi::Operation {
80 self.0.openapi(registry)
81 }
82
83 fn call(self, req: Request, state: E) -> impl Future<Output = Response> + Send {
84 self.0.call(req, state)
85 }
86}