Skip to main content

cnctd_server/server/
handlers.rs

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                // Not a binary route — reject so warp falls through to next filter
127                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        // Ok(warp::redirect::found(url.parse::<Uri>().unwrap()).into_response())
157    }
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