diff --git a/Cargo.lock b/Cargo.lock index 079d20e..6130519 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -792,6 +792,41 @@ dependencies = [ "typenum", ] +[[package]] +name = "darling" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 1.0.109", +] + +[[package]] +name = "darling_macro" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +dependencies = [ + "darling_core", + "quote", + "syn 1.0.109", +] + [[package]] name = "der" version = "0.7.8" @@ -824,6 +859,37 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "derive_builder" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "660047478bc508c0fde22c868991eec0c40a63e48d610befef466d48e2bee574" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b217e6dd1011a54d12f3b920a411b5abd44b1716ecfe94f5f2f2f7b52e08ab7" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_builder_macro" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5f77d7e20ac9153428f7ca14a88aba652adfc7a0ef0a06d654386310ef663b" +dependencies = [ + "derive_builder_core", + "syn 1.0.109", +] + [[package]] name = "deunicode" version = "1.4.2" @@ -1472,6 +1538,12 @@ dependencies = [ "cc", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "0.4.0" @@ -1755,6 +1827,7 @@ dependencies = [ "anyhow", "axum 0.7.4", "barrel", + "derive_builder", "dotenvy", "dunce", "entity", diff --git a/Cargo.toml b/Cargo.toml index 523a659..665ed2f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,3 +50,4 @@ log = "0.4.20" env_logger = "0.11" serde_json = "1.0.108" slug = "0.1.5" +derive_builder = "0.13.0" diff --git a/src/admin/domain.rs b/src/admin/domain.rs index f908211..4236adb 100644 --- a/src/admin/domain.rs +++ b/src/admin/domain.rs @@ -1,7 +1,9 @@ pub use config::AdminModelConfig; pub use dto::AdminApp; pub use dto::AdminModel; -pub use repository::{AdminRepository, RepositoryInfo, RepositoryList}; +pub use repository::{ + AdminRepository, RepoInfo, RepositoryInfo, RepositoryInfoBuilder, RepositoryList, +}; mod auth { @@ -47,6 +49,7 @@ mod dto { } pub mod repository { + use derive_builder::Builder; use serde::{Serialize, Serializer}; use serde_json::Value; use std::vec::IntoIter; @@ -95,8 +98,18 @@ pub mod repository { } } + /// Static initializer for RepositoryInfo. + pub struct RepoInfo { + pub name: &'static str, + pub lookup_key: &'static str, + pub display_list: &'static [&'static str], + } + + // consider builder: https://docs.rs/derive_builder/latest/derive_builder/ + // downside of builders as macro: no intellisense! // each repository has to implement a repo info. - #[derive(Serialize)] + #[derive(Serialize, Builder)] + #[builder(setter(into))] pub struct RepositoryInfo { name: String, lookup_key: String, @@ -112,16 +125,34 @@ pub mod repository { } } + /* // self mutating builder pattern? pub fn display_list(mut self, display_list: &[&str]) -> RepositoryInfo { self.display_list = display_list.iter().map(|&e| e.to_string()).collect(); self } + */ + } + + impl From for RepositoryInfo { + fn from(repo_info: RepoInfo) -> Self { + RepositoryInfo { + name: repo_info.name.to_string(), + lookup_key: repo_info.lookup_key.to_string(), + display_list: repo_info + .display_list + .iter() + .map(|&s| s.to_string()) + .collect(), + } + } } pub trait AdminRepository: Send + Sync { - fn get_item(&self, id: usize) -> Option; - - fn get_repo_info(&self) -> RepositoryInfo; - fn get_list(&self) -> RepositoryList; + fn info(&self) -> RepositoryInfo; + fn list(&self) -> RepositoryList; + fn get(&self, id: usize) -> Option; + fn create(&self, data: Value) -> Option; + fn update(&self, id: usize, data: Value) -> Option; + fn delete(&self, id: usize) -> Option; } } diff --git a/src/admin/example.rs b/src/admin/example.rs index 8f8236a..c8d5583 100644 --- a/src/admin/example.rs +++ b/src/admin/example.rs @@ -1,6 +1,6 @@ // implementation of static repository -use super::domain::{AdminModelConfig, AdminRepository, RepositoryInfo, RepositoryList}; +use super::domain::{AdminModelConfig, AdminRepository, RepoInfo, RepositoryInfo, RepositoryList}; use super::state::AdminRegistry; use serde_json::{json, Value}; @@ -25,19 +25,38 @@ impl MyStaticRepository { } impl AdminRepository for MyStaticRepository { - fn get_item(&self, id: usize) -> Option { + fn get(&self, id: usize) -> Option { self.content.get(id).cloned() } - fn get_list(&self) -> RepositoryList { + fn list(&self) -> RepositoryList { RepositoryList::List { values: self.content.clone(), } } - fn get_repo_info(&self) -> RepositoryInfo { - RepositoryInfo::new("My Static Repository", "id") - .display_list(&["id", "name", "age", "level"]) + fn info(&self) -> RepositoryInfo { + RepoInfo { + name: "My Static Repository", + lookup_key: "id", + display_list: &["id", "name", "level", "age"], + } + .into() + } + + fn create(&self, data: Value) -> Option { + println!("I would now create: {}", data); + None + } + + fn update(&self, id: usize, data: Value) -> Option { + println!("I would now update: {}, {}", id, data); + None + } + + fn delete(&self, id: usize) -> Option { + println!("Would delete: {}", id); + None } } diff --git a/src/admin/views.rs b/src/admin/views.rs index 6dd448c..b3d97d5 100644 --- a/src/admin/views.rs +++ b/src/admin/views.rs @@ -109,8 +109,8 @@ pub async fn list_item_collection( AdminContext { available_apps: registry.get_apps(), content: model_key.to_owned(), - item_info: Some(repo.get_repo_info()), - item_list: repo.get_list(), + item_info: Some(repo.info()), + item_list: repo.list(), ..Default::default() } } else {