1use crate::cookies::Cookies;
4use crate::error::{Error, Result};
5use serde::de::DeserializeOwned;
6use std::cell::OnceCell;
7use std::collections::HashMap;
8
9#[derive(Debug, Clone)]
11pub struct Params {
12 inner: HashMap<String, String>,
13}
14
15impl Params {
16 pub fn new() -> Self {
17 Self {
18 inner: HashMap::new(),
19 }
20 }
21
22 pub fn insert(&mut self, key: String, value: String) {
23 self.inner.insert(key, value);
24 }
25
26 pub fn get(&self, key: &str) -> Result<&str> {
27 self.inner
28 .get(key)
29 .map(|s| s.as_str())
30 .ok_or_else(|| Error::bad_request(format!("Missing param: {}", key)))
31 }
32
33 pub fn get_opt(&self, key: &str) -> Option<&str> {
34 self.inner.get(key).map(|s| s.as_str())
35 }
36}
37
38impl Default for Params {
39 fn default() -> Self {
40 Self::new()
41 }
42}
43
44#[derive(Debug, Clone)]
46pub struct Query {
47 inner: HashMap<String, String>,
48}
49
50impl Query {
51 pub fn new() -> Self {
52 Self {
53 inner: HashMap::new(),
54 }
55 }
56
57 pub fn parse_query_string(query: &str) -> Self {
58 let mut q = Query::new();
59 for pair in query.split('&') {
60 if let Some((key, value)) = pair.split_once('=') {
61 q.inner.insert(
62 key.to_string(),
63 urlencoding::decode(value).unwrap_or_default().to_string(),
64 );
65 }
66 }
67 q
68 }
69
70 pub fn get(&self, key: &str) -> Option<&str> {
71 self.inner.get(key).map(|s| s.as_str())
72 }
73
74 pub fn parse<T: DeserializeOwned>(&self) -> Result<T> {
75 let value = serde_json::to_value(&self.inner)
76 .map_err(|e| Error::internal(format!("Failed to serialize query params: {}", e)))?;
77 serde_json::from_value(value)
78 .map_err(|e| Error::bad_request(format!("Invalid query params: {}", e)))
79 }
80}
81
82impl Default for Query {
83 fn default() -> Self {
84 Self::new()
85 }
86}
87
88pub struct Request {
90 pub method: http::Method,
91 pub uri: http::Uri,
92 pub headers: http::HeaderMap,
93 pub body: bytes::Bytes,
94 pub params: Params,
95 pub query: Query,
96 cookies: OnceCell<Cookies>,
97}
98
99impl Request {
100 pub fn new(
101 method: http::Method,
102 uri: http::Uri,
103 headers: http::HeaderMap,
104 body: bytes::Bytes,
105 ) -> Self {
106 let query = uri
107 .query()
108 .map(Query::parse_query_string)
109 .unwrap_or_default();
110
111 Self {
112 method,
113 uri,
114 headers,
115 body,
116 params: Params::new(),
117 query,
118 cookies: OnceCell::new(),
119 }
120 }
121
122 pub fn cookies(&self) -> &Cookies {
124 self.cookies.get_or_init(|| {
125 if let Some(cookie_header) = self.headers.get("cookie") {
126 if let Ok(cookie_str) = cookie_header.to_str() {
127 Cookies::parse(cookie_str)
128 } else {
129 Cookies::new()
130 }
131 } else {
132 Cookies::new()
133 }
134 })
135 }
136
137 pub fn json<T: DeserializeOwned>(&self) -> Result<T> {
139 serde_json::from_slice(&self.body)
140 .map_err(|e| Error::bad_request(format!("Invalid JSON: {}", e)))
141 }
142}