Update macro to use #[index] attributes

- Also use proper types for index.
 - Update DB interface to be more flexible for index params

Signed-off-by: Lee Smet <lee.smet@hotmail.com>
This commit is contained in:
Lee Smet
2025-04-25 13:26:15 +02:00
parent dc93518a35
commit 96a1ecd974
10 changed files with 368 additions and 167 deletions

View File

@@ -1,3 +1,5 @@
use std::borrow::Borrow;
use crate::models::{Index, Model};
use serde::{Deserialize, Serialize};
@@ -22,9 +24,11 @@ where
type Error: std::fmt::Debug;
/// Get all items where the given index field is equal to key.
fn get<I>(&self, key: &I::Key) -> Result<Vec<V>, Error<Self::Error>>
fn get<I, Q>(&self, key: &Q) -> Result<Vec<V>, Error<Self::Error>>
where
I: Index<Model = V>;
I: Index<Model = V>,
I::Key: Borrow<Q>,
Q: ToString + ?Sized;
/// Get an object from its ID. This does not use an index lookup
fn get_by_id(&self, id: u32) -> Result<Option<V>, Error<Self::Error>>;
@@ -33,9 +37,11 @@ where
fn set(&self, value: &V) -> Result<(), Error<Self::Error>>;
/// Delete all items from the db with a given index.
fn delete<I>(&self, key: &I::Key) -> Result<(), Error<Self::Error>>
fn delete<I, Q>(&self, key: &Q) -> Result<(), Error<Self::Error>>
where
I: Index<Model = V>;
I: Index<Model = V>,
I::Key: Borrow<Q>,
Q: ToString + ?Sized;
/// Delete an object with a given ID
fn delete_by_id(&self, id: u32) -> Result<(), Error<Self::Error>>;

View File

@@ -4,6 +4,7 @@ use serde::Deserialize;
use crate::models::{Index, Model};
use std::{
borrow::Borrow,
collections::HashSet,
sync::{Arc, Mutex},
};
@@ -42,9 +43,11 @@ where
{
type Error = tst::Error;
fn get<I>(&self, key: &I::Key) -> Result<Vec<M>, super::Error<Self::Error>>
fn get<I, Q>(&self, key: &Q) -> Result<Vec<M>, super::Error<Self::Error>>
where
I: Index<Model = M>,
I::Key: Borrow<Q>,
Q: ToString + ?Sized,
{
let mut index_db = self.index.lock().expect("can lock index DB");
let index_key = Self::index_key(M::db_prefix(), I::key(), &key.to_string());
@@ -140,9 +143,11 @@ where
Ok(())
}
fn delete<I>(&self, key: &I::Key) -> Result<(), super::Error<Self::Error>>
fn delete<I, Q>(&self, key: &Q) -> Result<(), super::Error<Self::Error>>
where
I: Index<Model = M>,
I::Key: Borrow<Q>,
Q: ToString + ?Sized,
{
let mut index_db = self.index.lock().expect("can lock index db");
let key = Self::index_key(M::db_prefix(), I::key(), &key.to_string());

View File

@@ -1,22 +1,27 @@
use crate::models::core::model::{BaseModelData, Index, IndexKey, Model};
use crate::models::core::model::BaseModelData;
use heromodels_derive::model;
use serde::{Deserialize, Serialize};
/// Represents a user in the system
#[derive(Debug, Clone, Serialize, Deserialize)]
#[model]
pub struct User {
/// Base model data
pub base_data: BaseModelData,
/// User's username
#[index]
pub username: String,
/// User's email address
#[index]
pub email: String,
/// User's full name
pub full_name: String,
/// Whether the user is active
#[index(name = "ac")]
pub is_active: bool,
}
@@ -78,70 +83,70 @@ impl User {
}
// Implement the Model trait for User
impl Model for User {
fn db_prefix() -> &'static str {
"user"
}
fn get_id(&self) -> u32 {
self.base_data.id
}
//WHY?
fn base_data_mut(&mut self) -> &mut BaseModelData {
&mut self.base_data
}
fn db_keys(&self) -> Vec<IndexKey> {
vec![
IndexKey {
name: "username",
value: self.username.clone(),
},
IndexKey {
name: "email",
value: self.email.clone(),
},
IndexKey {
name: "is_active",
value: self.is_active.to_string(),
},
]
}
}
// Marker structs for indexed fields
pub struct UserName;
pub struct Email;
pub struct IsActive;
impl Index for UserName {
type Model = User;
type Key = str;
fn key() -> &'static str {
"username"
}
}
impl Index for Email {
type Model = User;
type Key = str;
fn key() -> &'static str {
"email"
}
}
impl Index for IsActive {
type Model = User;
type Key = bool;
fn key() -> &'static str {
"is_active"
}
}
// impl Model for User {
// fn db_prefix() -> &'static str {
// "user"
// }
//
// fn get_id(&self) -> u32 {
// self.base_data.id
// }
//
// //WHY?
// fn base_data_mut(&mut self) -> &mut BaseModelData {
// &mut self.base_data
// }
//
// fn db_keys(&self) -> Vec<IndexKey> {
// vec![
// IndexKey {
// name: "username",
// value: self.username.clone(),
// },
// IndexKey {
// name: "email",
// value: self.email.clone(),
// },
// IndexKey {
// name: "is_active",
// value: self.is_active.to_string(),
// },
// ]
// }
// }
//
// // Marker structs for indexed fields
//
// pub struct UserName;
// pub struct Email;
// pub struct IsActive;
//
// impl Index for UserName {
// type Model = User;
//
// type Key = str;
//
// fn key() -> &'static str {
// "username"
// }
// }
//
// impl Index for Email {
// type Model = User;
//
// type Key = str;
//
// fn key() -> &'static str {
// "email"
// }
// }
//
// impl Index for IsActive {
// type Model = User;
//
// type Key = bool;
//
// fn key() -> &'static str {
// "is_active"
// }
// }