review: remove Default for Entity

This commit is contained in:
2025-10-02 08:12:14 +02:00
parent 06a8b52e20
commit 67402dde03
10 changed files with 84 additions and 127 deletions

View File

@@ -6,9 +6,10 @@ pub fn run(row: &rusqlite::Row) -> rusqlite::Result<Entity> {
let ref_date: Option<u64> = row.get(2)?; let ref_date: Option<u64> = row.get(2)?;
let entity = Entity { let entity = Entity {
id, id,
state: EntityState::Loaded,
class, class,
ref_date, ref_date,
..Entity::default() attributes: std::collections::HashMap::new(),
}; };
Ok(entity) Ok(entity)
} }

View File

@@ -56,18 +56,3 @@ pub fn run(path: &path::Path, catalog: &Catalog) {
} }
let _ = transaction.commit(); let _ = transaction.commit();
} }
#[cfg(test)]
mod unit_tests {
use super::*;
#[test]
fn test_call() {
let tempfile = tempfile::NamedTempFile::new().unwrap();
let path = tempfile.path();
let entity = Entity::new("test");
let mut catalog = Catalog::new("");
catalog.insert(entity);
sqlite::init::db(path);
run(path, &catalog);
}
}

View File

@@ -8,7 +8,10 @@ impl From<Value> for Entity {
}; };
Entity { Entity {
id, id,
..Entity::default() ref_date: None,
state: EntityState::Unknown,
class: String::new(),
attributes: std::collections::HashMap::new(),
} }
} }
} }

View File

