1use std::ops::Deref;
2
3use mlua::{FromLua, Lua, Result, String as LuaString, Table, TableExt, Value};
4
5use crate::{Channel, Headers};
6
7#[derive(Clone)]
10pub struct HttpMessage<'lua> {
11 lua: &'lua Lua,
12 class: Table<'lua>,
13}
14
15impl<'lua> HttpMessage<'lua> {
16 #[inline]
18 pub fn add_header(&self, name: &str, value: impl AsRef<[u8]>) -> Result<()> {
19 let value = self.lua.create_string(value.as_ref())?;
20 self.class.call_method("add_header", (name, value))
21 }
22
23 #[inline]
26 pub fn append(&self, data: impl AsRef<[u8]>) -> Result<isize> {
27 let data = self.lua.create_string(data.as_ref())?;
28 self.class.call_method("append", data)
29 }
30
31 #[inline]
34 pub fn body(
35 &self,
36 offset: Option<isize>,
37 length: Option<isize>,
38 ) -> Result<Option<LuaString<'lua>>> {
39 let offset = offset.unwrap_or(0);
40 match length {
41 Some(length) => self.class.call_method("body", (offset, length)),
42 None => self.class.call_method("body", offset),
43 }
44 }
45
46 #[inline]
48 pub fn channel(&self) -> Result<Channel<'lua>> {
49 self.class.raw_get("channel")
50 }
51
52 #[inline]
54 pub fn eom(&self) -> Result<bool> {
55 self.class.call_method("eom", ())
56 }
57
58 #[inline]
60 pub fn del_header(&self, name: &str) -> Result<()> {
61 self.class.call_method("del_header", name)
62 }
63
64 #[inline]
66 pub fn get_headers(&self) -> Result<Headers<'lua>> {
67 self.class.call_method("get_headers", ())
68 }
69
70 #[inline]
72 pub fn get_stline(&self) -> Result<Table<'lua>> {
73 self.class.call_method("get_stline", ())
74 }
75
76 #[inline]
82 pub fn forward(&self, length: usize) -> Result<usize> {
83 self.class.call_method("forward", length)
84 }
85
86 #[inline]
88 pub fn input(&self) -> Result<usize> {
89 self.class.call_method("input", ())
90 }
91
92 #[inline]
98 pub fn insert(&self, data: impl AsRef<[u8]>, offset: Option<isize>) -> Result<isize> {
99 let data = self.lua.create_string(data.as_ref())?;
100 let offset = offset.unwrap_or(0);
101 self.class.call_method::<_, isize>("insert", (data, offset))
102 }
103
104 #[inline]
106 pub fn is_full(&self) -> Result<bool> {
107 self.class.call_method("is_full", ())
108 }
109
110 #[inline]
112 pub fn is_resp(&self) -> Result<bool> {
113 self.class.call_method("is_resp", ())
114 }
115
116 #[inline]
118 pub fn may_recv(&self) -> Result<bool> {
119 self.class.call_method("may_recv", ())
120 }
121
122 #[inline]
124 pub fn output(&self) -> Result<usize> {
125 self.class.call_method("output", ())
126 }
127
128 #[inline]
131 pub fn prepend(&self, data: impl AsRef<[u8]>) -> Result<isize> {
132 let data = self.lua.create_string(data.as_ref())?;
133 self.class.call_method::<_, isize>("prepend", data)
134 }
135
136 #[inline]
139 pub fn remove(&self, offset: Option<isize>, length: Option<usize>) -> Result<isize> {
140 let offset = offset.unwrap_or(0);
141 match length {
142 Some(length) => self.class.call_method("remove", (offset, length)),
143 None => self.class.call_method("remove", offset),
144 }
145 }
146
147 #[inline]
153 pub fn rep_header(&self, name: &str, regex: &str, replace: &str) -> Result<()> {
154 self.class.call_method("rep_header", (name, regex, replace))
155 }
156
157 #[inline]
162 pub fn rep_value(&self, name: &str, regex: &str, replace: &str) -> Result<()> {
163 self.class.call_method("rep_value", (name, regex, replace))
164 }
165
166 #[inline]
171 pub fn send(&self, data: impl AsRef<[u8]>) -> Result<isize> {
172 let data = self.lua.create_string(data.as_ref())?;
173 self.class.call_method("send", data)
174 }
175
176 #[inline]
179 pub fn set(
180 &self,
181 data: impl AsRef<[u8]>,
182 offset: Option<isize>,
183 length: Option<usize>,
184 ) -> Result<isize> {
185 let data = self.lua.create_string(data.as_ref())?;
186 let offset = offset.unwrap_or(0);
187 match length {
188 Some(length) => self.class.call_method("set", (data, offset, length)),
189 None => self.class.call_method("set", (data, offset)),
190 }
191 }
192
193 #[inline]
195 pub fn set_eom(&self, eom: bool) -> Result<()> {
196 match eom {
197 true => self.class.call_method("set_eom", ()),
198 false => self.class.call_method("unset_eom", ()),
199 }
200 }
201
202 #[inline]
204 pub fn set_header(&self, name: &str, value: impl AsRef<[u8]>) -> Result<()> {
205 let value = self.lua.create_string(value.as_ref())?;
206 self.class.call_method("set_header", (name, value))
207 }
208
209 #[inline]
211 pub fn set_method(&self, method: &str) -> Result<()> {
212 self.class.call_method("set_method", method)
213 }
214
215 #[inline]
217 pub fn set_path(&self, path: &str) -> Result<()> {
218 self.class.call_method("set_path", path)
219 }
220
221 #[inline]
223 pub fn set_query(&self, query: &str) -> Result<()> {
224 self.class.call_method("set_query", query)
225 }
226
227 #[inline]
230 pub fn set_status(&self, status: u16, reason: Option<&str>) -> Result<()> {
231 self.class.call_method("set_status", (status, reason))
232 }
233
234 #[inline]
236 pub fn set_uri(&self, uri: &str) -> Result<()> {
237 self.class.call_method("set_uri", uri)
238 }
239}
240
241impl<'lua> FromLua<'lua> for HttpMessage<'lua> {
242 #[inline]
243 fn from_lua(value: Value<'lua>, lua: &'lua Lua) -> Result<Self> {
244 let class = Table::from_lua(value, lua)?;
245 Ok(HttpMessage { lua, class })
246 }
247}
248
249impl<'lua> Deref for HttpMessage<'lua> {
250 type Target = Table<'lua>;
251
252 #[inline]
253 fn deref(&self) -> &Self::Target {
254 &self.class
255 }
256}