tablo_core/resource/pages.rs
1//! [`ResourcePage`]: the record pages a resource serves beside its list, and
2//! [`ResourceDef::without_page`], which turns one off.
3
4use super::{Resource, ResourceDef};
5
6/// A record page a resource serves beside its list, unless
7/// [`without_page`](ResourceDef::without_page) turns it off.
8///
9/// A resource serves its list, and these pages by default:
10///
11/// - the create page and the edit page, when it has a record form: a resource whose `Form` is
12/// [`NoForm`](crate::NoForm) serves neither;
13/// - the view page, which shows its [`detail`](ResourceDef::detail).
14///
15/// The policy decides who may open a page, per request, but never whether it exists.
16#[derive(Clone, Copy, Debug, PartialEq, Eq)]
17#[non_exhaustive]
18pub enum ResourcePage {
19 /// The create page, for a resource whose records arrive another way: a seed, an action.
20 /// Without it, mounting skips the check that a create fills every non-nullable column, the
21 /// list and the relations offer no create button, and an
22 /// [`importable`](ResourceDef::importable) resource refuses to mount.
23 Create,
24 /// The view page. Turned off, its route answers 404 and no row links to it.
25 View,
26}
27
28impl<R: Resource> ResourceDef<R> {
29 /// Turns `page` off.
30 ///
31 /// ```rust
32 /// # #[derive(Debug, Clone, toasty::Model, tablo_core::ModelColumns)]
33 /// # struct Post { #[key] #[auto] id: uuid::Uuid, title: String }
34 /// # struct PostResource;
35 /// # impl tablo_core::Resource for PostResource {
36 /// # type Model = Post;
37 /// # type Form = tablo_core::NoForm<Post>;
38 /// # }
39 /// use tablo_core::{ResourceDef, ResourcePage};
40 ///
41 /// ResourceDef::<PostResource>::new().without_page(ResourcePage::View);
42 /// ```
43 #[must_use]
44 pub fn without_page(mut self, page: ResourcePage) -> Self {
45 match page {
46 ResourcePage::Create => self.pages.create = false,
47 ResourcePage::View => self.pages.view = false,
48 }
49 self
50 }
51}
52
53/// The record pages a resource serves: on a [`ResourceDef`], the ones it has not turned off; on
54/// a mounted resource, the ones it serves.
55#[derive(Clone, Copy, Debug)]
56pub(crate) struct Pages {
57 pub(crate) create: bool,
58 pub(crate) view: bool,
59 pub(crate) edit: bool,
60}
61
62impl Default for Pages {
63 fn default() -> Self {
64 Self {
65 create: true,
66 view: true,
67 edit: true,
68 }
69 }
70}
71
72impl Pages {
73 /// The pages a resource that turned off none of `declared` serves, with a record form when
74 /// `has_form`.
75 pub(crate) fn served(declared: Self, has_form: bool) -> Self {
76 Self {
77 create: has_form && declared.create,
78 view: declared.view,
79 edit: has_form && declared.edit,
80 }
81 }
82}