use axum::http::HeaderMap;
use cookie::Cookie;
use roto::{Runtime, Val, roto_method};
use std::sync::Arc;
use crate::means_of_production::Error;
#[derive(Debug, Clone)]
pub struct Request {
pub method: String,
pub headers: HeaderMap,
pub path: String,
}
pub fn register_request_type(runtime: &mut Runtime) -> Result<(), Error> {
runtime
.register_clone_type_with_name::<Request>("Request", "Representation of a HTTP request")?;
#[roto_method(runtime, Request)]
fn path(request: Val<Request>) -> Arc<str> {
request.path.clone().into()
}
#[roto_method(runtime, Request)]
fn method(request: Val<Request>) -> Arc<str> {
request.method.clone().into()
}
#[roto_method(runtime, Request)]
fn header(request: Val<Request>, name: Arc<str>) -> Arc<str> {
let h = request.headers.get(name.to_string());
let s = h.map(|v| String::from_utf8_lossy(v.as_bytes()));
s.unwrap_or_default().into()
}
#[roto_method(runtime, Request)]
fn cookie(request: Val<Request>, name: Arc<str>) -> Arc<str> {
let Some(cookie_header) = request.headers.get("cookie") else {
return "".into();
};
let cookie_header = match cookie_header.to_str() {
Ok(v) => v,
Err(e) => {
tracing::error!(
{ cookies = format!("{cookie_header:?}") },
"Unable to parse cookie header: {e}"
);
return "".into();
}
};
for cookie in Cookie::split_parse(cookie_header) {
let Ok(cookie) = cookie else {
tracing::error!("Unable to parse cookie");
return "".into();
};
if cookie.name() == name.as_ref() {
return cookie.value().into();
}
}
"".into()
}
Ok(())
}