doc: update readme with actual example code

This commit is contained in:
2025-10-09 12:49:57 +02:00
parent 8fb5a2ce72
commit 02eddc19e3

119
README.md
View File

@@ -31,88 +31,83 @@ Learn more on EAV data model [here](https://en.wikipedia.org/wiki/Entity%E2%80%9
Here is an example of how to define a typed entity, persist it to a SQLite database, and load it back. Here is an example of how to define a typed entity, persist it to a SQLite database, and load it back.
```rust ```rust
use heave::{Catalog, EAV, Entity}; use heave::*;
use std::fs;
// Define a typed entity. // Define a struct named `Product` to represent a product.
#[derive(Clone, Debug, PartialEq)]
struct Product { struct Product {
id: String, // `id` is a public field of type `String` to uniquely identify the product.
name: String, pub id: String,
model: Option<String>, // `name` is a public field of type `String` for the product's name.
price: u64, pub name: String,
in_stock: bool, // `model` is a public optional field of type `String` for the product's model.
pub model: Option<String>,
// `price` is a public field of type `i64` for the product's price.
pub price: i64,
} }
// Implement the EAV trait to define the class of the entity. // Implement the `EAV` trait for the `Product` struct.
impl EAV for Product { impl EAV for Product {
// `class` is a function that returns the class name of the entity.
fn class() -> &'static str { fn class() -> &'static str {
"product" "product"
} }
} }
// Implement From<Entity> to map a schemaless entity to a typed one. // Implement the `From<Product>` trait for the `Entity` struct.
impl From<Entity> for Product { impl From<Product> for Entity {
fn from(entity: Entity) -> Self { // `from` is a function that converts a `Product` into an `Entity`.
Product { fn from(value: Product) -> Entity {
id: entity.id.clone(), // Create a new `Entity` for the `Product` class.
name: entity.unwrap("name"), Entity::new::<Product>()
model: entity.unwrap_opt("model"), // Set the entity's ID from the product's ID.
price: entity.unwrap_or("price", 0), .with_id(&value.id)
in_stock: entity.unwrap("in_stock"), // Add the "name" attribute with the product's name.
} .with_attribute("name", value.name)
// Add the optional "model" attribute with the product's model.
.with_opt_attribute("model", value.model)
// Add the "price" attribute with the product's price.
.with_attribute("price", value.price)
} }
} }
// Implement From<Product> to map a typed entity to a schemaless one. // Implement the `From<Entity>` trait for the `Product` struct.
impl From<Product> for Entity { impl From<Entity> for Product {
fn from(value: Product) -> Self { // `from` is a function that converts an `Entity` into a `Product`.
let mut entity = Entity::new::<Product>() fn from(value: Entity) -> Self {
.with_id(&value.id) // Create a new `Product` from the entity's attributes.
.with_attribute("name", value.name) Self {
.with_attribute("price", value.price) // Set the product's ID from the entity's ID.
.with_attribute("in_stock", value.in_stock); id: value.id.clone(),
if let Some(model) = value.model { // Unwrap the "name" attribute to get the product's name.
entity.set("model", model); name: value.unwrap("name"),
// Unwrap the optional "model" attribute to get the product's model.
model: value.unwrap_opt("model"),
// Unwrap the "price" attribute to get the product's price.
price: value.unwrap("price"),
} }
entity
} }
} }
fn main() { fn main() {
let db_path = "example.db"; // Define the path for the SQLite database file.
let db_path = "./simple_product.sqlite3";
// Initialize a new catalog and database. // Create a new `Catalog` instance with the specified database path.
let mut catalog = Catalog::new(db_path); let mut catalog = Catalog::new(db_path);
catalog.init(); // Initialize the catalog, which sets up the database.
catalog.init().unwrap();
// Create a new typed object. // Create a new `Product` instance representing a laptop.
let product = Product { let new_laptop = Product {
id: "prod-123".to_string(), id: "LT001".to_string(),
name: String::from("PenguinX Laptop"), name: "SuperPenguin".to_string(),
model: None, model: Some("Mark III.2".to_string()),
price: 135000, price: 125000,
in_stock: true,
}; };
let product_id = product.id.clone(); // Insert the new laptop into the catalog. Note that at this time the product is in memory.
catalog.insert(new_laptop);
// Insert the object and persist it to the database. // Persist the changes in the catalog to the database.
catalog.insert(product); catalog.persist().unwrap();
catalog.persist(); // Remove the SQLite database file.
std::fs::remove_file(db_path).unwrap();
// Create a new catalog to simulate a different application instance.
let mut new_catalog = Catalog::new(db_path);
// Load the entity from the database.
new_catalog.load_by_id(&product_id);
// Retrieve the typed object from the catalog.
let read_product = new_catalog.get::<Product>(&product_id).unwrap();
println!("Successfully persisted and loaded: {:?}", read_product);
// Clean up the database file.
fs::remove_file(db_path).unwrap();
} }
``` ```