chore: restore examples after thread safety feature

This commit is contained in:
2025-10-29 11:29:36 +01:00
parent 645e7560b3
commit e1178f7126
2 changed files with 397 additions and 388 deletions

View File

@@ -1,160 +1,161 @@
fn main() {} use heave::*;
// use heave::*;
// // Define a struct named `Component` to represent an electronic component.
// // Define a struct named `Component` to represent an electronic component. #[derive(Debug, Clone, PartialEq)]
// #[derive(Debug, Clone, PartialEq)] struct Component {
// struct Component { pub id: String,
// pub id: String, pub part_number: String,
// pub part_number: String, pub kind: String,
// pub kind: String, pub value: u64,
// pub value: u64, pub package: String,
// pub package: String, pub in_stock: bool,
// pub in_stock: bool, }
// } // Implement the `EAV` trait for the `Component` struct.
// // Implement the `EAV` trait for the `Component` struct. impl EAV for Component {
// impl EAV for Component { // `class` is a function that returns the class name of the entity.
// // `class` is a function that returns the class name of the entity. fn class() -> &'static str {
// fn class() -> &'static str { "component"
// "component" }
// } }
// } // Implement the `From<Component>` trait for the `Entity` struct.
// // Implement the `From<Component>` trait for the `Entity` struct. impl From<Component> for Entity {
// impl From<Component> for Entity { // `from` is a function that converts a `Component` into an `Entity`.
// // `from` is a function that converts a `Component` into an `Entity`. fn from(value: Component) -> Entity {
// fn from(value: Component) -> Entity { Entity::new::<Component>()
// Entity::new::<Component>() .with_id(&value.id)
// .with_id(&value.id) .with_attribute("part_number", value.part_number)
// .with_attribute("part_number", value.part_number) .with_attribute("kind", value.kind)
// .with_attribute("kind", value.kind) .with_attribute("value", value.value)
// .with_attribute("value", value.value) .with_attribute("package", value.package)
// .with_attribute("package", value.package) .with_attribute("in_stock", value.in_stock)
// .with_attribute("in_stock", value.in_stock) }
// } }
// } // Implement the `From<Entity>` trait for the `Component` struct.
// // Implement the `From<Entity>` trait for the `Component` struct. impl From<Entity> for Component {
// impl From<Entity> for Component { // `from` is a function that converts an `Entity` into a `Component`.
// // `from` is a function that converts an `Entity` into a `Component`. fn from(value: Entity) -> Self {
// fn from(value: Entity) -> Self { Self {
// Self { id: value.id.clone(),
// id: value.id.clone(), part_number: value
// part_number: value .unwrap("part_number")
// .unwrap("part_number") .expect("part_number is always present"),
// .expect("part_number is always present"), kind: value.unwrap("kind").expect("kind is always present"),
// kind: value.unwrap("kind").expect("kind is always present"), value: value.unwrap("value").expect("value is always present"),
// value: value.unwrap("value").expect("value is always present"), package: value.unwrap("package").expect("package is always present"),
// package: value.unwrap("package").expect("package is always present"), in_stock: value
// in_stock: value .unwrap("in_stock")
// .unwrap("in_stock") .expect("in_stock is always present"),
// .expect("in_stock is always present"), }
// } }
// } }
// }
// fn main() {
// fn main() { // Define the path for the SQLite database file.
// // Define the path for the SQLite database file. let db_path = "./using_filters.sqlite3";
// let db_path = "./using_filters.sqlite3"; // Create a new `Catalog` instance with the specified database path.
// // Create a new `Catalog` instance with the specified database path. let mut catalog = Catalog::new(db_path);
// let mut catalog = Catalog::new(db_path); // Initialize the catalog, which sets up the database.
// // Initialize the catalog, which sets up the database. catalog.init().unwrap();
// catalog.init().unwrap(); // Create some component instances.
// // Create some component instances. let components_to_add = vec![
// let components_to_add = vec![ // This one should be found
// // This one should be found Component {
// Component { id: "R1".to_string(),
// id: "R1".to_string(), part_number: "R-10K-0805".to_string(),
// part_number: "R-10K-0805".to_string(), kind: "resistor".to_string(),
// kind: "resistor".to_string(), value: 10000,
// value: 10000, package: "smd-0805".to_string(),
// package: "smd-0805".to_string(), in_stock: true,
// in_stock: true, },
// }, // This one should be found
// // This one should be found Component {
// Component { id: "R2".to_string(),
// id: "R2".to_string(), part_number: "R-4K7-0805".to_string(),
// part_number: "R-4K7-0805".to_string(), kind: "resistor".to_string(),
// kind: "resistor".to_string(), value: 4700,
// value: 4700, package: "smd-0805".to_string(),
// package: "smd-0805".to_string(), in_stock: true,
// in_stock: true, },
// }, // This one should NOT be found (wrong kind)
// // This one should NOT be found (wrong kind) Component {
// Component { id: "C1".to_string(),
// id: "C1".to_string(), part_number: "C-100n-0603".to_string(),
// part_number: "C-100n-0603".to_string(), kind: "capacitor".to_string(),
// kind: "capacitor".to_string(), value: 100,
// value: 100, package: "smd-0603".to_string(),
// package: "smd-0603".to_string(), in_stock: true,
// in_stock: true, },
// }, // This one should NOT be found (value too low)
// // This one should NOT be found (value too low) Component {
// Component { id: "R3".to_string(),
// id: "R3".to_string(), part_number: "R-100-0805".to_string(),
// part_number: "R-100-0805".to_string(), kind: "resistor".to_string(),
// kind: "resistor".to_string(), value: 100,
// value: 100, package: "smd-0805".to_string(),
// package: "smd-0805".to_string(), in_stock: true,
// in_stock: true, },
// }, // This one should NOT be found (not in stock)
// // This one should NOT be found (not in stock) Component {
// Component { id: "R4".to_string(),
// id: "R4".to_string(), part_number: "R-22K-TH".to_string(),
// part_number: "R-22K-TH".to_string(), kind: "resistor".to_string(),
// kind: "resistor".to_string(), value: 22000,
// value: 22000, package: "through-hole".to_string(),
// package: "through-hole".to_string(), in_stock: false,
// in_stock: false, },
// }, // This one should NOT be found (wrong kind, even if other fields match)
// // This one should NOT be found (wrong kind, even if other fields match) Component {
// Component { id: "L1".to_string(),
// id: "L1".to_string(), part_number: "L-10mH-TH".to_string(),
// part_number: "L-10mH-TH".to_string(), kind: "inductor".to_string(),
// kind: "inductor".to_string(), value: 10000,
// value: 10000, package: "through-hole".to_string(),
// package: "through-hole".to_string(), in_stock: true,
// in_stock: true, },
// }, ];
// ]; // Insert the components into the catalog.
// // Insert the components into the catalog. catalog.insert_many(components_to_add.clone()).unwrap();
// catalog.insert_many(components_to_add.clone()).unwrap(); // Persist the changes to the database.
// // Persist the changes to the database. catalog.persist().unwrap();
// catalog.persist().unwrap(); // Create a new catalog to ensure we are loading from the database.
// // Create a new catalog to ensure we are loading from the database. let mut new_catalog = Catalog::new(db_path);
// let mut new_catalog = Catalog::new(db_path); // Create a composite filter.
// // Create a composite filter. // We are looking for resistors with a value greater than 1000 that are in stock.
// // We are looking for resistors with a value greater than 1000 that are in stock. let filter = Filter::new()
// let filter = Filter::new() .with_text("kind", Comparison::IsExactly, "resistor")
// .with_text("kind", Comparison::IsExactly, "resistor") .with_unsigned_int("value", Comparison::Greater, 1000)
// .with_unsigned_int("value", Comparison::Greater, 1000) .with_bool("in_stock", true);
// .with_bool("in_stock", true); // Load entities from the database using the filter.
// // Load entities from the database using the filter. new_catalog.load_by_filter(&filter).unwrap();
// new_catalog.load_by_filter(&filter).unwrap(); // Get the list of loaded components.
// // Get the list of loaded components. let loaded_components: Vec<Component> = new_catalog
// let loaded_components: Vec<Component> = new_catalog .list_by_class::<Component>()
// .list_by_class::<Component>() .unwrap()
// .map(|c| c.unwrap()) .into_iter()
// .collect(); .map(|c| c.unwrap())
// // Print the loaded components .collect();
// println!( // Print the loaded components
// "Found {} components matching the filter:", println!(
// loaded_components.len() "Found {} components matching the filter:",
// ); loaded_components.len()
// for component in &loaded_components { );
// println!( for component in &loaded_components {
// "- ID: {}, Part Number: {}, Kind: {}, Value: {}, Package: {}, In Stock: {}", println!(
// component.id, "- ID: {}, Part Number: {}, Kind: {}, Value: {}, Package: {}, In Stock: {}",
// component.part_number, component.id,
// component.kind, component.part_number,
// component.value, component.kind,
// component.package, component.value,
// component.in_stock component.package,
// ); component.in_stock
// } );
// // Verify that we have loaded the correct number of components. }
// assert_eq!(loaded_components.len(), 2); // Verify that we have loaded the correct number of components.
// // Verify that the correct components were loaded. assert_eq!(loaded_components.len(), 2);
// let ids: Vec<String> = loaded_components.iter().map(|c| c.id.clone()).collect(); // Verify that the correct components were loaded.
// assert!(ids.contains(&"R1".to_string())); let ids: Vec<String> = loaded_components.iter().map(|c| c.id.clone()).collect();
// assert!(ids.contains(&"R2".to_string())); assert!(ids.contains(&"R1".to_string()));
// // Clean up the database file. assert!(ids.contains(&"R2".to_string()));
// std::fs::remove_file(db_path).unwrap(); // Clean up the database file.
// } std::fs::remove_file(db_path).unwrap();
}

