From 1eea8b58c1f2a6c10204ddcaa3e2a734843e22f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabor=20K=C3=B6rber?= Date: Sat, 1 Jun 2024 17:37:50 +0200 Subject: [PATCH] feat: moving associated type working into the repository --- rear/src/admin/domain.rs | 64 ++++++------------- rear/src/admin/views.rs | 82 +++++++++++++++---------- src/admin_examples/empty_repository.rs | 8 +++ src/admin_examples/static_repository.rs | 8 +++ src/admin_examples/user_repository.rs | 8 +++ 5 files changed, 92 insertions(+), 78 deletions(-) diff --git a/rear/src/admin/domain.rs b/rear/src/admin/domain.rs index aa2e139..f29d2f3 100644 --- a/rear/src/admin/domain.rs +++ b/rear/src/admin/domain.rs @@ -2,7 +2,7 @@ pub use config::AdminModelConfig; pub use dto::AdminApp; pub use dto::AdminModel; pub use repository::{ - AdminRepository, DynAdminRepository, LookupKey, RepoInfo, RepositoryContext, RepositoryInfo, + AdminRepository, DynAdminRepository, RepoInfo, RepositoryContext, RepositoryInfo, RepositoryItem, RepositoryList, Widget, }; @@ -54,6 +54,8 @@ pub mod repository { use async_trait::async_trait; use serde::{Serialize, Serializer}; use serde_json::Value; + use std::any::Any; + use std::fmt::Debug; use std::vec::IntoIter; pub type RepositoryContext = AdminModel; @@ -179,48 +181,6 @@ pub mod repository { } } - #[derive(PartialEq)] - pub enum LookupKey { - Integer(usize), - String(String), - } - - // Note that LookupKey auto converts to integer. - impl From for LookupKey { - fn from(s: String) -> Self { - if let Ok(int_key) = s.parse::() { - LookupKey::Integer(int_key) - } else { - LookupKey::String(s) - } - } - } - - impl From<&str> for LookupKey { - fn from(s: &str) -> Self { - if let Ok(int_key) = s.parse::() { - LookupKey::Integer(int_key) - } else { - LookupKey::String(s.to_owned()) - } - } - } - - impl From for LookupKey { - fn from(i: usize) -> Self { - LookupKey::Integer(i) - } - } - - impl std::fmt::Display for LookupKey { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - LookupKey::Integer(i) => write!(f, "{}", i), - LookupKey::String(s) => write!(f, "{}", s), - } - } - } - #[derive(Serialize)] pub struct RepositoryItem { pub fields: Value, @@ -350,9 +310,6 @@ pub mod repository { } } - use std::any::Any; - use std::fmt::Debug; - pub trait PrimaryKeyType: Any + Debug + Send + Sync { fn as_any(&self) -> &dyn Any; } @@ -383,6 +340,8 @@ pub mod repository { pub trait AdminRepository: Send + Sync { type Key: PrimaryKeyType; + fn key_from_string(&self, s: String) -> Option; + async fn info(&self, context: &RepositoryContext) -> RepositoryInfo; async fn list(&self, context: &RepositoryContext) -> RepositoryList; async fn get(&self, context: &RepositoryContext, id: &Self::Key) -> Option; @@ -408,6 +367,7 @@ pub mod repository { #[async_trait] pub trait DynAdminRepository: Send + Sync { + fn key_from_string(&self, s: String) -> Option>; async fn info(&self, context: &RepositoryContext) -> RepositoryInfo; async fn list(&self, context: &RepositoryContext) -> RepositoryList; async fn get( @@ -447,10 +407,22 @@ pub mod repository { pub fn new(inner: T) -> Self { Self { inner } } + + fn key_from_string(&self, s: String) -> Option<::Key> { + self.inner.key_from_string(s) + } } #[async_trait] impl DynAdminRepository for AdminRepositoryWrapper { + fn key_from_string(&self, s: String) -> Option> { + if let Some(key) = self.inner.key_from_string(s) { + Some(Box::new(key)) + } else { + None + } + } + async fn info(&self, context: &RepositoryContext) -> RepositoryInfo { self.inner.info(context).await } diff --git a/rear/src/admin/views.rs b/rear/src/admin/views.rs index 23a3047..2c05593 100644 --- a/rear/src/admin/views.rs +++ b/rear/src/admin/views.rs @@ -9,8 +9,7 @@ use crate::admin::domain::{AdminApp, AdminModel}; use crate::admin::state::AdminState; use serde::{Deserialize, Serialize}; -use super::domain::repository::PrimaryKeyType; -use super::domain::{LookupKey, RepositoryInfo, RepositoryItem, RepositoryList}; +use super::domain::{RepositoryInfo, RepositoryItem, RepositoryList}; #[derive(Serialize, Deserialize)] pub struct AdminRequest { @@ -158,15 +157,22 @@ pub async fn view_item_details( let admin_model = registry .get_model(&app_key, &model_key) .expect("Admin Model not found?"); - let key: Box = Box::new(id); - AdminContext { - base: base_template(&headers), - available_apps: registry.get_apps(), - item_info: Some(repo.info(&admin_model).await), - item_list: repo.list(&admin_model).await, - item: repo.get(&admin_model, key.as_ref()).await, - item_model: Some(admin_model), - ..Default::default() + if let Some(key) = repo.key_from_string(id) { + AdminContext { + base: base_template(&headers), + available_apps: registry.get_apps(), + item_info: Some(repo.info(&admin_model).await), + item_list: repo.list(&admin_model).await, + item: repo.get(&admin_model, key.as_ref()).await, + item_model: Some(admin_model), + ..Default::default() + } + } else { + AdminContext { + base: base_template(&headers), + available_apps: registry.get_apps(), + ..Default::default() + } } } else { AdminContext { @@ -258,15 +264,22 @@ pub async fn change_item( let admin_model = registry .get_model(&app_key, &model_key) .expect("Admin Model not found?"); - let key: Box = Box::new(id); - AdminContext { - base: base_template(&headers), - available_apps: registry.get_apps(), - item_info: Some(repo.info(&admin_model).await), - item_list: repo.list(&admin_model).await, - item: repo.get(&admin_model, key.as_ref()).await, - item_model: Some(admin_model), - ..Default::default() + if let Some(key) = repo.key_from_string(id) { + AdminContext { + base: base_template(&headers), + available_apps: registry.get_apps(), + item_info: Some(repo.info(&admin_model).await), + item_list: repo.list(&admin_model).await, + item: repo.get(&admin_model, key.as_ref()).await, + item_model: Some(admin_model), + ..Default::default() + } + } else { + AdminContext { + base: base_template(&headers), + available_apps: registry.get_apps(), + ..Default::default() + } } } else { AdminContext { @@ -291,18 +304,23 @@ pub async fn update_item( let admin_model = registry .get_model(&app_key, &model_key) .expect("Admin Model not found?"); - let key: Box = Box::new(id); - - let result = repo.update(&admin_model, key.as_ref(), form).await; - - AdminContext { - base: base_template(&headers), - available_apps: registry.get_apps(), - item_info: Some(repo.info(&admin_model).await), - item_list: repo.list(&admin_model).await, - item: result, - item_model: Some(admin_model), - ..Default::default() + if let Some(key) = repo.key_from_string(id) { + let result = repo.update(&admin_model, key.as_ref(), form).await; + AdminContext { + base: base_template(&headers), + available_apps: registry.get_apps(), + item_info: Some(repo.info(&admin_model).await), + item_list: repo.list(&admin_model).await, + item: result, + item_model: Some(admin_model), + ..Default::default() + } + } else { + AdminContext { + base: base_template(&headers), + available_apps: registry.get_apps(), + ..Default::default() + } } } else { AdminContext { diff --git a/src/admin_examples/empty_repository.rs b/src/admin_examples/empty_repository.rs index 05d08d5..91e6eed 100644 --- a/src/admin_examples/empty_repository.rs +++ b/src/admin_examples/empty_repository.rs @@ -10,6 +10,14 @@ impl Repository {} impl AdminRepository for Repository { type Key = i64; + fn key_from_string(&self, s: String) -> Option { + if let Ok(i) = s.parse::() { + Some(i) + } else { + None + } + } + async fn info(&self, _: &RepositoryContext) -> RepositoryInfo { RepoInfo { name: "My Empty Repository", diff --git a/src/admin_examples/static_repository.rs b/src/admin_examples/static_repository.rs index 2e90b78..d62b32e 100644 --- a/src/admin_examples/static_repository.rs +++ b/src/admin_examples/static_repository.rs @@ -38,6 +38,14 @@ impl MyStaticRepository { impl AdminRepository for MyStaticRepository { type Key = i64; + fn key_from_string(&self, s: String) -> Option { + if let Ok(i) = s.parse::() { + Some(i) + } else { + None + } + } + async fn info(&self, _: &RepositoryContext) -> RepositoryInfo { RepoInfo { name: "My Static Repository", diff --git a/src/admin_examples/user_repository.rs b/src/admin_examples/user_repository.rs index f815cd8..19db3fd 100644 --- a/src/admin_examples/user_repository.rs +++ b/src/admin_examples/user_repository.rs @@ -21,6 +21,14 @@ impl UserRepository { impl AdminRepository for UserRepository { type Key = i64; + fn key_from_string(&self, s: String) -> Option { + if let Ok(i) = s.parse::() { + Some(i) + } else { + None + } + } + async fn info(&self, _: &RepositoryContext) -> RepositoryInfo { RepoInfo { name: "User",