use topcoat_core::{context::Cx, error::Result};
use topcoat_view::View;
use crate::{Body, Layout, Methods, Page, Path, PathBuf, RouteId, ViewFuture};
#[doc(hidden)]
pub trait ModulePage: Send + Sync + 'static {
fn id(&self) -> RouteId;
fn methods(&self) -> Methods<'_>;
fn module_path(&self) -> &'static str;
fn render<'cx>(&'cx self, cx: &'cx Cx, body: Body) -> ViewFuture<'cx>;
}
impl<P: ModulePage + ?Sized> ModulePage for &'static P {
fn id(&self) -> RouteId {
(**self).id()
}
fn methods(&self) -> Methods<'_> {
(**self).methods()
}
fn module_path(&self) -> &'static str {
(**self).module_path()
}
fn render<'cx>(&'cx self, cx: &'cx Cx, body: Body) -> ViewFuture<'cx> {
(**self).render(cx, body)
}
}
#[cfg(feature = "discover")]
inventory::collect!(&'static dyn ModulePage);
pub(super) struct ResolvedPage<P> {
page: P,
path: PathBuf,
}
impl<P: ModulePage> ResolvedPage<P> {
pub(super) fn new(page: P, path: PathBuf) -> Self {
Self { page, path }
}
}
impl<P: ModulePage> Page for ResolvedPage<P> {
fn id(&self) -> RouteId {
self.page.id()
}
fn methods(&self) -> Methods<'_> {
self.page.methods()
}
fn path(&self) -> &Path {
&self.path
}
fn render<'cx>(&'cx self, cx: &'cx Cx, body: Body) -> ViewFuture<'cx> {
self.page.render(cx, body)
}
}
#[doc(hidden)]
pub trait ModuleLayout: Send + Sync + 'static {
fn module_path(&self) -> &'static str;
fn render<'cx>(&'cx self, cx: &'cx Cx, slot: Result<View>) -> ViewFuture<'cx>;
}
impl<L: ModuleLayout + ?Sized> ModuleLayout for &'static L {
fn module_path(&self) -> &'static str {
(**self).module_path()
}
fn render<'cx>(&'cx self, cx: &'cx Cx, slot: Result<View>) -> ViewFuture<'cx> {
(**self).render(cx, slot)
}
}
#[cfg(feature = "discover")]
inventory::collect!(&'static dyn ModuleLayout);
pub(super) struct ResolvedLayout<L> {
layout: L,
path: PathBuf,
}
impl<L: ModuleLayout> ResolvedLayout<L> {
pub(super) fn new(layout: L, path: PathBuf) -> Self {
Self { layout, path }
}
}
impl<L: ModuleLayout> Layout for ResolvedLayout<L> {
fn path(&self) -> &Path {
&self.path
}
fn render<'cx>(&'cx self, cx: &'cx Cx, slot: Result<View>) -> ViewFuture<'cx> {
self.layout.render(cx, slot)
}
}