code: added register function. need to refactor naming conventions

This commit is contained in:
Gabor Körber 2024-01-02 15:19:39 +01:00
parent d09bfa6da0
commit fb72a5deab
3 changed files with 87 additions and 20 deletions

17
Cargo.lock generated
View File

@ -772,6 +772,12 @@ dependencies = [
"syn 1.0.109", "syn 1.0.109",
] ]
[[package]]
name = "deunicode"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ae2a35373c5c74340b79ae6780b498b2b183915ec5dacf263aac5a099bf485a"
[[package]] [[package]]
name = "digest" name = "digest"
version = "0.10.7" version = "0.10.7"
@ -1622,6 +1628,7 @@ dependencies = [
"sea-orm", "sea-orm",
"serde", "serde",
"serde_json", "serde_json",
"slug",
"sqlformat", "sqlformat",
"tokio", "tokio",
] ]
@ -2700,6 +2707,16 @@ dependencies = [
"autocfg", "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]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.11.0" version = "1.11.0"

View File

@ -47,3 +47,4 @@ dunce = "1.0.4"
log = "0.4.20" log = "0.4.20"
env_logger = "0.10.1" env_logger = "0.10.1"
serde_json = "1.0.108" serde_json = "1.0.108"
slug = "0.1.5"

View File

@ -1,12 +1,7 @@
use crate::admin::domain::{AdminApp, AdminModel}; use crate::admin::domain::{AdminApp, AdminModel};
use axum::routing::MethodRouter; use axum::Router;
use axum::{async_trait, response::IntoResponse};
use axum::{routing::get, Router};
use core::future::Future;
use std::collections::HashMap;
use serde::Serialize;
use serde_json::Value; use serde_json::Value;
use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
pub type AdminState = Arc<AdminRegistry>; pub type AdminState = Arc<AdminRegistry>;
@ -19,8 +14,8 @@ pub trait AdminRepository: Send + Sync {
// main registry. // main registry.
pub struct AdminRegistry { pub struct AdminRegistry {
base_path: String, base_path: String,
apps: HashMap<String, internal::DataNode>, apps: HashMap<String, internal::AdminApp>,
models: HashMap<String, internal::DataNode>, models: HashMap<String, internal::AdminModel>,
repositories: HashMap<String, Box<dyn AdminRepository>>, repositories: HashMap<String, Box<dyn AdminRepository>>,
} }
@ -53,7 +48,7 @@ impl AdminRegistry {
.collect() .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(); let label = node.label.as_ref().unwrap_or(&String::new()).clone();
AdminApp { AdminApp {
name: name.to_owned(), name: name.to_owned(),
@ -66,36 +61,90 @@ impl AdminRegistry {
pub fn register_app(&mut self, name: &str, app_label: &str, app_url: &str) { pub fn register_app(&mut self, name: &str, app_label: &str, app_url: &str) {
self.apps.insert( self.apps.insert(
name.to_owned(), name.to_owned(),
internal::DataNode { internal::AdminApp {
object_name: name.to_owned(), object_name: name.to_owned(),
label: Some(app_label.to_owned()), label: Some(app_label.to_owned()),
}, },
); );
} }
pub fn get_models(&self) -> Vec<AdminModel> { pub fn get_models(&self, app_name: &str) -> Vec<AdminModel> {
vec![] vec![]
} }
pub fn get_models_for_app(&self, name: &str) -> Vec<AdminModel> { pub fn get_model(&self, app_name: &str, model_name: &str) -> Option<AdminModel> {
vec![] 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<String, String> {
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<R: AdminRepository + 'static>(
&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(())
}
}
pub mod config {
use axum::routing::MethodRouter;
// user uses this configuration object to register another model. // user uses this configuration object to register another model.
pub struct AdminModelConfig { pub struct AdminModelConfig {
pub app: Arc<str>, pub name: String,
pub app_name: String,
pub custom_index_handler: Option<MethodRouter>, pub custom_index_handler: Option<MethodRouter>,
} }
}
mod internal { mod internal {
#[derive(Clone)] #[derive(Clone)]
pub struct DataNode { pub struct AdminApp {
pub object_name: String, pub object_name: String,
pub label: Option<String>, pub label: Option<String>,
} }
#[derive(Clone)]
pub struct AdminModel {
pub app_name: String,
pub model_name: String,
}
impl From<super::config::AdminModelConfig> for AdminModel {
fn from(value: super::config::AdminModelConfig) -> Self {
AdminModel {
app_name: value.app_name,
model_name: value.name,
}
}
}
} }
mod routing { mod routing {