use std::marker::PhantomData;
use super::props_schema::PropsSchema;
#[derive(Debug, Clone, Copy)]
pub struct PageContract<P> {
name: &'static str,
marker: PhantomData<fn() -> P>,
}
impl<P> PageContract<P> {
#[must_use]
pub const fn new(name: &'static str) -> Self {
Self {
name,
marker: PhantomData,
}
}
#[must_use]
pub const fn name(self) -> &'static str {
self.name
}
}
pub trait PageType: super::ClientData + Sized {
const CONTRACT: PageContract<Self>;
}
#[derive(Debug, Clone, Copy)]
pub struct PageContractEntry {
pub name: &'static str,
pub schema: fn() -> PropsSchema,
}
impl PageContractEntry {
#[must_use]
pub const fn new(name: &'static str, schema: fn() -> PropsSchema) -> Self {
Self { name, schema }
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::inertia::contracts::{ClientData, ContractType};
#[derive(serde::Serialize)]
struct Home;
impl ClientData for Home {
fn exposure_schema() -> PropsSchema {
PropsSchema::new().required("name", ContractType::string())
}
}
const HOME: PageContract<Home> = PageContract::new("Home");
const HOME_ENTRY: PageContractEntry = PageContractEntry::new("Home", Home::exposure_schema);
#[test]
fn contract_carries_the_page_identity() {
assert_eq!(HOME.name(), "Home");
}
#[test]
fn entry_schema_pointer_builds_the_exposure_schema() {
assert_eq!(HOME_ENTRY.name, "Home");
assert_eq!((HOME_ENTRY.schema)(), Home::exposure_schema());
}
}