From fb72a5deab7a948bdce9e0feab8a69142997f113 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabor=20K=C3=B6rber?= Date: Tue, 2 Jan 2024 15:19:39 +0100 Subject: [PATCH] code: added register function. need to refactor naming conventions --- Cargo.lock | 17 +++++++++ Cargo.toml | 1 + src/admin/state.rs | 89 +++++++++++++++++++++++++++++++++++----------- 3 files changed, 87 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 95ac3e8..6ede3c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -772,6 +772,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "deunicode" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ae2a35373c5c74340b79ae6780b498b2b183915ec5dacf263aac5a099bf485a" + [[package]] name = "digest" version = "0.10.7" @@ -1622,6 +1628,7 @@ dependencies = [ "sea-orm", "serde", "serde_json", + "slug", "sqlformat", "tokio", ] @@ -2700,6 +2707,16 @@ dependencies = [ "autocfg", ] +[[package]] +name = "slug" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bd94acec9c8da640005f8e135a39fc0372e74535e6b368b7a04b875f784c8c4" +dependencies = [ + "deunicode", + "wasm-bindgen", +] + [[package]] name = "smallvec" version = "1.11.0" diff --git a/Cargo.toml b/Cargo.toml index 425beec..3c82a50 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,3 +47,4 @@ dunce = "1.0.4" log = "0.4.20" env_logger = "0.10.1" serde_json = "1.0.108" +slug = "0.1.5" diff --git a/src/admin/state.rs b/src/admin/state.rs index 2a65d8c..4987ac2 100644 --- a/src/admin/state.rs +++ b/src/admin/state.rs @@ -1,12 +1,7 @@ use crate::admin::domain::{AdminApp, AdminModel}; -use axum::routing::MethodRouter; -use axum::{async_trait, response::IntoResponse}; -use axum::{routing::get, Router}; -use core::future::Future; -use std::collections::HashMap; - -use serde::Serialize; +use axum::Router; use serde_json::Value; +use std::collections::HashMap; use std::sync::Arc; pub type AdminState = Arc; @@ -19,8 +14,8 @@ pub trait AdminRepository: Send + Sync { // main registry. pub struct AdminRegistry { base_path: String, - apps: HashMap, - models: HashMap, + apps: HashMap, + models: HashMap, repositories: HashMap>, } @@ -53,7 +48,7 @@ impl AdminRegistry { .collect() } - fn get_app(&self, name: &str, node: &internal::DataNode) -> AdminApp { + fn get_app(&self, name: &str, node: &internal::AdminApp) -> AdminApp { let label = node.label.as_ref().unwrap_or(&String::new()).clone(); AdminApp { name: name.to_owned(), @@ -66,36 +61,90 @@ impl AdminRegistry { pub fn register_app(&mut self, name: &str, app_label: &str, app_url: &str) { self.apps.insert( name.to_owned(), - internal::DataNode { + internal::AdminApp { object_name: name.to_owned(), label: Some(app_label.to_owned()), }, ); } - pub fn get_models(&self) -> Vec { + pub fn get_models(&self, app_name: &str) -> Vec { vec![] } - pub fn get_models_for_app(&self, name: &str) -> Vec { - vec![] + pub fn get_model(&self, app_name: &str, model_name: &str) -> Option { + let full_model_name = format!("{}.{}", app_name, model_name); + let internal_model = self.models.get(&full_model_name)?; + + // unfinished: we need to think about model_name vs. model_id vs. entry_id, as "name" is ambiguous. + Some(AdminModel { + object_name: internal_model.model_name.clone(), + name: internal_model.model_name.clone(), + admin_url: "".to_owned(), + view_only: false, + add_url: None, + }) } - pub fn register_model(&mut self, name: &str, config: AdminModelConfig) {} + fn register_model_config(&mut self, model: config::AdminModelConfig) -> Result { + let local_config = internal::AdminModel::from(model); + if local_config.model_name.is_empty() { + return Err("No model name".to_owned()); + } + let local_config_name = format!("{}.{}", local_config.app_name, local_config.model_name); + if self.models.contains_key(&local_config_name) { + return Err(format!("Model {} already exists", local_config_name)); + } + if let Some(local_config) = self.models.insert(local_config_name, local_config) { + return Ok(local_config.model_name); + } + Err("Model could not be added!".to_owned()) + } + + pub fn register_model( + &mut self, + model: config::AdminModelConfig, + repository: R, + ) -> Result<(), String> { + let model_name = self.register_model_config(model)?; + self.repositories.insert(model_name, Box::new(repository)); + Ok(()) + } } -// user uses this configuration object to register another model. -pub struct AdminModelConfig { - pub app: Arc, - pub custom_index_handler: Option, +pub mod config { + use axum::routing::MethodRouter; + + // user uses this configuration object to register another model. + pub struct AdminModelConfig { + pub name: String, + pub app_name: String, + + pub custom_index_handler: Option, + } } mod internal { #[derive(Clone)] - pub struct DataNode { + pub struct AdminApp { pub object_name: String, pub label: Option, } + + #[derive(Clone)] + pub struct AdminModel { + pub app_name: String, + pub model_name: String, + } + + impl From for AdminModel { + fn from(value: super::config::AdminModelConfig) -> Self { + AdminModel { + app_name: value.app_name, + model_name: value.name, + } + } + } } mod routing {