1use serde::{Deserialize, Serialize};
2use crate::ffi::string_to_ptr;
3use crate::utils::log;
4
5#[derive(Deserialize)]
6struct Request {
7 method: String,
8 path: String,
9 headers: std::collections::HashMap<String, String>,
10 body: String,
11}
12
13#[derive(Serialize)]
14struct Response {
15 status_code: u16,
16 headers: std::collections::HashMap<String, String>,
17 body: String,
18}
19
20#[no_mangle]
21pub extern "C" fn handle_http_request(request_ptr: *const u8, request_len: usize) -> *const u8 {
22 let request_str = unsafe { std::str::from_utf8_unchecked(std::slice::from_raw_parts(request_ptr, request_len)) };
23 log(&format!("Received request: {}", request_str));
24
25 let request: Request = match serde_json::from_str(request_str) {
26 Ok(v) => v,
27 Err(e) => {
28 let error_msg = format!("{{\"error\": \"Invalid JSON: {}\"}}", e);
29 return string_to_ptr(&error_msg);
30 }
31 };
32
33 let response = handle_request(request);
34 let response_json = serde_json::to_string(&response).unwrap_or_else(|e| format!("{{\"error\": \"{}\"}}", e));
35
36 log(&format!("Sending response: {}", response_json));
37 string_to_ptr(&response_json)
38}
39
40fn handle_request(req: Request) -> Response {
41 match (req.method.as_str(), req.path.as_str()) {
42 ("GET", "/api/data") => handle_data_request(req),
43 ("POST", "/api/data") => handle_data_request(req),
44 ("PUT", "/api/data") => handle_data_request(req),
45 ("DELETE", "/api/data") => handle_data_request(req),
46 _ => Response {
47 status_code: 404,
48 headers: [("Content-Type".to_string(), "text/plain".to_string())].into(),
49 body: "Not Found".to_string(),
50 },
51 }
52}
53
54fn handle_data_request(req: Request) -> Response {
55 match req.method.as_str() {
56 "GET" => Response {
57 status_code: 200,
58 headers: [("Content-Type".to_string(), "application/json".to_string())].into(),
59 body: r#"{"message": "Hello from Rust WebAssembly API!"}"#.to_string(),
60 },
61 "POST" => Response {
62 status_code: 201,
63 headers: [("Content-Type".to_string(), "application/json".to_string())].into(),
64 body: r#"{"message": "Data created successfully"}"#.to_string(),
65 },
66 "PUT" => Response {
67 status_code: 200,
68 headers: [("Content-Type".to_string(), "application/json".to_string())].into(),
69 body: r#"{"message": "Data updated successfully"}"#.to_string(),
70 },
71 "DELETE" => Response {
72 status_code: 200,
73 headers: [("Content-Type".to_string(), "application/json".to_string())].into(),
74 body: r#"{"message": "Data deleted successfully"}"#.to_string(),
75 },
76 _ => Response {
77 status_code: 405,
78 headers: [("Content-Type".to_string(), "text/plain".to_string())].into(),
79 body: "Method Not Allowed".to_string(),
80 },
81 }
82}