View File

@@ -1,228 +1,236 @@
fn main() {} use heave::*;
// use heave::*; use std::path::Path;
// use std::path::Path;
// struct Laptop {
// struct Laptop { pub id: String,
// pub id: String, pub model: String,
// pub model: String, pub price: u64,
// pub price: u64, }
// } struct Display {
// struct Display { pub id: String,
// pub id: String, pub model: String,
// pub model: String, pub resolution: f64,
// pub resolution: f64, pub price: u64,
// pub price: u64, }
// } struct Mouse {
// struct Mouse { pub id: String,
// pub id: String, pub model: String,
// pub model: String, pub wireless: bool,
// pub wireless: bool, pub price: u64,
// pub price: u64, }
// } enum Product {
// enum Product { None,
// None, Laptop(Laptop),
// Laptop(Laptop), Display(Display),
// Display(Display), Mouse(Mouse),
// Mouse(Mouse), }
// } impl EAV for Product {
// impl EAV for Product { fn class() -> &'static str {
// fn class() -> &'static str { "product"
// "product" }
// } }
// } impl From<Entity> for Product {
// impl From<Entity> for Product { fn from(value: Entity) -> Self {
// fn from(value: Entity) -> Self { if let Some(ref subclass) = value.subclass {
// if let Some(ref subclass) = value.subclass { match subclass.as_ref() {
// match subclass.as_ref() { "laptop" => Product::Laptop(Laptop {
// "laptop" => Product::Laptop(Laptop { id: value.id.clone(),
// id: value.id.clone(), model: value.unwrap("model").expect("model is mandatory"),
// model: value.unwrap("model").expect("model is mandatory"), price: value.unwrap("price").expect("price is mandatory"),
// price: value.unwrap("price").expect("price is mandatory"), }),
// }), "display" => Product::Display(Display {
// "display" => Product::Display(Display { id: value.id.clone(),
// id: value.id.clone(), model: value.unwrap("model").expect("model is mandatory"),
// model: value.unwrap("model").expect("model is mandatory"), price: value.unwrap("price").expect("price is mandatory"),
// price: value.unwrap("price").expect("price is mandatory"), resolution: value.unwrap("resolution").expect("resolution is mandatory"),
// resolution: value.unwrap("resolution").expect("resolution is mandatory"), }),
// }), "mouse" => Product::Mouse(Mouse {
// "mouse" => Product::Mouse(Mouse { id: value.id.clone(),
// id: value.id.clone(), model: value.unwrap("model").expect("model is mandatory"),
// model: value.unwrap("model").expect("model is mandatory"), price: value.unwrap("price").expect("price is mandatory"),
// price: value.unwrap("price").expect("price is mandatory"), wireless: value.unwrap("wireless").expect("wireless is mandatory"),
// wireless: value.unwrap("wireless").expect("wireless is mandatory"), }),
// }), _ => unreachable!(),
// _ => unreachable!(), }
// } } else {
// } else { Product::None
// Product::None }
// } }
// } }
// } impl From<Product> for Entity {
// impl From<Product> for Entity { fn from(value: Product) -> Self {
// fn from(value: Product) -> Self { match value {
// match value { Product::Laptop(value) => Entity::new::<Product>()
// Product::Laptop(value) => Entity::new::<Product>() .with_id(&value.id)
// .with_id(&value.id) .with_subclass("laptop")
// .with_subclass("laptop") .with_attribute("model", value.model)
// .with_attribute("model", value.model) .with_attribute("price", value.price),
// .with_attribute("price", value.price), Product::Display(value) => Entity::new::<Product>()
// Product::Display(value) => Entity::new::<Product>() .with_id(&value.id)
// .with_id(&value.id) .with_subclass("display")
// .with_subclass("display") .with_attribute("model", value.model)
// .with_attribute("model", value.model) .with_attribute("resolution", value.resolution)
// .with_attribute("resolution", value.resolution) .with_attribute("price", value.price),
// .with_attribute("price", value.price), Product::Mouse(value) => Entity::new::<Product>()
// Product::Mouse(value) => Entity::new::<Product>() .with_id(&value.id)
// .with_id(&value.id) .with_subclass("mouse")
// .with_subclass("mouse") .with_attribute("model", value.model)
// .with_attribute("model", value.model) .with_attribute("wireless", value.wireless)
// .with_attribute("wireless", value.wireless) .with_attribute("price", value.price),
// .with_attribute("price", value.price), _ => unreachable!(),
// _ => unreachable!(), }
// } }
// } }
// } fn main() -> Result<(), FailedTo> {
// fn main() -> Result<(), FailedTo> { let db_path = "working_with_many_types.db";
// let db_path = "working_with_many_types.db";
// // Clean up previous runs if file exists
// // Clean up previous runs if file exists if Path::new(db_path).exists() {
// if Path::new(db_path).exists() { std::fs::remove_file(db_path).unwrap();
// std::fs::remove_file(db_path).unwrap(); }
// }
// // 1. Initialize and Persist Data
// // 1. Initialize and Persist Data println!("== 1. Storing different product types ==");
// println!("== 1. Storing different product types =="); let mut catalog = Catalog::new(db_path);
// let mut catalog = Catalog::new(db_path); catalog.init()?;
// catalog.init()?;
// let products_to_add = vec![
// let products_to_add = vec![ Product::Laptop(Laptop {
// Product::Laptop(Laptop { id: "laptop_01".to_string(),
// id: "laptop_01".to_string(), model: "Titan".to_string(),
// model: "Titan".to_string(), price: 1500,
// price: 1500, }),
// }), Product::Display(Display {
// Product::Display(Display { id: "display_01".to_string(),
// id: "display_01".to_string(), model: "CrystalClear".to_string(),
// model: "CrystalClear".to_string(), resolution: 4.0, // 4K
// resolution: 4.0, // 4K price: 600,
// price: 600, }),
// }), Product::Mouse(Mouse {
// Product::Mouse(Mouse { id: "mouse_01".to_string(),
// id: "mouse_01".to_string(), model: "SwiftClick".to_string(),
// model: "SwiftClick".to_string(), wireless: true,
// wireless: true, price: 80,
// price: 80, }),
// }), Product::Laptop(Laptop {
// Product::Laptop(Laptop { id: "laptop_02".to_string(),
// id: "laptop_02".to_string(), model: "Nomad".to_string(),
// model: "Nomad".to_string(), price: 950,
// price: 950, }),
// }), ];
// ];
// catalog.insert_many(products_to_add)?;
// catalog.insert_many(products_to_add)?; catalog.persist()?;
// catalog.persist()?; println!("✅ 4 products saved to the database.\n");
// println!("✅ 4 products saved to the database.\n");
// // 2. Load data using filters
// // 2. Load data using filters println!("== 2. Loading products using class and subclass filters ==");
// println!("== 2. Loading products using class and subclass filters ==");
// // Load only laptops
// // Load only laptops let mut laptop_catalog = Catalog::new(db_path);
// let mut laptop_catalog = Catalog::new(db_path); let laptop_filter = Filter::new()
// let laptop_filter = Filter::new() .with_class(Product::class())
// .with_class(Product::class()) .with_subclass("laptop");
// .with_subclass("laptop");
// laptop_catalog.load_by_filter(&laptop_filter)?;
// laptop_catalog.load_by_filter(&laptop_filter)?;
// let laptops: Vec<Product> = laptop_catalog
// let laptops: Vec<Product> = laptop_catalog.list_by_class().map(|p| p.unwrap()).collect(); .list_by_class()
// .unwrap()
// println!("✅ Loaded {} laptop(s) using filter.", laptops.len()); .into_iter()
// assert_eq!(laptops.len(), 2); .map(|p| p.unwrap())
// for p in laptops { .collect();
// if let Product::Laptop(laptop) = p {
// println!( println!("✅ Loaded {} laptop(s) using filter.", laptops.len());
// " - Laptop: {} ({}) - ${}", assert_eq!(laptops.len(), 2);
// laptop.id, laptop.model, laptop.price for p in laptops {
// ); if let Product::Laptop(laptop) = p {
// } println!(
// } " - Laptop: {} ({}) - ${}",
// println!(); laptop.id, laptop.model, laptop.price
// );
// println!("== 3. Loading products using attribute filters =="); }
// // Load expensive products (price > 1000) }
// let mut expensive_catalog = Catalog::new(db_path); println!();
// let expensive_filter = Filter::new()
// .with_class(Product::class()) println!("== 3. Loading products using attribute filters ==");
// .with_unsigned_int("price", Comparison::Greater, 1000); // Load expensive products (price > 1000)
// let mut expensive_catalog = Catalog::new(db_path);
// expensive_catalog.load_by_filter(&expensive_filter)?; let expensive_filter = Filter::new()
// .with_class(Product::class())
// let expensive_products: Vec<Product> = expensive_catalog .with_unsigned_int("price", Comparison::Greater, 1000);
// .list_by_class()
// .map(|p| p.unwrap()) expensive_catalog.load_by_filter(&expensive_filter)?;
// .collect();
// let expensive_products: Vec<Product> = expensive_catalog
// println!( .list_by_class()
// "✅ Loaded {} product(s) with price > $1000.", .unwrap()
// expensive_products.len() .into_iter()
// ); .map(|p| p.unwrap())
// assert_eq!(expensive_products.len(), 1); .collect();
//
// for p in expensive_products { println!(
// match p { "✅ Loaded {} product(s) with price > $1000.",
// Product::Laptop(laptop) => { expensive_products.len()
// println!( );
// " - Found Laptop: {} ({}) - ${}", assert_eq!(expensive_products.len(), 1);
// laptop.id, laptop.model, laptop.price
// ); for p in expensive_products {
// assert_eq!(laptop.id, "laptop_01"); match p {
// } Product::Laptop(laptop) => {
// _ => panic!("Expected a laptop!"), println!(
// } " - Found Laptop: {} ({}) - ${}",
// } laptop.id, laptop.model, laptop.price
// println!(); );
// assert_eq!(laptop.id, "laptop_01");
// println!("== 4. Loading all product types =="); }
// let mut all_products_catalog = Catalog::new(db_path); _ => panic!("Expected a laptop!"),
// let all_products_filter = Filter::new().with_class(Product::class()); }
// all_products_catalog.load_by_filter(&all_products_filter)?; }
// println!();
// let all_products: Vec<Product> = all_products_catalog
// .list_by_class() println!("== 4. Loading all product types ==");
// .map(|p| p.unwrap()) let mut all_products_catalog = Catalog::new(db_path);
// .collect(); let all_products_filter = Filter::new().with_class(Product::class());
// all_products_catalog.load_by_filter(&all_products_filter)?;
// println!("✅ Loaded {} total products.", all_products.len());
// assert_eq!(all_products.len(), 4); let all_products: Vec<Product> = all_products_catalog
// .list_by_class()
// for p in all_products { .unwrap()
// match p { .into_iter()
// Product::Laptop(laptop) => { .map(|p| p.unwrap())
// println!( .collect();
// " - Found Laptop: {} ({}) - ${}",
// laptop.id, laptop.model, laptop.price println!("✅ Loaded {} total products.", all_products.len());
// ); assert_eq!(all_products.len(), 4);
// }
// Product::Display(display) => { for p in all_products {
// println!( match p {
// " - Found Display: {} ({}) - ${}", Product::Laptop(laptop) => {
// display.id, display.model, display.price println!(
// ); " - Found Laptop: {} ({}) - ${}",
// } laptop.id, laptop.model, laptop.price
// Product::Mouse(mouse) => { );
// println!( }
// " - Found Mouse: {} ({}) - ${}", Product::Display(display) => {
// mouse.id, mouse.model, mouse.price println!(
// ); " - Found Display: {} ({}) - ${}",
// } display.id, display.model, display.price
// Product::None => panic!("Product::None should not be loaded"), );
// } }
// } Product::Mouse(mouse) => {
// println!(); println!(
// " - Found Mouse: {} ({}) - ${}",
// // Clean up the created database file mouse.id, mouse.model, mouse.price
// std::fs::remove_file(db_path).unwrap(); );
// }
// Ok(()) Product::None => panic!("Product::None should not be loaded"),
// } }
}
println!();
// Clean up the created database file
std::fs::remove_file(db_path).unwrap();
Ok(())
}