From f7ab450e2c746856f5d459997458dec062572970 Mon Sep 17 00:00:00 2001 From: davidemazzocchi Date: Wed, 29 Oct 2025 14:26:26 +0100 Subject: [PATCH] review: make entity fields private; expose id and subclass --- 01.workspace/heave/examples/simple_product.rs | 2 +- 01.workspace/heave/examples/using_filters.rs | 2 +- .../heave/examples/working_with_many_types.rs | 8 ++-- 01.workspace/heave/src/str/entity.rs | 48 +++++++++++++------ 4 files changed, 39 insertions(+), 21 deletions(-) diff --git a/01.workspace/heave/examples/simple_product.rs b/01.workspace/heave/examples/simple_product.rs index 8334635..69c1a2b 100644 --- a/01.workspace/heave/examples/simple_product.rs +++ b/01.workspace/heave/examples/simple_product.rs @@ -44,7 +44,7 @@ impl From for Product { // Create a new `Product` from the entity's attributes. Self { // Set the product's ID from the entity's ID. - id: value.id.clone(), + id: value.id(), // Unwrap the "name" attribute to get the product's name. name: value.unwrap("name").expect("name is always present"), // Unwrap the optional "model" attribute to get the product's model. diff --git a/01.workspace/heave/examples/using_filters.rs b/01.workspace/heave/examples/using_filters.rs index d5ae6c9..2609586 100644 --- a/01.workspace/heave/examples/using_filters.rs +++ b/01.workspace/heave/examples/using_filters.rs @@ -35,7 +35,7 @@ impl From for Component { // `from` is a function that converts an `Entity` into a `Component`. fn from(value: Entity) -> Self { Self { - id: value.id.clone(), + id: value.id(), part_number: value .unwrap("part_number") .expect("part_number is always present"), diff --git a/01.workspace/heave/examples/working_with_many_types.rs b/01.workspace/heave/examples/working_with_many_types.rs index 6263f5b..c4cab2d 100644 --- a/01.workspace/heave/examples/working_with_many_types.rs +++ b/01.workspace/heave/examples/working_with_many_types.rs @@ -31,21 +31,21 @@ impl EAV for Product { } impl From for Product { fn from(value: Entity) -> Self { - if let Some(ref subclass) = value.subclass { + if let Some(ref subclass) = value.subclass() { match subclass.as_ref() { "laptop" => Product::Laptop(Laptop { - id: value.id.clone(), + id: value.id(), model: value.unwrap("model").expect("model is mandatory"), price: value.unwrap("price").expect("price is mandatory"), }), "display" => Product::Display(Display { - id: value.id.clone(), + id: value.id(), model: value.unwrap("model").expect("model is mandatory"), price: value.unwrap("price").expect("price is mandatory"), resolution: value.unwrap("resolution").expect("resolution is mandatory"), }), "mouse" => Product::Mouse(Mouse { - id: value.id.clone(), + id: value.id(), model: value.unwrap("model").expect("model is mandatory"), price: value.unwrap("price").expect("price is mandatory"), wireless: value.unwrap("wireless").expect("wireless is mandatory"), diff --git a/01.workspace/heave/src/str/entity.rs b/01.workspace/heave/src/str/entity.rs index 0afda28..56d44b9 100644 --- a/01.workspace/heave/src/str/entity.rs +++ b/01.workspace/heave/src/str/entity.rs @@ -4,23 +4,23 @@ use crate::*; #[derive(Debug, PartialEq, Clone)] pub struct O { /// The unique identifier for this entity. - pub id: String, + pub(crate) id: String, /// The current state of the entity within the `Catalog`'s in-memory cache. /// This tracks whether the entity is new, modified, or marked for deletion. - pub state: EntityState, + pub(crate) state: EntityState, /// An optional timestamp or version number, typically used for optimistic /// locking or tracking when the entity was last referenced or modified. - pub ref_date: Option, + pub(crate) ref_date: Option, /// A string identifying the "type" or "class" of the entity (e.g., "product", "user"). /// This is used to group and query entities of the same kind. - pub class: String, + pub(crate) class: String, /// A string identifying the "subtype" or "subclass" of the entity (e.g., /// "computer", "phone", "customer"). This is used to group and query entities /// of different subtype but of the same kind or inside the same domain (class) - pub subclass: Option, + pub(crate) subclass: Option, /// A map of attribute names to `Attribute` values, holding the actual data /// of the entity. - pub attributes: std::collections::HashMap, + pub(crate) attributes: std::collections::HashMap, } impl Entity { @@ -42,7 +42,6 @@ impl Entity { attributes: std::collections::HashMap::::new(), } } - /// Sets the ID of the entity. /// /// # Arguments @@ -56,12 +55,19 @@ impl Entity { self.id = id.to_string(); self } - + /// Sets the subclass of the entity. + /// + /// # Arguments + /// + /// * `subclass` - The subclass to set for the entity. + /// + /// # Returns + /// + /// The entity with the updated subclass. pub fn with_subclass(mut self, subclass: &str) -> Self { self.subclass = Some(subclass.to_string()); self } - /// Sets the reference date of the entity. /// /// # Arguments @@ -75,7 +81,6 @@ impl Entity { self.ref_date = Some(ref_date); self } - /// Adds or updates an attribute for the entity. /// /// # Arguments @@ -91,7 +96,6 @@ impl Entity { self.attributes.insert(attribute.id.clone(), attribute); self } - /// Adds or updates an attribute if the value is `Some`. /// /// # Arguments @@ -109,7 +113,16 @@ impl Entity { } self } - + /// Returns a reference to the `Value` of an attribute. + /// + /// # Arguments + /// + /// * `id` - The ID of the attribute to get the value of. + /// + /// # Returns + /// + /// An `Option<&Value>` which is `Some(&Value)` if the attribute exists, + /// or `None` if it does not. pub(crate) fn value_of(&self, id: &str) -> Option<&Value> { let attribute = self.attributes.get(id); match attribute { @@ -117,7 +130,6 @@ impl Entity { Some(attribute) => Some(&attribute.value), } } - /// Unwraps an attribute's value into a specified type `T`. /// /// This function requires `T` to implement `TryFrom`. @@ -138,7 +150,6 @@ impl Entity { .map(|value| T::try_from(value.clone()).map_err(|_| FailedTo::ConvertValue)) .unwrap() } - /// Unwraps an attribute's value into an `Option`. /// /// This function requires `T` to implement `TryFrom`. @@ -161,7 +172,6 @@ impl Entity { .map(|value| T::try_from(value.clone()).map_err(|_| FailedTo::ConvertValue)) .transpose() } - /// Unwraps an attribute's value, returning a default value if it doesn't exist or fails to convert. /// /// This function requires `T` to implement `TryFrom`. @@ -183,4 +193,12 @@ impl Entity { .transpose() .map(|value| value.unwrap_or(default)) } + /// Returns the ID of the entity. + pub fn id(&self) -> String { + self.id.clone() + } + /// Returns the subclass of the entity, if it has one. + pub fn subclass(&self) -> Option { + self.subclass.clone() + } }