use crate::components::http::server::cookie::AstraHTTPCookie;
use axum::{
http::{HeaderMap, HeaderName, HeaderValue, StatusCode},
response::Redirect,
};
#[derive(Debug, Clone)]
pub enum CookieOperation<'a> {
Add(AstraHTTPCookie<'a>),
Remove { key: String },
}
#[derive(Debug, Clone)]
pub struct ResponseLua<'a> {
pub status_code: StatusCode,
pub headers: HeaderMap,
pub cookie_operations: Vec<CookieOperation<'a>>,
pub redirect: Option<Redirect>,
}
impl Default for ResponseLua<'_> {
fn default() -> Self {
Self {
status_code: StatusCode::OK,
headers: HeaderMap::new(),
cookie_operations: Vec::new(),
redirect: None,
}
}
}
impl mlua::UserData for ResponseLua<'_> {
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
methods.add_method_mut("set_status_code", |_, this, status_code: u16| {
match StatusCode::from_u16(status_code) {
Ok(status_code) => {
this.status_code = status_code;
Ok(())
}
Err(e) => Err(mlua::Error::runtime(format!(
"Could not set the response HTTP status code: {e:#?}"
))),
}
});
methods.add_method_mut("redirect_to", |_, this, redirect_path: String| {
this.redirect = Some(Redirect::to(&redirect_path));
Ok(())
});
methods.add_method_mut("redirect_temporary", |_, this, redirect_path: String| {
this.redirect = Some(Redirect::temporary(&redirect_path));
Ok(())
});
methods.add_method_mut("redirect_permanent", |_, this, redirect_path: String| {
this.redirect = Some(Redirect::permanent(&redirect_path));
Ok(())
});
methods.add_method_mut(
"set_header",
|_, this, (header_key, header_value): (String, String)| match HeaderName::from_lowercase(
header_key.to_lowercase().as_bytes(),
) {
Ok(header_key) => match HeaderValue::from_str(&header_value) {
Ok(header_value) => {
this.headers.insert(header_key, header_value);
Ok(())
}
Err(e) => Err(mlua::Error::runtime(format!(
"Could not set the header (value): {e:#?}"
))),
},
Err(e) => Err(mlua::Error::runtime(format!(
"Could not set the header (key): {e:#?}"
))),
},
);
methods.add_method_mut("remove_header", |_, this, header_key: String| {
match HeaderName::from_lowercase(header_key.to_lowercase().as_bytes()) {
Ok(header_key) => {
this.headers.remove(header_key);
Ok(())
}
Err(e) => Err(mlua::Error::runtime(format!(
"Could not set the header (key): {e:#?}"
))),
}
});
methods.add_method("get_headers", |lua, this, ()| {
let header_map = lua.create_table()?;
for (key, value) in this.headers.iter() {
header_map.set(key.as_str(), String::from_utf8_lossy(value.as_bytes()))?;
}
Ok(header_map)
});
methods.add_method_mut("set_cookie", |_, this, cookie: AstraHTTPCookie| {
this.cookie_operations.push(CookieOperation::Add(cookie));
Ok(())
});
methods.add_method_mut("remove_cookie", |_, this, key: String| {
this.cookie_operations.push(CookieOperation::Remove { key });
Ok(())
});
}
}