1use serde::{de::DeserializeOwned, Serialize};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
4pub enum Method {
5 Post,
6 Get,
7 Put,
8 Delete,
9}
10
11impl std::fmt::Display for Method {
12 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13 match self {
14 Method::Post => write!(f, "POST"),
15 Method::Get => write!(f, "GET"),
16 Method::Put => write!(f, "PUT"),
17 Method::Delete => write!(f, "DELETE"),
18 }
19 }
20}
21
22pub trait Client: Clone {
23 type Error: core::fmt::Debug;
24
25 fn request_with_body_and_query<B, Q, R>(
28 &self,
29 method: Method,
30 path: &str,
31 body: Option<&B>,
32 query: Option<&Q>,
33 ) -> Result<R, Self::Error>
34 where
35 B: Serialize,
36 Q: Serialize,
37 R: DeserializeOwned;
38
39 fn request_with_body<B, R>(
40 &self,
41 method: Method,
42 path: &str,
43 body: &B,
44 ) -> Result<R, Self::Error>
45 where
46 B: Serialize,
47 R: DeserializeOwned,
48 {
49 self.request_with_body_and_query::<_, (), _>(method, path, Some(body), None)
50 }
51
52 fn request_with_query<Q, R>(
53 &self,
54 method: Method,
55 path: &str,
56 query: &Q,
57 ) -> Result<R, Self::Error>
58 where
59 Q: Serialize,
60 R: DeserializeOwned,
61 {
62 self.request_with_body_and_query::<(), _, _>(method, path, None, Some(query))
63 }
64
65 fn put<B, R>(&self, path: &str, body: &B) -> Result<R, Self::Error>
66 where
67 B: Serialize,
68 R: DeserializeOwned,
69 {
70 self.request_with_body(Method::Put, path, body)
71 }
72
73 fn post<B, R>(&self, path: &str, body: &B) -> Result<R, Self::Error>
74 where
75 B: Serialize,
76 R: DeserializeOwned,
77 {
78 self.request_with_body(Method::Post, path, body)
79 }
80
81 fn delete<B, R>(&self, path: &str, body: &B) -> Result<R, Self::Error>
82 where
83 B: Serialize,
84 R: DeserializeOwned,
85 {
86 self.request_with_body(Method::Delete, path, body)
87 }
88
89 fn get<Q, R>(&self, path: &str, query: &Q) -> Result<R, Self::Error>
90 where
91 Q: Serialize,
92 R: DeserializeOwned,
93 {
94 self.request_with_query(Method::Get, path, query)
95 }
96}
97
98impl<T> Client for &T
99where
100 T: Client,
101{
102 type Error = <T as Client>::Error;
103
104 fn request_with_body_and_query<B, Q, R>(
105 &self,
106 method: Method,
107 path: &str,
108 body: Option<&B>,
109 query: Option<&Q>,
110 ) -> Result<R, Self::Error>
111 where
112 B: Serialize,
113 Q: Serialize,
114 R: DeserializeOwned,
115 {
116 T::request_with_body_and_query(self, method, path, body, query)
117 }
118}