From 31897711b9d978a3994a7941c6d3e3de55bb3b30 Mon Sep 17 00:00:00 2001 From: davidemazzocchi Date: Fri, 3 Oct 2025 14:34:46 +0200 Subject: [PATCH] doc: add more information to README.md --- README.md | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 106 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 76878d4..8a43560 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,12 @@ # heave 󱅝 -A Rust EAV data model implementation +A Rust EAV data model implementation. + +Heave is a Rust library that provides a flexible and extensible implementation of the Entity-Attribute-Value (EAV) data model. It allows you to manage data with a dynamic schema, making it suitable for scenarios where attributes of entities are not known at compile time. The library includes support for persisting the EAV data to a SQLite database. + +## Typed Entities + +Typed entities may be used leveraging the `EAV` trait to map to and from schemaless entities. ## EAV @@ -22,7 +28,105 @@ Learn more on EAV data model [here](https://en.wikipedia.org/wiki/Entity%E2%80%9 ## Example -... +Here is an example of how to define a typed entity, persist it to a SQLite database, and load it back. + +```rust +use heave::{Catalog, EAV, Entity}; +use std::fs; + +// Define a typed entity. +#[derive(Clone, Debug, PartialEq)] +struct Product { + id: String, + name: String, + model: Option, + price: u64, + in_stock: bool, +} + +// Implement the EAV trait to define the class of the entity. +impl EAV for Product { + fn class() -> &'static str { + "product" + } +} + +// Implement From to map a schemaless entity to a typed one. +impl From for Product { + fn from(entity: Entity) -> Self { + Product { + id: entity.id.clone(), + name: entity.unwrap("name"), + model: entity.unwrap_opt("model"), + price: entity.unwrap_or("price", 0), + in_stock: entity.unwrap("in_stock"), + } + } +} + +// Implement From to map a typed entity to a schemaless one. +impl From for Entity { + fn from(value: Product) -> Self { + let mut entity = Entity::new::() + .with_id(&value.id) + .with_attribute("name", value.name) + .with_attribute("price", value.price) + .with_attribute("in_stock", value.in_stock); + if let Some(model) = value.model { + entity.set("model", model); + } + entity + } +} + +fn main() { + let db_path = "example.db"; + + // Initialize a new catalog and database. + let mut catalog = Catalog::new(db_path); + catalog.init(); + + // Create a new typed object. + let product = Product { + id: "prod-123".to_string(), + name: String::from("PenguinX Laptop"), + model: None, + price: 135000, + in_stock: true, + }; + let product_id = product.id.clone(); + + // Insert the object and persist it to the database. + catalog.insert(product); + catalog.persist(); + + // 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_id).unwrap(); + + println!("Successfully persisted and loaded: {:?}", read_product); + + // Clean up the database file. + fs::remove_file(db_path).unwrap(); +} +``` + +## Contributing + +Contributions are welcome! If you'd like to contribute to heave, please follow these steps: + +1. Fork the repository. +2. Create a new branch for your feature or bug fix. +3. Make your changes and commit them with a clear message. +4. Push your branch to your fork. +5. Open a pull request to the main repository. + +Please ensure that your code adheres to the existing style and that all tests pass before submitting a pull request. ## Credits