feat: moving associated type working into the repository
This commit is contained in:
parent
d1abc6b6c2
commit
1eea8b58c1
@ -2,7 +2,7 @@ pub use config::AdminModelConfig;
|
|||||||
pub use dto::AdminApp;
|
pub use dto::AdminApp;
|
||||||
pub use dto::AdminModel;
|
pub use dto::AdminModel;
|
||||||
pub use repository::{
|
pub use repository::{
|
||||||
AdminRepository, DynAdminRepository, LookupKey, RepoInfo, RepositoryContext, RepositoryInfo,
|
AdminRepository, DynAdminRepository, RepoInfo, RepositoryContext, RepositoryInfo,
|
||||||
RepositoryItem, RepositoryList, Widget,
|
RepositoryItem, RepositoryList, Widget,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -54,6 +54,8 @@ pub mod repository {
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use serde::{Serialize, Serializer};
|
use serde::{Serialize, Serializer};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
use std::any::Any;
|
||||||
|
use std::fmt::Debug;
|
||||||
use std::vec::IntoIter;
|
use std::vec::IntoIter;
|
||||||
|
|
||||||
pub type RepositoryContext = AdminModel;
|
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<String> for LookupKey {
|
|
||||||
fn from(s: String) -> Self {
|
|
||||||
if let Ok(int_key) = s.parse::<usize>() {
|
|
||||||
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::<usize>() {
|
|
||||||
LookupKey::Integer(int_key)
|
|
||||||
} else {
|
|
||||||
LookupKey::String(s.to_owned())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<usize> 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)]
|
#[derive(Serialize)]
|
||||||
pub struct RepositoryItem {
|
pub struct RepositoryItem {
|
||||||
pub fields: Value,
|
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 {
|
pub trait PrimaryKeyType: Any + Debug + Send + Sync {
|
||||||
fn as_any(&self) -> &dyn Any;
|
fn as_any(&self) -> &dyn Any;
|
||||||
}
|
}
|
||||||
@ -383,6 +340,8 @@ pub mod repository {
|
|||||||
pub trait AdminRepository: Send + Sync {
|
pub trait AdminRepository: Send + Sync {
|
||||||
type Key: PrimaryKeyType;
|
type Key: PrimaryKeyType;
|
||||||
|
|
||||||
|
fn key_from_string(&self, s: String) -> Option<Self::Key>;
|
||||||
|
|
||||||
async fn info(&self, context: &RepositoryContext) -> RepositoryInfo;
|
async fn info(&self, context: &RepositoryContext) -> RepositoryInfo;
|
||||||
async fn list(&self, context: &RepositoryContext) -> RepositoryList;
|
async fn list(&self, context: &RepositoryContext) -> RepositoryList;
|
||||||
async fn get(&self, context: &RepositoryContext, id: &Self::Key) -> Option<RepositoryItem>;
|
async fn get(&self, context: &RepositoryContext, id: &Self::Key) -> Option<RepositoryItem>;
|
||||||
@ -408,6 +367,7 @@ pub mod repository {
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait DynAdminRepository: Send + Sync {
|
pub trait DynAdminRepository: Send + Sync {
|
||||||
|
fn key_from_string(&self, s: String) -> Option<Box<dyn PrimaryKeyType>>;
|
||||||
async fn info(&self, context: &RepositoryContext) -> RepositoryInfo;
|
async fn info(&self, context: &RepositoryContext) -> RepositoryInfo;
|
||||||
async fn list(&self, context: &RepositoryContext) -> RepositoryList;
|
async fn list(&self, context: &RepositoryContext) -> RepositoryList;
|
||||||
async fn get(
|
async fn get(
|
||||||
@ -447,10 +407,22 @@ pub mod repository {
|
|||||||
pub fn new(inner: T) -> Self {
|
pub fn new(inner: T) -> Self {
|
||||||
Self { inner }
|
Self { inner }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn key_from_string(&self, s: String) -> Option<<T as AdminRepository>::Key> {
|
||||||
|
self.inner.key_from_string(s)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<T: AdminRepository> DynAdminRepository for AdminRepositoryWrapper<T> {
|
impl<T: AdminRepository> DynAdminRepository for AdminRepositoryWrapper<T> {
|
||||||
|
fn key_from_string(&self, s: String) -> Option<Box<dyn PrimaryKeyType>> {
|
||||||
|
if let Some(key) = self.inner.key_from_string(s) {
|
||||||
|
Some(Box::new(key))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn info(&self, context: &RepositoryContext) -> RepositoryInfo {
|
async fn info(&self, context: &RepositoryContext) -> RepositoryInfo {
|
||||||
self.inner.info(context).await
|
self.inner.info(context).await
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,7 @@ use crate::admin::domain::{AdminApp, AdminModel};
|
|||||||
use crate::admin::state::AdminState;
|
use crate::admin::state::AdminState;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use super::domain::repository::PrimaryKeyType;
|
use super::domain::{RepositoryInfo, RepositoryItem, RepositoryList};
|
||||||
use super::domain::{LookupKey, RepositoryInfo, RepositoryItem, RepositoryList};
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct AdminRequest {
|
pub struct AdminRequest {
|
||||||
@ -158,15 +157,22 @@ pub async fn view_item_details<S: AdminState + Clone + Send + Sync + 'static>(
|
|||||||
let admin_model = registry
|
let admin_model = registry
|
||||||
.get_model(&app_key, &model_key)
|
.get_model(&app_key, &model_key)
|
||||||
.expect("Admin Model not found?");
|
.expect("Admin Model not found?");
|
||||||
let key: Box<dyn PrimaryKeyType> = Box::new(id);
|
if let Some(key) = repo.key_from_string(id) {
|
||||||
AdminContext {
|
AdminContext {
|
||||||
base: base_template(&headers),
|
base: base_template(&headers),
|
||||||
available_apps: registry.get_apps(),
|
available_apps: registry.get_apps(),
|
||||||
item_info: Some(repo.info(&admin_model).await),
|
item_info: Some(repo.info(&admin_model).await),
|
||||||
item_list: repo.list(&admin_model).await,
|
item_list: repo.list(&admin_model).await,
|
||||||
item: repo.get(&admin_model, key.as_ref()).await,
|
item: repo.get(&admin_model, key.as_ref()).await,
|
||||||
item_model: Some(admin_model),
|
item_model: Some(admin_model),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
AdminContext {
|
||||||
|
base: base_template(&headers),
|
||||||
|
available_apps: registry.get_apps(),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
AdminContext {
|
AdminContext {
|
||||||
@ -258,15 +264,22 @@ pub async fn change_item<S: AdminState + Clone + Send + Sync + 'static>(
|
|||||||
let admin_model = registry
|
let admin_model = registry
|
||||||
.get_model(&app_key, &model_key)
|
.get_model(&app_key, &model_key)
|
||||||
.expect("Admin Model not found?");
|
.expect("Admin Model not found?");
|
||||||
let key: Box<dyn PrimaryKeyType> = Box::new(id);
|
if let Some(key) = repo.key_from_string(id) {
|
||||||
AdminContext {
|
AdminContext {
|
||||||
base: base_template(&headers),
|
base: base_template(&headers),
|
||||||
available_apps: registry.get_apps(),
|
available_apps: registry.get_apps(),
|
||||||
item_info: Some(repo.info(&admin_model).await),
|
item_info: Some(repo.info(&admin_model).await),
|
||||||
item_list: repo.list(&admin_model).await,
|
item_list: repo.list(&admin_model).await,
|
||||||
item: repo.get(&admin_model, key.as_ref()).await,
|
item: repo.get(&admin_model, key.as_ref()).await,
|
||||||
item_model: Some(admin_model),
|
item_model: Some(admin_model),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
AdminContext {
|
||||||
|
base: base_template(&headers),
|
||||||
|
available_apps: registry.get_apps(),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
AdminContext {
|
AdminContext {
|
||||||
@ -291,18 +304,23 @@ pub async fn update_item<S: AdminState + Clone + Send + Sync + 'static>(
|
|||||||
let admin_model = registry
|
let admin_model = registry
|
||||||
.get_model(&app_key, &model_key)
|
.get_model(&app_key, &model_key)
|
||||||
.expect("Admin Model not found?");
|
.expect("Admin Model not found?");
|
||||||
let key: Box<dyn PrimaryKeyType> = Box::new(id);
|
if let Some(key) = repo.key_from_string(id) {
|
||||||
|
let result = repo.update(&admin_model, key.as_ref(), form).await;
|
||||||
let result = repo.update(&admin_model, key.as_ref(), form).await;
|
AdminContext {
|
||||||
|
base: base_template(&headers),
|
||||||
AdminContext {
|
available_apps: registry.get_apps(),
|
||||||
base: base_template(&headers),
|
item_info: Some(repo.info(&admin_model).await),
|
||||||
available_apps: registry.get_apps(),
|
item_list: repo.list(&admin_model).await,
|
||||||
item_info: Some(repo.info(&admin_model).await),
|
item: result,
|
||||||
item_list: repo.list(&admin_model).await,
|
item_model: Some(admin_model),
|
||||||
item: result,
|
..Default::default()
|
||||||
item_model: Some(admin_model),
|
}
|
||||||
..Default::default()
|
} else {
|
||||||
|
AdminContext {
|
||||||
|
base: base_template(&headers),
|
||||||
|
available_apps: registry.get_apps(),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
AdminContext {
|
AdminContext {
|
||||||
|
@ -10,6 +10,14 @@ impl Repository {}
|
|||||||
impl AdminRepository for Repository {
|
impl AdminRepository for Repository {
|
||||||
type Key = i64;
|
type Key = i64;
|
||||||
|
|
||||||
|
fn key_from_string(&self, s: String) -> Option<Self::Key> {
|
||||||
|
if let Ok(i) = s.parse::<i64>() {
|
||||||
|
Some(i)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn info(&self, _: &RepositoryContext) -> RepositoryInfo {
|
async fn info(&self, _: &RepositoryContext) -> RepositoryInfo {
|
||||||
RepoInfo {
|
RepoInfo {
|
||||||
name: "My Empty Repository",
|
name: "My Empty Repository",
|
||||||
|
@ -38,6 +38,14 @@ impl MyStaticRepository {
|
|||||||
impl AdminRepository for MyStaticRepository {
|
impl AdminRepository for MyStaticRepository {
|
||||||
type Key = i64;
|
type Key = i64;
|
||||||
|
|
||||||
|
fn key_from_string(&self, s: String) -> Option<Self::Key> {
|
||||||
|
if let Ok(i) = s.parse::<i64>() {
|
||||||
|
Some(i)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn info(&self, _: &RepositoryContext) -> RepositoryInfo {
|
async fn info(&self, _: &RepositoryContext) -> RepositoryInfo {
|
||||||
RepoInfo {
|
RepoInfo {
|
||||||
name: "My Static Repository",
|
name: "My Static Repository",
|
||||||
|
@ -21,6 +21,14 @@ impl UserRepository {
|
|||||||
impl AdminRepository for UserRepository {
|
impl AdminRepository for UserRepository {
|
||||||
type Key = i64;
|
type Key = i64;
|
||||||
|
|
||||||
|
fn key_from_string(&self, s: String) -> Option<Self::Key> {
|
||||||
|
if let Ok(i) = s.parse::<i64>() {
|
||||||
|
Some(i)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn info(&self, _: &RepositoryContext) -> RepositoryInfo {
|
async fn info(&self, _: &RepositoryContext) -> RepositoryInfo {
|
||||||
RepoInfo {
|
RepoInfo {
|
||||||
name: "User",
|
name: "User",
|
||||||
|
Loading…
Reference in New Issue
Block a user