1use std::{fmt::Display, future::Future};
2
3use axum::extract::FromRequestParts;
4pub use derived_cms_derive::Entity;
5use generic_array::{ArrayLength, GenericArray};
6use serde::{Deserialize, Serialize};
7
8use crate::{
9 app::AppError,
10 column::{Column, ColumnInfo},
11 context::ContextTrait,
12 input::InputInfo,
13};
14
15pub trait EntityBase<S: ContextTrait>:
16 for<'de> Deserialize<'de> + Serialize + Send + Sync + Unpin + 'static
17{
18 type Id: for<'de> Deserialize<'de> + Clone + Display + Serialize + Send;
20
21 type Create: for<'de> Deserialize<'de> + Serialize + Send + Sync + Unpin + 'static;
22 type Update: for<'de> Deserialize<'de> + Serialize + Send + Sync + Unpin + 'static;
23
24 type NumberOfColumns: ArrayLength;
25
26 fn name() -> &'static str;
27 fn name_plural() -> &'static str;
28
29 fn id(&self) -> &Self::Id;
31
32 fn columns() -> GenericArray<ColumnInfo, Self::NumberOfColumns>;
33 fn column_values(&self) -> GenericArray<&dyn Column, Self::NumberOfColumns>;
34 fn inputs(value: Option<&Self>) -> impl IntoIterator<Item = InputInfo<'_, S>>;
35}
36
37pub trait Entity<S: ContextTrait>:
38 EntityBase<S> + Get<S> + List<S> + Create<S> + Update<S> + Delete<S>
39{
40}
41
42pub trait Get<S: ContextTrait>: EntityBase<S> {
43 type RequestExt: FromRequestParts<S> + Send + Sync + Clone;
44 type Error: Into<AppError> + Serialize + Send;
45
46 fn get(
47 id: &<Self as EntityBase<S>>::Id,
48 ext: Self::RequestExt,
49 ) -> impl Future<Output = Result<Option<Self>, Self::Error>> + Send;
50}
51
52pub trait List<S: ContextTrait>: EntityBase<S> {
53 type RequestExt: FromRequestParts<S> + Send + Sync + Clone;
54 type Error: Into<AppError> + Serialize + Send;
55
56 fn list(
58 ext: Self::RequestExt,
59 ) -> impl Future<Output = Result<impl IntoIterator<Item = Self>, Self::Error>> + Send;
60}
61
62pub trait Create<S: ContextTrait>: EntityBase<S> {
63 type RequestExt: FromRequestParts<S> + Send + Sync + Clone;
64 type Error: Into<AppError> + Serialize + Send;
65
66 fn create(
67 data: <Self as EntityBase<S>>::Create,
68 ext: Self::RequestExt,
69 ) -> impl Future<Output = Result<Self, Self::Error>> + Send;
70}
71
72pub trait Update<S: ContextTrait>: EntityBase<S> {
73 type RequestExt: FromRequestParts<S> + Send + Sync + Clone;
74 type Error: Into<AppError> + Serialize + Send;
75
76 fn update(
77 id: &<Self as EntityBase<S>>::Id,
78 data: <Self as EntityBase<S>>::Update,
79 ext: Self::RequestExt,
80 ) -> impl Future<Output = Result<Self, Self::Error>> + Send;
81}
82
83pub trait Delete<S: ContextTrait>: EntityBase<S> {
84 type RequestExt: FromRequestParts<S> + Send + Sync + Clone;
85 type Error: Into<AppError> + Serialize + Send + Sync + Unpin + 'static;
86
87 fn delete(
88 id: &<Self as EntityBase<S>>::Id,
89 ext: Self::RequestExt,
90 ) -> impl Future<Output = Result<(), Self::Error>> + Send;
91}