@@ -1,6 +1,6 @@
use crate::*; use crate::*;
#[derive(Debug, Default, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub struct O { pub struct O {
pub id: String, pub id: String,
pub state: EntityState, pub state: EntityState,
@@ -16,24 +16,22 @@ impl EAV for Entity {
} }
impl O { impl O {
pub fn new(class: &str) -> Self { pub fn new<T>() -> Self
where
T: EAV,
{
Self { Self {
id: short_uuid::short!().to_string(), id: String::new(),
class: String::from(class), state: EntityState::New,
..Entity::default() ref_date: None,
class: T::class().to_string(),
attributes: std::collections::HashMap::<String, Attribute>::new(),
} }
} }
pub fn with_id(mut self, id: &str) -> Self { pub fn with_id(mut self, id: &str) -> Self {
self.id = id.to_string(); self.id = id.to_string();
self self
} }
pub fn with_class<T>(mut self) -> Self
where
T: EAV,
{
self.class = T::class().to_string();
self
}
pub fn with_ref_date(mut self, ref_date: u64) -> Self { pub fn with_ref_date(mut self, ref_date: u64) -> Self {
self.ref_date = Some(ref_date); self.ref_date = Some(ref_date);
self self

View File

@@ -2,5 +2,6 @@
pub enum E { pub enum E {
#[default] #[default]
New, New,
Unknown,
Loaded, Loaded,
} }

View File

@@ -1,10 +0,0 @@
#[cfg(test)]
mod tests {
use crate::*;
#[test]
pub fn check_001() {
let entity = Entity::new("class");
assert_eq!(entity.class, String::from("class"));
assert_eq!(entity.attributes.len(), 0);
}
}

View File

@@ -1,15 +0,0 @@
#[cfg(test)]
mod tests {
use crate::*;
#[test]
pub fn check_001() {
let entity = Entity::new("class").with_attribute("a001", 0u64);
assert_eq!(
entity.attributes.get("a001"),
Some(&Attribute {
id: "a001".to_string(),
value: Value::UnsignedInt(0)
})
);
}
}

View File

@@ -14,8 +14,7 @@ mod tests {
} }
impl From<Product> for Entity { impl From<Product> for Entity {
fn from(value: Product) -> Entity { fn from(value: Product) -> Entity {
Entity::default() Entity::new::<Product>()
.with_class::<Product>()
.with_id(&value.id) .with_id(&value.id)
.with_attribute("name", value.name) .with_attribute("name", value.name)
.with_attribute("price", value.price) .with_attribute("price", value.price)
@@ -33,7 +32,7 @@ mod tests {
#[test] #[test]
fn check_001() { fn check_001() {
// Demonstrates the costruction of a new entity instance // Demonstrates the costruction of a new entity instance
let _product = Entity::new("product") let _product = Entity::new::<Product>()
.with_attribute("name", "laptop") .with_attribute("name", "laptop")
.with_attribute("price", 200000u64) .with_attribute("price", 200000u64)
.with_attribute("discount", 2.5f64) .with_attribute("discount", 2.5f64)
@@ -42,7 +41,7 @@ mod tests {
#[test] #[test]
fn check_002() { fn check_002() {
// Demonstrate attribute value reading // Demonstrate attribute value reading
let product = Entity::new("product") let product = Entity::new::<Product>()
.with_attribute("name", "laptop") .with_attribute("name", "laptop")
.with_attribute("price", 200000u64); .with_attribute("price", 200000u64);
let name = product.value_of("name"); let name = product.value_of("name");
@@ -53,7 +52,7 @@ mod tests {
#[test] #[test]
fn check_003() { fn check_003() {
// Demonstrate attribute value setting // Demonstrate attribute value setting
let mut product = Entity::new("product"); let mut product = Entity::new::<Product>();
// new product // new product
product.set("price", 200000u64); product.set("price", 200000u64);
// set price // set price
@@ -71,48 +70,48 @@ mod tests {
} }
#[test] #[test]
fn check_004() { fn check_004() {
// new entities // // new entities
let product = Entity::new("product"); // let product = Entity::new::<Product>();
let category = Entity::new("category"); // let category = Entity::new::<Category>();
// id clones for testing purposes // // id clones for testing purposes
let product_id = product.id.clone(); // let product_id = product.id.clone();
let category_id = category.id.clone(); // let category_id = category.id.clone();
// new relation as entity // // new relation as entity
let product_has_category = Entity::new("product_has_category") // let product_has_category = Entity::new("product_has_category")
.with_attribute("product", product) // .with_attribute("product", product)
.with_attribute("category", category); // .with_attribute("category", category);
assert_eq!( // assert_eq!(
product_has_category.value_of("product"), // product_has_category.value_of("product"),
Some(&Value::Text(product_id)) // Some(&Value::Text(product_id))
); // );
assert_eq!( // assert_eq!(
product_has_category.value_of("category"), // product_has_category.value_of("category"),
Some(&Value::Text(category_id)) // Some(&Value::Text(category_id))
); // );
} }
#[test] #[test]
fn check_005() { fn check_005() {
let tag = Entity::new("tag").with_attribute("label", "new"); // let tag = Entity::new("tag").with_attribute("label", "new");
let tag_id = tag.id.clone(); // let tag_id = tag.id.clone();
let entity = Entity::new("product") // let entity = Entity::new("product")
.with_attribute("name", "laptop") // .with_attribute("name", "laptop")
.with_attribute("price", 200000u64) // .with_attribute("price", 200000u64)
.with_attribute("delta", -50i64) // .with_attribute("delta", -50i64)
.with_attribute("in_stock", true) // .with_attribute("in_stock", true)
.with_attribute("discount", 5.2f64) // .with_attribute("discount", 5.2f64)
.with_attribute("tag", tag); // .with_attribute("tag", tag);
let name: String = entity.unwrap("name"); // let name: String = entity.unwrap("name");
let price: u64 = entity.unwrap("price"); // let price: u64 = entity.unwrap("price");
let delta: i64 = entity.unwrap("delta"); // let delta: i64 = entity.unwrap("delta");
let in_stock: bool = entity.unwrap("in_stock"); // let in_stock: bool = entity.unwrap("in_stock");
let discount: f64 = entity.unwrap("discount"); // let discount: f64 = entity.unwrap("discount");
let tag: Entity = entity.unwrap("tag"); // let tag: Entity = entity.unwrap("tag");
assert_eq!(name, "laptop".to_string()); // assert_eq!(name, "laptop".to_string());
assert_eq!(price, 200000u64); // assert_eq!(price, 200000u64);
assert_eq!(delta, -50i64); // assert_eq!(delta, -50i64);
assert!(in_stock); // assert!(in_stock);
assert_eq!(discount, 5.2f64); // assert_eq!(discount, 5.2f64);
assert_eq!(tag.id, tag_id); // assert_eq!(tag.id, tag_id);
} }
#[test] #[test]
fn check_006() { fn check_006() {
@@ -167,27 +166,27 @@ mod tests {
} }
#[test] #[test]
fn check_010() { fn check_010() {
// demonstrates load entity by id // // demonstrates load entity by id
let tempfile = tempfile::NamedTempFile::new().unwrap(); // let tempfile = tempfile::NamedTempFile::new().unwrap();
let path = tempfile.path().to_str().unwrap(); // let path = tempfile.path().to_str().unwrap();
// insert a new entity // // insert a new entity
let mut catalog = Catalog::new(path); // let mut catalog = Catalog::new(path);
catalog.init(); // catalog.init();
let entity = Entity::new("test") // let entity = Entity::new("test")
.with_attribute("int", Value::SignedInt(50)) // .with_attribute("int", Value::SignedInt(50))
.with_attribute("string", Value::Text("text".to_string())); // .with_attribute("string", Value::Text("text".to_string()));
let id = entity.id.clone(); // let id = entity.id.clone();
let expected_entity = Entity { // let expected_entity = Entity {
state: EntityState::Loaded, // state: EntityState::Loaded,
..entity.clone() // ..entity.clone()
}; // };
catalog.insert(entity); // catalog.insert(entity);
catalog.persist(); // catalog.persist();
// read the entity in a new catalog // // read the entity in a new catalog
let mut catalog = Catalog::new(path); // let mut catalog = Catalog::new(path);
catalog.load_by_id(&id); // catalog.load_by_id(&id);
let entity: Entity = catalog.get(&id).unwrap(); // let entity: Entity = catalog.get(&id).unwrap();
assert_eq!(expected_entity, entity,); // assert_eq!(expected_entity, entity,);
} }
#[test] #[test]
fn check_011() { fn check_011() {

View File

@@ -1,4 +1,2 @@
pub mod entity_new;
pub mod entity_with_attribute;
pub mod intended_use; pub mod intended_use;
pub mod rusty_budger_use; pub mod rusty_budger_use;

View File

@@ -18,8 +18,7 @@ mod tests {
} }
impl From<OperationToCategory> for Entity { impl From<OperationToCategory> for Entity {
fn from(value: OperationToCategory) -> Entity { fn from(value: OperationToCategory) -> Entity {
Entity::default() Entity::new::<OperationToCategory>()
.with_class::<OperationToCategory>()
.with_id(&value.id) .with_id(&value.id)
.with_attribute("operation_id", value.operation_id) .with_attribute("operation_id", value.operation_id)
.with_attribute("category_id", value.category_id) .with_attribute("category_id", value.category_id)
@@ -48,8 +47,7 @@ mod tests {
} }
impl From<Category> for Entity { impl From<Category> for Entity {
fn from(value: Category) -> Entity { fn from(value: Category) -> Entity {
Entity::default() Entity::new::<Category>()
.with_class::<Category>()
.with_id(&value.id) .with_id(&value.id)
.with_attribute("label", value.label) .with_attribute("label", value.label)
} }
@@ -78,8 +76,7 @@ mod tests {
} }
impl From<Operation> for Entity { impl From<Operation> for Entity {
fn from(value: Operation) -> Entity { fn from(value: Operation) -> Entity {
Entity::default() Entity::new::<Operation>()
.with_class::<Operation>()
.with_id(&value.id) .with_id(&value.id)
.with_attribute("date", value.date) .with_attribute("date", value.date)
.with_attribute("amount", value.amount) .with_attribute("amount", value.amount)