Skip to main content

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}