use std::sync::Arc;
use topcoat::icon::IconData;
use super::{Action, Actions, Relation, Resource};
use crate::{
navigation::NavigationItem,
policy::{Deny, Policy},
schema::Schema,
table::Table,
tenancy::Tenancy,
};
pub struct ResourceDef<R: Resource> {
pub(crate) slug: Option<String>,
pub(crate) label: Option<String>,
pub(crate) plural_label: Option<String>,
pub(crate) icon: Option<IconData>,
pub(crate) navigation_order: i32,
pub(crate) navigation: Option<NavigationItem>,
pub(crate) policy: Arc<dyn Policy<R::Model>>,
pub(crate) tenancy: Tenancy<R::Model>,
pub(crate) table: Option<Table<R::Model>>,
pub(crate) form: Option<Schema>,
pub(crate) view: Option<Schema>,
pub(crate) relations: Vec<Relation<R::Model>>,
pub(crate) actions: Actions<R>,
pub(crate) create_columns: Vec<&'static str>,
}
impl<R: Resource> Default for ResourceDef<R> {
fn default() -> Self {
Self {
slug: None,
label: None,
plural_label: None,
icon: None,
navigation_order: 0,
navigation: None,
policy: Arc::new(Deny),
tenancy: Tenancy::none(),
table: None,
form: None,
view: None,
relations: Vec::new(),
actions: Actions::default(),
create_columns: Vec::new(),
}
}
}
impl<R: Resource> ResourceDef<R> {
pub fn new() -> Self {
Self::default()
}
#[must_use]
pub fn slug(mut self, slug: impl Into<String>) -> Self {
self.slug = Some(slug.into());
self
}
#[must_use]
pub fn label(mut self, label: impl Into<String>) -> Self {
self.label = Some(label.into());
self
}
#[must_use]
pub fn plural_label(mut self, label: impl Into<String>) -> Self {
self.plural_label = Some(label.into());
self
}
#[must_use]
pub fn icon(mut self, icon: IconData) -> Self {
self.icon = Some(icon);
self
}
#[must_use]
pub fn navigation_order(mut self, order: i32) -> Self {
self.navigation_order = order;
self
}
#[must_use]
pub fn navigation(mut self, item: NavigationItem) -> Self {
self.navigation = Some(item);
self
}
#[must_use]
pub fn policy(mut self, policy: impl Policy<R::Model>) -> Self {
self.policy = Arc::new(policy);
self
}
#[must_use]
pub fn tenancy(mut self, tenancy: Tenancy<R::Model>) -> Self {
self.tenancy = tenancy;
self
}
#[must_use]
pub fn table(mut self, table: Table<R::Model>) -> Self {
self.table = Some(table);
self
}
#[must_use]
pub fn form(mut self, form: Schema) -> Self {
self.form = Some(form);
self
}
#[must_use]
pub fn view(mut self, view: Schema) -> Self {
self.view = Some(view);
self
}
#[must_use]
pub fn relation(mut self, relation: Relation<R::Model>) -> Self {
self.relations.push(relation);
self
}
#[must_use]
pub fn action<A: Action<R>>(mut self) -> Self {
self.actions = self.actions.add::<A>();
self
}
#[must_use]
pub fn create_columns(mut self, columns: impl IntoIterator<Item = &'static str>) -> Self {
self.create_columns.extend(columns);
self
}
}
impl<R: Resource> std::fmt::Debug for ResourceDef<R> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ResourceDef")
.field("slug", &self.slug)
.field("label", &self.label)
.field("plural_label", &self.plural_label)
.field("relations", &self.relations)
.field("actions", &self.actions)
.finish_non_exhaustive()
}
}