use toasty::{schema::Model, stmt::IntoExpr};
use crate::{Detail, Table};
#[diagnostic::on_unimplemented(
message = "`{Self}` declares no default columns",
label = "a resource's model implements `ModelColumns`",
note = "add `#[derive(tablo::ModelColumns)]` to `{Self}`, or `impl tablo::ModelColumns for \
{Self} {{ const TENANT_COLUMNS: &[&str] = &[..]; }}`, naming its `TenantId` fields, \
when its resources declare their own table and detail page"
)]
pub trait ModelColumns: Model + IntoExpr<Self> + Sized {
const TENANT_COLUMNS: &'static [&'static str];
fn table() -> Table<Self> {
Table::new(())
}
fn detail() -> Detail<Self> {
Detail::empty()
}
fn version(&self) -> Option<u64> {
None
}
const UNLOADS_RELATIONS: bool = false;
#[must_use]
fn bare(&self) -> Self
where
Self: Clone,
{
self.clone()
}
fn references(&self) -> Vec<(&'static str, Option<String>)> {
Vec::new()
}
}
#[doc(hidden)]
pub trait Reference {
fn spell(&self) -> Option<String>;
}
macro_rules! reference {
($($ty:ty),* $(,)?) => {
$(
impl Reference for $ty {
fn spell(&self) -> Option<String> {
Some(self.to_string())
}
}
impl Reference for Option<$ty> {
fn spell(&self) -> Option<String> {
self.as_ref().map(ToString::to_string)
}
}
)*
};
}
reference!(
uuid::Uuid,
crate::TenantId,
String,
i8,
i16,
i32,
i64,
isize,
u8,
u16,
u32,
u64,
usize,
);
pub(crate) fn bare<M: ModelColumns + Clone>(row: &M) -> M {
row.bare()
}
#[doc(hidden)]
pub mod pick;
#[cfg(test)]
mod tests;