1use std::sync::Arc;
2use std::fmt::Debug;
3use serde::{de::DeserializeOwned, Deserialize, Serialize};
4use serde_json::Value;
5use warp::{reject::Rejection, reply::Reply};
6use warp::hyper::Uri;
7
8use warp::http::Response;
9
10use crate::router::HttpMethod;
11use crate::router::RestRouterFunction;
12
13pub type Result<T> = std::result::Result<T, Rejection>;
14
15
16pub trait RedirectHandler<Value>: Send + Sync
17where
18 Value: Serialize + DeserializeOwned + Send + Sync,
19{
20 fn handle(&self, data: Value) -> anyhow::Result<String>;
21}
22
23#[derive(Serialize, Deserialize, Debug, Clone)]
24pub struct RedirectQuery {
25 pub path: String,
26 pub client_id: String,
27 pub size: Option<String>,
28}
29
30pub struct Handler;
31
32impl Handler {
33 pub async fn post<R>(path: String, data: Value, auth_token: Option<String>, client_id: Option<String>, ip_address: Option<String>, router: Arc<R>) -> Result<impl warp::Reply>
34 where
35 R: RestRouterFunction,
36 {
37 match router.route(HttpMethod::POST, path, data, auth_token, client_id, ip_address).await {
38 Ok(response) => {
39 let status = &response.status.to_warp_status_code();
40 let json = warp::reply::json(&response);
41
42 Ok(warp::reply::with_status(json, status.clone()))
43 }
44 Err(e) => {
45 let status = &e.status.to_warp_status_code();
46 let json = warp::reply::json(&e);
47
48 Ok(warp::reply::with_status(json, status.clone()))
49 }
50 }
51 }
52
53 pub async fn get<R>(path: String, data: Value, auth_token: Option<String>, client_id: Option<String>, ip_address: Option<String>, router: Arc<R>) -> Result<impl warp::Reply>
54 where
55 R: RestRouterFunction,
56 {
57 match router.route(HttpMethod::GET, path, data, auth_token, client_id, ip_address).await {
58 Ok(response) => {
59 let status = &response.status.to_warp_status_code();
60 let json = warp::reply::json(&response);
61
62 Ok(warp::reply::with_status(json, status.clone()))
63 }
64 Err(e) => {
65 let status = &e.status.to_warp_status_code();
66 let json = warp::reply::json(&e);
67
68 Ok(warp::reply::with_status(json, status.clone()))
69 }
70 }
71 }
72
73 pub async fn put<R>(path: String, data: Value, auth_token: Option<String>, client_id: Option<String>, ip_address: Option<String>, router: Arc<R>) -> Result<impl warp::Reply>
74 where
75 R: RestRouterFunction,
76 {
77 match router.route(HttpMethod::PUT, path, data, auth_token, client_id, ip_address).await {
78 Ok(response) => {
79 let status = &response.status.to_warp_status_code();
80 let json = warp::reply::json(&response);
81
82 Ok(warp::reply::with_status(json, status.clone()))
83 }
84 Err(e) => {
85 let status = &e.status.to_warp_status_code();
86 let json = warp::reply::json(&e);
87
88 Ok(warp::reply::with_status(json, status.clone()))
89 }
90 }
91 }
92
93 pub async fn delete<R>(path: String, data: Value, auth_token: Option<String>, client_id: Option<String>, ip_address: Option<String>, router: Arc<R>) -> Result<impl warp::Reply>
94 where
95 R: RestRouterFunction,
96 {
97 match router.route(HttpMethod::DELETE, path, data, auth_token, client_id, ip_address).await {
98 Ok(response) => {
99 let status = &response.status.to_warp_status_code();
100 let json = warp::reply::json(&response);
101
102 Ok(warp::reply::with_status(json, status.clone()))
103 }
104 Err(e) => {
105 let status = &e.status.to_warp_status_code();
106 let json = warp::reply::json(&e);
107
108 Ok(warp::reply::with_status(json, status.clone()))
109 }
110 }
111 }
112
113 pub async fn get_binary<R>(path: String, data: Value, auth_token: Option<String>, client_id: Option<String>, ip_address: Option<String>, router: Arc<R>) -> Result<impl warp::Reply>
114 where
115 R: RestRouterFunction,
116 {
117 match router.route_binary(HttpMethod::GET, path, data, auth_token, client_id, ip_address).await {
118 Ok(Some(binary)) => {
119 let response = Response::builder()
120 .header("content-type", binary.content_type)
121 .body(binary.data)
122 .unwrap();
123 Ok(response)
124 }
125 Ok(None) => {
126 Err(warp::reject::not_found())
128 }
129 Err(e) => {
130 let status = e.status.to_warp_status_code();
131 let body = serde_json::to_vec(&e).unwrap_or_default();
132 let response = Response::builder()
133 .status(status)
134 .header("content-type", "application/json")
135 .body(body)
136 .unwrap();
137 Ok(response)
138 }
139 }
140 }
141
142 pub async fn get_redirect<R>(path: String, data: Value, auth_token: Option<String>, client_id: Option<String>, router: Arc<R>) -> Result<impl warp::Reply>
143 where
144
145 R: RestRouterFunction,
146 {
147 println!("File router. path: {}", path);
148 println!("File HANDLER, data: {:?}", data);
149 let url = router.route_redirect(path, data, auth_token, client_id).await;
150 println!("File HANDLER, url: {}", url);
151 match url.parse::<Uri>() {
152 Ok(uri) => Ok(warp::redirect::found(uri).into_response()),
153 Err(_) => Err(warp::reject::not_found())
154 }
155
156 }
158
159 pub async fn api_redirect<Value, H>(data: Value, handler: Arc<H>) -> Result<impl warp::Reply>
160 where
161 Value: Serialize + DeserializeOwned + Send + Sync,
162 H: RedirectHandler<Value>,
163 {
164 match handler.handle(data) {
165 Ok(html_response) => Ok(warp::reply::html(html_response)),
166 Err(_) => Err(warp::reject::reject()),
167 }
168 }
169
170
171
172}
173