rustbasic_core/
requests.rs1use serde_json::{json, Value};
2use std::collections::HashMap;
3use crate::validator::Validate;
4use crate::router::{Response, IntoResponse, Json};
5use crate::session::Session;
6
7#[derive(Clone)]
8pub struct Request {
9 pub inputs: Value,
10 pub method: http::Method,
11 pub path: String,
12 pub headers: HashMap<String, String>,
13 pub session: Session,
14 pub state: crate::AppState,
15 pub ip_address: String,
16 pub params: HashMap<String, String>,
18}
19
20impl Request {
21 pub fn input(&self, key: &str) -> Option<&Value> {
22 self.inputs.get(key)
23 }
24
25 pub fn input_as_str(&self, key: &str) -> Option<&str> {
26 self.inputs.get(key).and_then(|v| v.as_str())
27 }
28
29 pub fn query(&self, key: &str) -> Option<&str> {
30 self.input_as_str(key)
31 }
32
33 pub fn all(&self) -> &Value {
34 &self.inputs
35 }
36
37 pub fn param(&self, key: &str) -> Option<&str> {
39 self.params.get(key).map(|s| s.as_str())
40 }
41
42 pub fn validate<T: Validate + serde::de::DeserializeOwned>(&self) -> Result<T, Box<(http::StatusCode, Response)>> {
43 let data: T = serde_json::from_value(self.inputs.clone()).map_err(|e| {
44 Box::new((http::StatusCode::UNPROCESSABLE_ENTITY,
45 Json(json!({ "error": "Invalid format", "detail": e.to_string() })).into_response()))
46 })?;
47
48 data.validate().map_err(|errors| {
49 self.session.set("old", self.inputs.clone());
51
52 self.session.set("errors", errors.clone());
54
55 Box::new((http::StatusCode::UNPROCESSABLE_ENTITY,
56 Json(json!({ "errors": errors })).into_response()))
57 })?;
58
59 Ok(data)
60 }
61}