Skip to main content

tablo_core/declaration/
site.rs

1//! [`DeclarationError`], one declaration mistake, and [`Site`]: where in the declaration it is.
2
3use std::fmt;
4
5use super::DeclarationErrorKind;
6
7/// One declaration mistake: who declares it, where, and what is wrong.
8#[derive(Debug, Clone, PartialEq, Eq)]
9#[non_exhaustive]
10pub struct DeclarationError {
11    /// The resource or page type that declares it; `None` for the panel's own configuration.
12    pub resource: Option<&'static str>,
13    /// The part of the declaration it is in.
14    pub site: Site,
15    /// What is wrong.
16    pub kind: DeclarationErrorKind,
17}
18
19impl DeclarationError {
20    /// A mistake in the panel's own configuration.
21    pub(crate) fn panel(kind: DeclarationErrorKind) -> Self {
22        Self {
23            resource: None,
24            site: Site::Panel,
25            kind,
26        }
27    }
28
29    /// A mistake in `T`'s declaration.
30    pub(crate) fn of<T>(site: Site, kind: DeclarationErrorKind) -> Self {
31        Self {
32            resource: Some(std::any::type_name::<T>()),
33            site,
34            kind,
35        }
36    }
37}
38
39impl std::error::Error for DeclarationError {}
40
41/// The part of a declaration a [`DeclarationError`] is in.
42#[derive(Debug, Clone, PartialEq, Eq)]
43#[non_exhaustive]
44pub enum Site {
45    /// The panel's own configuration: its prefix, served directories, assets and auth.
46    Panel,
47    /// The resource or page itself: its registration, slug, actions or create columns, or a
48    /// second home page.
49    Registration,
50    /// `ResourceDef::tenancy`.
51    Tenancy,
52    /// `ResourceDef::soft_delete`.
53    SoftDelete,
54    /// The `ResourceDef::field_access` over this field.
55    FieldAccess(String),
56    /// `ResourceDef::record_title`.
57    RecordTitle,
58    /// `ResourceDef::table`.
59    Table,
60    /// `ResourceDef::form`, checked against the record form.
61    Form,
62    /// `ResourceDef::detail`.
63    Detail,
64    /// The `ResourceDef::relation` to the resource with this slug, or this type when the panel
65    /// does not register it.
66    Relation(String),
67    /// The `ResourceDef::record_page` at this slug.
68    RecordPage(String),
69}
70
71/// How an error message names the site after its resource: nothing for the resource itself.
72impl fmt::Display for Site {
73    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74        match self {
75            Self::Panel | Self::Registration => Ok(()),
76            Self::Tenancy => f.write_str(" tenancy"),
77            Self::SoftDelete => f.write_str(" soft delete"),
78            Self::FieldAccess(field) => write!(f, " field access `{field}`"),
79            Self::RecordTitle => f.write_str(" record title"),
80            Self::Table => f.write_str(" table"),
81            Self::Form => f.write_str(" form"),
82            Self::Detail => f.write_str(" detail"),
83            Self::Relation(key) => write!(f, " relation `{key}`"),
84            Self::RecordPage(slug) => write!(f, " record page `{slug}`"),
85        }
86    }
87}