use crate::depot::prelude::*; use async_trait::async_trait; use log::debug; use serde_json::{json, Value}; /// This is a showcase implementation with a static repository /// It uses a Vec to store it's data. struct MyStaticRepository { /// In Memory Storage for Example. content: Vec, /// ID Counter for content. next_id: usize, } impl MyStaticRepository { pub fn new() -> Self { MyStaticRepository { next_id: 12, content: vec![ json!({"id": 1, "name": "Strange", "age": 150, "level": "master" }), json!({"id": 2, "name": "Adam", "age": 12, "powers": 8}), json!({"id": 3, "name": "Tony", "age": 42, "powers": 0}), json!({"id": 4, "name": "Rex", "age": 72}), json!({"id": 5, "name": "Justin", "age": 46}), json!({"id": 6, "name": "Reacher", "age": 39, "level": "adept", "powers": 0}), json!({"id": 7, "name": "Arnold", "age": 7}), json!({"id": 8, "name": "Eight", "age": 8}), json!({"id": 9, "name": "Nine", "age": 9}), json!({"id": 10, "name": "Ten", "age": 10}), json!({"id": 11, "name": "Eleven", "age": 11}), ], } } } #[async_trait] impl DepotRepository 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", lookup_key: "id", display_list: &["id", "name", "level", "age"], fields: &["name", "level", "age", "powers"], } .build() //.set_widget("age", Widget::default().as_password().labeled("hi there.")) //.set_widget("name", Widget::textarea().options(&[("disabled", "true")])) } async fn get(&self, model: &RepositoryContext, id: &Self::Key) -> RepositoryResult { let id = *id as usize; let item = self.content.get(id - 1).cloned().unwrap(); let id = item.get("id").unwrap(); Ok(RepositoryResponse::ItemOnly( model.build_item(&*id.to_string(), item), )) } async fn list(&self, model: &RepositoryContext) -> RepositoryList { RepositoryList::List { values: self .content .clone() .into_iter() .filter_map(|item| match item.get("id") { Some(id_value) => { let id_str = id_value.to_string(); Some(model.build_item(&id_str, item)) } None => { eprintln!("Skipping item due to missing 'id'"); None } }) .collect(), } } async fn create(&mut self, model: &RepositoryContext, mut data: Value) -> RepositoryResult { debug!("Asked to create: {}", data); let new_id = self.next_id; self.next_id += 1; data["id"] = Value::Number(new_id.into()); debug!("I create: {}", data); // Push the data into the repository self.content.push(data.clone()); // Return the newly created item Ok(RepositoryResponse::ItemOnly( model.build_item(&*new_id.to_string(), data), )) } async fn update( &mut self, model: &RepositoryContext, id: &Self::Key, data: Value, ) -> RepositoryResult { debug!("I would now update: {}, {}", id, data); // First, find the index of the item to update let item_index = self.content.iter().position(|item| { if let Some(item_id) = item.get("id") { item_id == id } else { false } }); // Then, update the item if found if let Some(index) = item_index { let item = &mut self.content[index]; *item = data.clone(); item["id"] = (*id).into(); if let Some(item_id) = item.get("id") { return Ok(RepositoryResponse::ItemOnly( model.build_item(&*item_id.to_string(), data), )); } } Ok(RepositoryResponse::NoItem) } async fn replace( &mut self, model: &RepositoryContext, id: &Self::Key, data: Value, ) -> RepositoryResult { self.update(model, id, data).await } async fn delete(&mut self, _: &RepositoryContext, id: &Self::Key) -> Option { debug!("Would delete: {}", id); let item_index = self.content.iter().position(|item| { if let Some(item_id) = item.get("id") { item_id == id } else { false } }); if let Some(index) = item_index { // Remove and return the item Some(self.content.remove(index)) } else { None } } } pub fn register(registry: &mut DepotRegistry) { let section_key = registry.register_section("Example App"); let repo = MyStaticRepository::new(); let model_config = DepotModelConfig { section_key: section_key, name: "ExampleModel".to_owned(), }; let model_result = registry.register_model(model_config, repo); match model_result { Err(err) => panic!("{}", err), _ => (), } }