diff --git a/01.workspace/heave/src/str/catalog.rs b/01.workspace/heave/src/str/catalog.rs index 1f8e3c3..3e278e9 100644 --- a/01.workspace/heave/src/str/catalog.rs +++ b/01.workspace/heave/src/str/catalog.rs @@ -64,17 +64,16 @@ impl O { /// An `Option` containing the converted entity if found, otherwise `None`. pub fn get(&self, id: &str) -> Option where - T: From, + T: EAV, { let entity = self.items.get(id); entity.map(|e| T::from(e.clone())) } - /// Retrieves the first entity that matches a given class, attribute, and value. + /// Retrieves the first entity that matches a given attribute and value. /// /// # Arguments /// - /// * `class` - The class of the entity to search for. /// * `attribute` - The attribute of the entity to match. /// * `value` - The value of the attribute to match. /// @@ -83,17 +82,16 @@ impl O { /// An `Option` containing the converted entity if found, otherwise `None`. pub fn get_by_class_and_attribute( &self, - class: &str, attribute: &str, value: impl Into + Clone, ) -> Option where - T: From, + T: EAV, { let mut items = self .items .values() - .filter(|item| item.class == class) + .filter(|item| item.class == T::class()) .filter(|item| item.value_of(attribute) == Some(&value.clone().into())) .take(1) .map(|item| T::from(item.clone())); @@ -102,28 +100,23 @@ impl O { /// Returns an iterator over entities of a specific class. /// - /// # Arguments - /// - /// * `class` - The class of the entities to list. - /// /// # Returns /// /// An iterator that yields items of type `T`. - pub fn list_by_class(&self, class: &str) -> impl Iterator + pub fn list_by_class(&self) -> impl Iterator where - T: From, + T: EAV, { self.items .values() - .filter(move |item| item.class == class) + .filter(move |item| item.class == T::class()) .map(|item| T::from(item.clone())) } - /// Returns an iterator over entities that match a given class, attribute, and value. + /// Returns an iterator over entities that match a given attribute and value. /// /// # Arguments /// - /// * `class` - The class of the entities to search for. /// * `attribute` - The attribute of the entities to match. /// * `value` - The value of the attribute to match. /// @@ -132,17 +125,16 @@ impl O { /// An iterator that yields items of type `T`. pub fn list_by_class_and_attribute( &self, - class: &str, attribute: &str, value: impl Into + Clone, ) -> impl Iterator where - T: From, + T: EAV, { let value: Value = value.into(); self.items .values() - .filter(move |item| item.class == class) + .filter(move |item| item.class == T::class()) .filter(move |item| item.value_of(attribute) == Some(&value)) .map(|item| T::from(item.clone())) } @@ -170,11 +162,11 @@ impl O { } /// Loads all entities of a specific class from the database into the catalog. - /// - /// # Arguments - /// - /// * `class` - The class of the entities to load. - pub fn load_by_class(&mut self, class: &str) { + pub fn load_by_class(&mut self) + where + T: EAV, + { + let class = T::class(); let path = path::Path::new(&self.path); let entities = sqlite::load::by_class(path, class); for entity in entities { diff --git a/01.workspace/heave/src/str/entity.rs b/01.workspace/heave/src/str/entity.rs index f617ec8..1cb278e 100644 --- a/01.workspace/heave/src/str/entity.rs +++ b/01.workspace/heave/src/str/entity.rs @@ -9,7 +9,11 @@ pub struct O { pub attributes: std::collections::HashMap, } -impl EAV for Entity {} +impl EAV for Entity { + fn class() -> &'static str { + "entity" + } +} impl O { pub fn new(class: &str) -> Self { diff --git a/01.workspace/heave/src/trt/eav.rs b/01.workspace/heave/src/trt/eav.rs index 40428c0..05a0267 100644 --- a/01.workspace/heave/src/trt/eav.rs +++ b/01.workspace/heave/src/trt/eav.rs @@ -5,6 +5,7 @@ pub trait T where Self: From, Self: Into, { + fn class() -> &'static str; } // #[cfg(test)] diff --git a/01.workspace/heave/src/tst/intended_use.rs b/01.workspace/heave/src/tst/intended_use.rs index 34b78cd..a1aecd4 100644 --- a/01.workspace/heave/src/tst/intended_use.rs +++ b/01.workspace/heave/src/tst/intended_use.rs @@ -7,7 +7,11 @@ mod tests { pub name: String, pub price: u64, } - impl EAV for Product {} + impl EAV for Product { + fn class() -> &'static str { + "product" + } + } impl From for Entity { fn from(value: Product) -> Entity { Entity::default() @@ -208,7 +212,7 @@ mod tests { catalog.persist(); // new empty catalog let mut catalog = Catalog::new(path.to_str().unwrap()); - catalog.load_by_class("product"); + catalog.load_by_class::(); assert_eq!(catalog.items.len(), 2); let loaded_value_01: Product = catalog.get(&expected_value_01.id).unwrap(); assert_eq!(loaded_value_01, expected_value_01); diff --git a/01.workspace/heave/src/tst/rusty_budger_use.rs b/01.workspace/heave/src/tst/rusty_budger_use.rs index ec6a97a..885c4f8 100644 --- a/01.workspace/heave/src/tst/rusty_budger_use.rs +++ b/01.workspace/heave/src/tst/rusty_budger_use.rs @@ -11,7 +11,11 @@ mod tests { pub operation_id: String, pub category_id: String, } - impl EAV for OperationToCategory {} + impl EAV for OperationToCategory { + fn class() -> &'static str { + "operation_to_category" + } + } impl From for Entity { fn from(value: OperationToCategory) -> Entity { Entity::default() @@ -37,7 +41,11 @@ mod tests { pub id: String, pub label: String, } - impl EAV for Category {} + impl EAV for Category { + fn class() -> &'static str { + "category" + } + } impl From for Entity { fn from(value: Category) -> Entity { Entity::default() @@ -63,7 +71,11 @@ mod tests { pub amount: i64, pub description: String, } - impl EAV for Operation {} + impl EAV for Operation { + fn class() -> &'static str { + "operation" + } + } impl From for Entity { fn from(value: Operation) -> Entity { Entity::default()