use crate::request::RequestContext;
use zino_core::{Map, bail, error::Error, extension::JsonObjectExt};
#[derive(Debug, Clone, Default)]
pub struct InertiaPage {
component: String,
props: Map,
url: String,
version: String,
partial_data: Vec<String>,
redirect_url: Option<String>,
}
impl InertiaPage {
#[inline]
pub fn new(component: impl ToString) -> Self {
Self {
component: component.to_string(),
props: Map::new(),
url: String::new(),
version: String::new(),
partial_data: Vec::new(),
redirect_url: None,
}
}
pub fn partial_reload<Ctx: RequestContext>(ctx: &Ctx) -> Result<Self, Error> {
if !ctx.get_header("x-inertia").is_some_and(|s| s == "true") {
bail!("invalid `x-inertia` header");
}
let Some(component) = ctx.get_header("x-inertia-partial-component") else {
bail!("invalid `x-inertia-partial-component` header");
};
let mut page = Self {
component: component.to_owned(),
props: Map::new(),
url: ctx.request_path().to_owned(),
version: String::new(),
partial_data: Vec::new(),
redirect_url: None,
};
if let Some(version) = ctx.get_header("x-inertia-version") {
page.version = version.to_owned();
}
if let Some(data) = ctx.get_header("x-inertia-partial-data") {
page.partial_data = data.split(',').map(|s| s.trim().to_owned()).collect();
}
Ok(page)
}
pub fn context<Ctx: RequestContext>(mut self, ctx: &Ctx) -> Self {
self.url = ctx.request_path().to_owned();
if let Some(version) = ctx.get_header("x-inertia-version") {
self.version = version.to_owned();
}
if let Some(component) = ctx.get_header("x-inertia-partial-component") {
self.component = component.to_owned();
}
if let Some(data) = ctx.get_header("x-inertia-partial-data") {
self.partial_data = data.split(',').map(|s| s.trim().to_owned()).collect();
}
self
}
#[inline]
pub fn append_props(&mut self, props: &mut Map) {
self.props.append(props);
}
#[inline]
pub fn set_url(&mut self, url: String) {
self.url = url;
}
#[inline]
pub fn set_version(&mut self, version: String) {
self.version = version;
}
#[inline]
pub fn set_redirect_url(&mut self, url: String) {
self.redirect_url = Some(url);
}
#[inline]
pub fn component(&self) -> &str {
&self.component
}
#[inline]
pub fn props(&self) -> &Map {
&self.props
}
#[inline]
pub fn url(&self) -> &str {
&self.url
}
#[inline]
pub fn version(&self) -> &str {
&self.version
}
#[inline]
pub fn partial_data(&self) -> &[String] {
&self.partial_data
}
#[inline]
pub fn redirect_url(&self) -> Option<&str> {
self.redirect_url.as_deref()
}
#[inline]
pub fn into_json_response(self) -> Map {
let mut map = Map::new();
map.upsert("component", self.component);
map.upsert("props", self.props);
map.upsert("url", self.url);
map.upsert("version", self.version);
map
}
}