1use std::fmt;
2use std::pin::Pin;
3
4use async_trait::async_trait;
5use futures::Future;
6
7use tc_error::*;
8use tc_value::{Number, Value};
9use tcgeneric::{Instance, Map, PathSegment, TCPath, ThreadSafe, Tuple};
10
11use super::{Gateway, Transaction};
12
13pub mod generic;
14pub mod helpers;
15pub mod number;
16pub mod string;
17pub mod value;
18
19pub type GetFuture<'a, State> = Pin<Box<dyn Future<Output = TCResult<State>> + Send + 'a>>;
20pub type GetHandler<'a, 'b, Txn, State> =
21 Box<dyn FnOnce(&'b Txn, Value) -> GetFuture<'a, State> + Send + 'a>;
22
23pub type PutFuture<'a> = Pin<Box<dyn Future<Output = TCResult<()>> + Send + 'a>>;
24pub type PutHandler<'a, 'b, Txn, State> =
25 Box<dyn FnOnce(&'b Txn, Value, State) -> PutFuture<'a> + Send + 'a>;
26
27pub type PostFuture<'a, State> = Pin<Box<dyn Future<Output = TCResult<State>> + Send + 'a>>;
28pub type PostHandler<'a, 'b, Txn, State> =
29 Box<dyn FnOnce(&'b Txn, Map<State>) -> PostFuture<'a, State> + Send + 'a>;
30
31pub type DeleteFuture<'a> = Pin<Box<dyn Future<Output = TCResult<()>> + Send + 'a>>;
32pub type DeleteHandler<'a, 'b, Txn> =
33 Box<dyn FnOnce(&'b Txn, Value) -> DeleteFuture<'a> + Send + 'a>;
34
35#[derive(Debug)]
36pub enum HandlerType {
37 Get,
38 Put,
39 Post,
40 Delete,
41}
42
43#[async_trait]
44pub trait ClosureInstance<State: StateInstance>: Send + Sync {
45 async fn call(self: Box<Self>, txn: State::Txn, args: State) -> TCResult<State>;
47}
48
49pub trait StateInstance:
50 Default
51 + Instance
52 + Route<Self>
53 + ToState<Self>
54 + From<bool>
55 + From<Number>
56 + From<Value>
57 + From<Map<Self>>
58 + From<Tuple<Self>>
59 + From<Self::Class>
60 + From<Self::Closure>
61 + Clone
62 + fmt::Debug
63 + 'static
64{
65 type FE: ThreadSafe + Clone;
66 type Txn: Transaction<Self::FE> + Gateway<Self>;
67 type Closure: ClosureInstance<Self>;
68
69 fn is_map(&self) -> bool;
71
72 fn is_tuple(&self) -> bool;
74}
75
76pub trait ToState<State: StateInstance> {
78 fn to_state(&self) -> State;
79}
80
81impl<State: StateInstance, T: Clone + Into<State>> ToState<State> for T {
82 fn to_state(&self) -> State {
83 self.clone().into()
84 }
85}
86
87#[async_trait]
88pub trait Handler<'a, State: StateInstance>: Send {
89 fn get<'b>(self: Box<Self>) -> Option<GetHandler<'a, 'b, State::Txn, State>>
90 where
91 'b: 'a,
92 {
93 None
94 }
95
96 fn put<'b>(self: Box<Self>) -> Option<PutHandler<'a, 'b, State::Txn, State>>
97 where
98 'b: 'a,
99 {
100 None
101 }
102
103 fn post<'b>(self: Box<Self>) -> Option<PostHandler<'a, 'b, State::Txn, State>>
104 where
105 'b: 'a,
106 {
107 None
108 }
109
110 fn delete<'b>(self: Box<Self>) -> Option<DeleteHandler<'a, 'b, State::Txn>>
111 where
112 'b: 'a,
113 {
114 None
115 }
116}
117
118pub trait Route<State>: Send + Sync {
119 fn route<'a>(&'a self, path: &'a [PathSegment]) -> Option<Box<dyn Handler<'a, State> + 'a>>;
120}
121
122#[async_trait]
123pub trait Public<State: StateInstance> {
124 async fn get(&self, txn: &State::Txn, path: &[PathSegment], key: Value) -> TCResult<State>;
125
126 async fn put(
127 &self,
128 txn: &State::Txn,
129 path: &[PathSegment],
130 key: Value,
131 value: State,
132 ) -> TCResult<()>;
133
134 async fn post(
135 &self,
136 txn: &State::Txn,
137 path: &[PathSegment],
138 params: Map<State>,
139 ) -> TCResult<State>;
140
141 async fn delete(&self, txn: &State::Txn, path: &[PathSegment], key: Value) -> TCResult<()>;
142}
143
144#[async_trait]
145impl<State: StateInstance, T: Route<State> + fmt::Debug> Public<State> for T {
146 async fn get(&self, txn: &State::Txn, path: &[PathSegment], key: Value) -> TCResult<State> {
147 let handler = self
148 .route(path)
149 .ok_or_else(|| TCError::not_found(TCPath::from(path)))?;
150
151 if let Some(get_handler) = handler.get() {
152 get_handler(txn, key).await
153 } else {
154 Err(TCError::method_not_allowed(
155 HandlerType::Get,
156 TCPath::from(path),
157 ))
158 }
159 }
160
161 async fn put(
162 &self,
163 txn: &State::Txn,
164 path: &[PathSegment],
165 key: Value,
166 value: State,
167 ) -> TCResult<()> {
168 let handler = self
169 .route(path)
170 .ok_or_else(|| not_found!("{} in {:?}", TCPath::from(path), self))?;
171
172 if let Some(put_handler) = handler.put() {
173 put_handler(txn, key, value).await
174 } else {
175 Err(TCError::method_not_allowed(
176 HandlerType::Put,
177 TCPath::from(path),
178 ))
179 }
180 }
181
182 async fn post(
183 &self,
184 txn: &State::Txn,
185 path: &[PathSegment],
186 params: Map<State>,
187 ) -> TCResult<State> {
188 let handler = self
189 .route(path)
190 .ok_or_else(|| TCError::not_found(TCPath::from(path)))?;
191
192 if let Some(post_handler) = handler.post() {
193 post_handler(txn, params).await
194 } else {
195 Err(TCError::method_not_allowed(
196 HandlerType::Post,
197 TCPath::from(path),
198 ))
199 }
200 }
201
202 async fn delete(&self, txn: &State::Txn, path: &[PathSegment], key: Value) -> TCResult<()> {
203 let handler = self
204 .route(path)
205 .ok_or_else(|| TCError::not_found(TCPath::from(path)))?;
206
207 if let Some(delete_handler) = handler.delete() {
208 delete_handler(txn, key).await
209 } else {
210 Err(TCError::method_not_allowed(
211 HandlerType::Delete,
212 TCPath::from(path),
213 ))
214 }
215 }
216}