implement more models and rhai examples

This commit is contained in:
timurgordon
2025-05-22 03:57:03 +03:00
parent aa8ef90f9f
commit 56ec505874
79 changed files with 4546 additions and 182 deletions

View File

@@ -0,0 +1,324 @@
use rhai::{Engine, Module, Dynamic, EvalAltResult, Position};
use std::sync::Arc;
use crate::db::Collection; // For db.set and db.get_by_id
use crate::db::hero::OurDB;
use super::company::{Company, CompanyStatus, BusinessType};
use crate::models::biz::shareholder::{Shareholder, ShareholderType};
use crate::models::biz::product::{Product, ProductType, ProductStatus, ProductComponent};
use crate::models::biz::sale::{Sale, SaleItem, SaleStatus};
use heromodels_core::Model;
// Helper function to convert i64 to u32, returning a Rhai error if conversion fails
fn id_from_i64(id_val: i64) -> Result<u32, Box<EvalAltResult>> {
u32::try_from(id_val).map_err(|_| {
Box::new(EvalAltResult::ErrorArithmetic(
format!("Failed to convert i64 '{}' to u32 for ID", id_val),
Position::NONE,
))
})
}
pub fn register_biz_rhai_module(engine: &mut Engine, db: Arc<OurDB>) {
let module = Module::new();
// --- Enum Constants: CompanyStatus ---
let mut status_constants_module = Module::new();
status_constants_module.set_var("Active", Dynamic::from(CompanyStatus::Active.clone()));
status_constants_module.set_var("Inactive", Dynamic::from(CompanyStatus::Inactive.clone()));
status_constants_module.set_var("Suspended", Dynamic::from(CompanyStatus::Suspended.clone()));
engine.register_static_module("CompanyStatusConstants", status_constants_module.into());
engine.register_type_with_name::<CompanyStatus>("CompanyStatus");
// --- Enum Constants: BusinessType ---
let mut business_type_constants_module = Module::new();
business_type_constants_module.set_var("Coop", Dynamic::from(BusinessType::Coop.clone()));
business_type_constants_module.set_var("Single", Dynamic::from(BusinessType::Single.clone()));
business_type_constants_module.set_var("Twin", Dynamic::from(BusinessType::Twin.clone()));
business_type_constants_module.set_var("Starter", Dynamic::from(BusinessType::Starter.clone()));
business_type_constants_module.set_var("Global", Dynamic::from(BusinessType::Global.clone()));
engine.register_static_module("BusinessTypeConstants", business_type_constants_module.into());
engine.register_type_with_name::<BusinessType>("BusinessType");
// --- Company ---
engine.register_type_with_name::<Company>("Company");
// Constructor
engine.register_fn("new_company", |id: i64, name: String, registration_number: String, incorporation_date: i64| -> Result<Company, Box<EvalAltResult>> { Ok(Company::new(id as u32, name, registration_number, incorporation_date)) });
// Getters for Company
engine.register_get("id", |company: &mut Company| -> Result<i64, Box<EvalAltResult>> { Ok(company.get_id() as i64) });
engine.register_get("created_at", |company: &mut Company| -> Result<i64, Box<EvalAltResult>> { Ok(company.base_data.created_at) });
engine.register_get("modified_at", |company: &mut Company| -> Result<i64, Box<EvalAltResult>> { Ok(company.base_data.modified_at) });
engine.register_get("name", |company: &mut Company| -> Result<String, Box<EvalAltResult>> { Ok(company.name.clone()) });
engine.register_get("registration_number", |company: &mut Company| -> Result<String, Box<EvalAltResult>> { Ok(company.registration_number.clone()) });
engine.register_get("incorporation_date", |company: &mut Company| -> Result<i64, Box<EvalAltResult>> { Ok(company.incorporation_date as i64) });
engine.register_get("fiscal_year_end", |company: &mut Company| -> Result<String, Box<EvalAltResult>> { Ok(company.fiscal_year_end.clone()) });
engine.register_get("email", |company: &mut Company| -> Result<String, Box<EvalAltResult>> { Ok(company.email.clone()) });
engine.register_get("phone", |company: &mut Company| -> Result<String, Box<EvalAltResult>> { Ok(company.phone.clone()) });
engine.register_get("website", |company: &mut Company| -> Result<String, Box<EvalAltResult>> { Ok(company.website.clone()) });
engine.register_get("address", |company: &mut Company| -> Result<String, Box<EvalAltResult>> { Ok(company.address.clone()) });
engine.register_get("business_type", |company: &mut Company| -> Result<BusinessType, Box<EvalAltResult>> { Ok(company.business_type.clone()) });
engine.register_get("industry", |company: &mut Company| -> Result<String, Box<EvalAltResult>> { Ok(company.industry.clone()) });
engine.register_get("description", |company: &mut Company| -> Result<String, Box<EvalAltResult>> { Ok(company.description.clone()) });
engine.register_get("status", |company: &mut Company| -> Result<CompanyStatus, Box<EvalAltResult>> { Ok(company.status.clone()) });
// Builder methods for Company
engine.register_fn("fiscal_year_end", |company: Company, fiscal_year_end: String| -> Result<Company, Box<EvalAltResult>> { Ok(company.fiscal_year_end(fiscal_year_end)) });
engine.register_fn("email", |company: Company, email: String| -> Result<Company, Box<EvalAltResult>> { Ok(company.email(email)) });
engine.register_fn("phone", |company: Company, phone: String| -> Result<Company, Box<EvalAltResult>> { Ok(company.phone(phone)) });
engine.register_fn("website", |company: Company, website: String| -> Result<Company, Box<EvalAltResult>> { Ok(company.website(website)) });
engine.register_fn("address", |company: Company, address: String| -> Result<Company, Box<EvalAltResult>> { Ok(company.address(address)) });
engine.register_fn("business_type", |company: Company, business_type: BusinessType| -> Result<Company, Box<EvalAltResult>> { Ok(company.business_type(business_type)) });
engine.register_fn("industry", |company: Company, industry: String| -> Result<Company, Box<EvalAltResult>> { Ok(company.industry(industry)) });
engine.register_fn("description", |company: Company, description: String| -> Result<Company, Box<EvalAltResult>> { Ok(company.description(description)) });
engine.register_fn("status", |company: Company, status: CompanyStatus| -> Result<Company, Box<EvalAltResult>> { Ok(company.status(status)) });
engine.register_fn("set_base_created_at", |company: Company, created_at: i64| -> Result<Company, Box<EvalAltResult>> { Ok(company.set_base_created_at(created_at)) });
engine.register_fn("set_base_modified_at", |company: Company, modified_at: i64| -> Result<Company, Box<EvalAltResult>> { Ok(company.set_base_modified_at(modified_at)) });
// --- Enum Constants: ShareholderType ---
let mut shareholder_type_constants_module = Module::new();
shareholder_type_constants_module.set_var("Individual", Dynamic::from(ShareholderType::Individual.clone()));
shareholder_type_constants_module.set_var("Corporate", Dynamic::from(ShareholderType::Corporate.clone()));
engine.register_static_module("ShareholderTypeConstants", shareholder_type_constants_module.into());
engine.register_type_with_name::<ShareholderType>("ShareholderType");
// --- Shareholder ---
engine.register_type_with_name::<Shareholder>("Shareholder");
// Constructor for Shareholder (minimal, takes only ID)
engine.register_fn("new_shareholder", |id: i64| -> Result<Shareholder, Box<EvalAltResult>> {
Ok(Shareholder::new(id as u32))
});
// Getters for Shareholder
engine.register_get("id", |shareholder: &mut Shareholder| -> Result<i64, Box<EvalAltResult>> { Ok(shareholder.get_id() as i64) });
engine.register_get("created_at", |shareholder: &mut Shareholder| -> Result<i64, Box<EvalAltResult>> { Ok(shareholder.base_data.created_at) });
engine.register_get("modified_at", |shareholder: &mut Shareholder| -> Result<i64, Box<EvalAltResult>> { Ok(shareholder.base_data.modified_at) });
engine.register_get("company_id", |shareholder: &mut Shareholder| -> Result<i64, Box<EvalAltResult>> { Ok(shareholder.company_id as i64) });
engine.register_get("user_id", |shareholder: &mut Shareholder| -> Result<i64, Box<EvalAltResult>> { Ok(shareholder.user_id as i64) });
engine.register_get("name", |shareholder: &mut Shareholder| -> Result<String, Box<EvalAltResult>> { Ok(shareholder.name.clone()) });
engine.register_get("shares", |shareholder: &mut Shareholder| -> Result<f64, Box<EvalAltResult>> { Ok(shareholder.shares) });
engine.register_get("percentage", |shareholder: &mut Shareholder| -> Result<f64, Box<EvalAltResult>> { Ok(shareholder.percentage) });
engine.register_get("type_", |shareholder: &mut Shareholder| -> Result<ShareholderType, Box<EvalAltResult>> { Ok(shareholder.type_.clone()) });
engine.register_get("since", |shareholder: &mut Shareholder| -> Result<i64, Box<EvalAltResult>> { Ok(shareholder.since) });
// Builder methods for Shareholder
engine.register_fn("company_id", |shareholder: Shareholder, company_id: i64| -> Result<Shareholder, Box<EvalAltResult>> { Ok(shareholder.company_id(company_id as u32)) });
engine.register_fn("user_id", |shareholder: Shareholder, user_id: i64| -> Result<Shareholder, Box<EvalAltResult>> { Ok(shareholder.user_id(user_id as u32)) });
engine.register_fn("name", |shareholder: Shareholder, name: String| -> Result<Shareholder, Box<EvalAltResult>> { Ok(shareholder.name(name)) });
engine.register_fn("shares", |shareholder: Shareholder, shares: f64| -> Result<Shareholder, Box<EvalAltResult>> { Ok(shareholder.shares(shares)) });
engine.register_fn("percentage", |shareholder: Shareholder, percentage: f64| -> Result<Shareholder, Box<EvalAltResult>> { Ok(shareholder.percentage(percentage)) });
engine.register_fn("type_", |shareholder: Shareholder, type_: ShareholderType| -> Result<Shareholder, Box<EvalAltResult>> { Ok(shareholder.type_(type_)) });
engine.register_fn("since", |shareholder: Shareholder, since: i64| -> Result<Shareholder, Box<EvalAltResult>> { Ok(shareholder.since(since)) });
engine.register_fn("set_base_created_at", |shareholder: Shareholder, created_at: i64| -> Result<Shareholder, Box<EvalAltResult>> { Ok(shareholder.set_base_created_at(created_at)) });
engine.register_fn("set_base_modified_at", |shareholder: Shareholder, modified_at: i64| -> Result<Shareholder, Box<EvalAltResult>> { Ok(shareholder.set_base_modified_at(modified_at)) });
// --- Enum Constants: ProductType ---
let mut product_type_constants_module = Module::new();
product_type_constants_module.set_var("Product", Dynamic::from(ProductType::Product.clone()));
product_type_constants_module.set_var("Service", Dynamic::from(ProductType::Service.clone()));
engine.register_static_module("ProductTypeConstants", product_type_constants_module.into());
engine.register_type_with_name::<ProductType>("ProductType");
// --- Enum Constants: ProductStatus ---
let mut product_status_constants_module = Module::new();
product_status_constants_module.set_var("Available", Dynamic::from(ProductStatus::Available.clone()));
product_status_constants_module.set_var("Unavailable", Dynamic::from(ProductStatus::Unavailable.clone()));
engine.register_static_module("ProductStatusConstants", product_status_constants_module.into());
engine.register_type_with_name::<ProductStatus>("ProductStatus");
// --- Enum Constants: SaleStatus ---
let mut sale_status_module = Module::new();
sale_status_module.set_var("Pending", Dynamic::from(SaleStatus::Pending.clone()));
sale_status_module.set_var("Completed", Dynamic::from(SaleStatus::Completed.clone()));
sale_status_module.set_var("Cancelled", Dynamic::from(SaleStatus::Cancelled.clone()));
engine.register_static_module("SaleStatusConstants", sale_status_module.into());
engine.register_type_with_name::<SaleStatus>("SaleStatus");
// --- ProductComponent ---
engine.register_type_with_name::<ProductComponent>("ProductComponent")
.register_fn("new_product_component", |name: String| -> Result<ProductComponent, Box<EvalAltResult>> { Ok(ProductComponent::new(name)) })
.register_get("name", |pc: &mut ProductComponent| -> Result<String, Box<EvalAltResult>> { Ok(pc.name.clone()) })
.register_fn("name", |pc: ProductComponent, name: String| -> Result<ProductComponent, Box<EvalAltResult>> { Ok(pc.name(name)) })
.register_get("description", |pc: &mut ProductComponent| -> Result<String, Box<EvalAltResult>> { Ok(pc.description.clone()) })
.register_fn("description", |pc: ProductComponent, description: String| -> Result<ProductComponent, Box<EvalAltResult>> { Ok(pc.description(description)) })
.register_get("quantity", |pc: &mut ProductComponent| -> Result<i64, Box<EvalAltResult>> { Ok(pc.quantity as i64) })
.register_fn("quantity", |pc: ProductComponent, quantity: i64| -> Result<ProductComponent, Box<EvalAltResult>> { Ok(pc.quantity(quantity as u32)) });
// --- Product ---
engine.register_type_with_name::<Product>("Product")
.register_fn("new_product", |id: i64| -> Result<Product, Box<EvalAltResult>> { Ok(Product::new(id as u32)) })
// Getters for Product
.register_get("id", |p: &mut Product| -> Result<i64, Box<EvalAltResult>> { Ok(p.base_data.id as i64) })
.register_get("name", |p: &mut Product| -> Result<String, Box<EvalAltResult>> { Ok(p.name.clone()) })
.register_get("description", |p: &mut Product| -> Result<String, Box<EvalAltResult>> { Ok(p.description.clone()) })
.register_get("price", |p: &mut Product| -> Result<f64, Box<EvalAltResult>> { Ok(p.price) })
.register_get("type_", |p: &mut Product| -> Result<ProductType, Box<EvalAltResult>> { Ok(p.type_.clone()) })
.register_get("category", |p: &mut Product| -> Result<String, Box<EvalAltResult>> { Ok(p.category.clone()) })
.register_get("status", |p: &mut Product| -> Result<ProductStatus, Box<EvalAltResult>> { Ok(p.status.clone()) })
.register_get("max_amount", |p: &mut Product| -> Result<i64, Box<EvalAltResult>> { Ok(p.max_amount as i64) })
.register_get("purchase_till", |p: &mut Product| -> Result<i64, Box<EvalAltResult>> { Ok(p.purchase_till) })
.register_get("active_till", |p: &mut Product| -> Result<i64, Box<EvalAltResult>> { Ok(p.active_till) })
.register_get("components", |p: &mut Product| -> Result<rhai::Array, Box<EvalAltResult>> {
let rhai_array = p.components.iter().cloned().map(Dynamic::from).collect::<rhai::Array>();
Ok(rhai_array)
})
// Getters for BaseModelData fields
.register_get("created_at", |p: &mut Product| -> Result<i64, Box<EvalAltResult>> { Ok(p.base_data.created_at) })
.register_get("modified_at", |p: &mut Product| -> Result<i64, Box<EvalAltResult>> { Ok(p.base_data.modified_at) })
.register_get("comments", |p: &mut Product| -> Result<Vec<i64>, Box<EvalAltResult>> { Ok(p.base_data.comments.iter().map(|&id| id as i64).collect()) })
// Builder methods for Product
.register_fn("name", |p: Product, name: String| -> Result<Product, Box<EvalAltResult>> { Ok(p.name(name)) })
.register_fn("description", |p: Product, description: String| -> Result<Product, Box<EvalAltResult>> { Ok(p.description(description)) })
.register_fn("price", |p: Product, price: f64| -> Result<Product, Box<EvalAltResult>> { Ok(p.price(price)) })
.register_fn("type_", |p: Product, type_: ProductType| -> Result<Product, Box<EvalAltResult>> { Ok(p.type_(type_)) })
.register_fn("category", |p: Product, category: String| -> Result<Product, Box<EvalAltResult>> { Ok(p.category(category)) })
.register_fn("status", |p: Product, status: ProductStatus| -> Result<Product, Box<EvalAltResult>> { Ok(p.status(status)) })
.register_fn("max_amount", |p: Product, max_amount: i64| -> Result<Product, Box<EvalAltResult>> { Ok(p.max_amount(max_amount as u16)) })
.register_fn("purchase_till", |p: Product, purchase_till: i64| -> Result<Product, Box<EvalAltResult>> { Ok(p.purchase_till(purchase_till)) })
.register_fn("active_till", |p: Product, active_till: i64| -> Result<Product, Box<EvalAltResult>> { Ok(p.active_till(active_till)) })
.register_fn("add_component", |p: Product, component: ProductComponent| -> Result<Product, Box<EvalAltResult>> { Ok(p.add_component(component)) })
.register_fn("components", |p: Product, components: Vec<ProductComponent>| -> Result<Product, Box<EvalAltResult>> { Ok(p.components(components)) })
.register_fn("set_base_created_at", |p: Product, time: i64| -> Result<Product, Box<EvalAltResult>> { Ok(p.set_base_created_at(time)) })
.register_fn("set_base_modified_at", |p: Product, time: i64| -> Result<Product, Box<EvalAltResult>> { Ok(p.set_base_modified_at(time)) })
.register_fn("add_base_comment_id", |p: Product, comment_id: i64| -> Result<Product, Box<EvalAltResult>> { Ok(p.add_base_comment_id(id_from_i64(comment_id)?)) })
.register_fn("set_base_comment_ids", |p: Product, comment_ids: Vec<i64>| -> Result<Product, Box<EvalAltResult>> {
let u32_ids = comment_ids.into_iter().map(id_from_i64).collect::<Result<Vec<u32>, _>>()?;
Ok(p.set_base_comment_ids(u32_ids))
});
// --- SaleItem ---
engine.register_type_with_name::<SaleItem>("SaleItem");
engine.register_fn("new_sale_item", |product_id_i64: i64, name: String, quantity_i64: i64, unit_price: f64, subtotal: f64| -> Result<SaleItem, Box<EvalAltResult>> {
Ok(SaleItem::new(id_from_i64(product_id_i64)?, name, quantity_i64 as i32, unit_price, subtotal))
});
// Getters for SaleItem
engine.register_get("product_id", |si: &mut SaleItem| -> Result<i64, Box<EvalAltResult>> { Ok(si.product_id as i64) });
engine.register_get("name", |si: &mut SaleItem| -> Result<String, Box<EvalAltResult>> { Ok(si.name.clone()) });
engine.register_get("quantity", |si: &mut SaleItem| -> Result<i64, Box<EvalAltResult>> { Ok(si.quantity as i64) });
engine.register_get("unit_price", |si: &mut SaleItem| -> Result<f64, Box<EvalAltResult>> { Ok(si.unit_price) });
engine.register_get("subtotal", |si: &mut SaleItem| -> Result<f64, Box<EvalAltResult>> { Ok(si.subtotal) });
engine.register_get("service_active_until", |si: &mut SaleItem| -> Result<Option<i64>, Box<EvalAltResult>> { Ok(si.service_active_until) });
// Builder-style methods for SaleItem
engine.register_type_with_name::<SaleItem>("SaleItem")
.register_fn("product_id", |item: SaleItem, product_id_i64: i64| -> Result<SaleItem, Box<EvalAltResult>> { Ok(item.product_id(id_from_i64(product_id_i64)?)) })
.register_fn("name", |item: SaleItem, name: String| -> Result<SaleItem, Box<EvalAltResult>> { Ok(item.name(name)) })
.register_fn("quantity", |item: SaleItem, quantity_i64: i64| -> Result<SaleItem, Box<EvalAltResult>> { Ok(item.quantity(quantity_i64 as i32)) })
.register_fn("unit_price", |item: SaleItem, unit_price: f64| -> Result<SaleItem, Box<EvalAltResult>> { Ok(item.unit_price(unit_price)) })
.register_fn("subtotal", |item: SaleItem, subtotal: f64| -> Result<SaleItem, Box<EvalAltResult>> { Ok(item.subtotal(subtotal)) })
.register_fn("service_active_until", |item: SaleItem, until: Option<i64>| -> Result<SaleItem, Box<EvalAltResult>> { Ok(item.service_active_until(until)) });
// --- Sale ---
engine.register_type_with_name::<Sale>("Sale");
engine.register_fn("new_sale", |id_i64: i64, company_id_i64: i64, buyer_name: String, buyer_email: String, total_amount: f64, status: SaleStatus, sale_date: i64| -> Result<Sale, Box<EvalAltResult>> {
Ok(Sale::new(id_from_i64(id_i64)?, id_from_i64(company_id_i64)?, buyer_name, buyer_email, total_amount, status, sale_date))
});
// Getters for Sale
engine.register_get("id", |s: &mut Sale| -> Result<i64, Box<EvalAltResult>> { Ok(s.get_id() as i64) });
engine.register_get("customer_id", |s: &mut Sale| -> Result<i64, Box<EvalAltResult>> { Ok(s.company_id as i64) });
engine.register_get("buyer_name", |s: &mut Sale| -> Result<String, Box<EvalAltResult>> { Ok(s.buyer_name.clone()) });
engine.register_get("buyer_email", |s: &mut Sale| -> Result<String, Box<EvalAltResult>> { Ok(s.buyer_email.clone()) });
engine.register_get("total_amount", |s: &mut Sale| -> Result<f64, Box<EvalAltResult>> { Ok(s.total_amount) });
engine.register_get("status", |s: &mut Sale| -> Result<SaleStatus, Box<EvalAltResult>> { Ok(s.status.clone()) });
engine.register_get("sale_date", |s: &mut Sale| -> Result<i64, Box<EvalAltResult>> { Ok(s.sale_date) });
engine.register_get("items", |s: &mut Sale| -> Result<rhai::Array, Box<EvalAltResult>> {
Ok(s.items.iter().cloned().map(Dynamic::from).collect::<rhai::Array>())
});
engine.register_get("notes", |s: &mut Sale| -> Result<String, Box<EvalAltResult>> { Ok(s.notes.clone()) });
engine.register_get("created_at", |s: &mut Sale| -> Result<i64, Box<EvalAltResult>> { Ok(s.base_data.created_at) });
engine.register_get("modified_at", |s: &mut Sale| -> Result<i64, Box<EvalAltResult>> { Ok(s.base_data.modified_at) });
// engine.register_get("uuid", |s: &mut Sale| -> Result<Option<String>, Box<EvalAltResult>> { Ok(s.base_data().uuid.clone()) }); // UUID not in BaseModelData
engine.register_get("comments", |s: &mut Sale| -> Result<rhai::Array, Box<EvalAltResult>> {
Ok(s.base_data.comments.iter().map(|&id| Dynamic::from(id as i64)).collect::<rhai::Array>())
});
// Builder-style methods for Sale
engine.register_type_with_name::<Sale>("Sale")
.register_fn("customer_id", |s: Sale, customer_id_i64: i64| -> Result<Sale, Box<EvalAltResult>> { Ok(s.company_id(id_from_i64(customer_id_i64)?)) })
.register_fn("buyer_name", |s: Sale, buyer_name: String| -> Result<Sale, Box<EvalAltResult>> { Ok(s.buyer_name(buyer_name)) })
.register_fn("buyer_email", |s: Sale, buyer_email: String| -> Result<Sale, Box<EvalAltResult>> { Ok(s.buyer_email(buyer_email)) })
.register_fn("total_amount", |s: Sale, total_amount: f64| -> Result<Sale, Box<EvalAltResult>> { Ok(s.total_amount(total_amount)) })
.register_fn("status", |s: Sale, status: SaleStatus| -> Result<Sale, Box<EvalAltResult>> { Ok(s.status(status)) })
.register_fn("sale_date", |s: Sale, sale_date: i64| -> Result<Sale, Box<EvalAltResult>> { Ok(s.sale_date(sale_date)) })
.register_fn("add_item", |s: Sale, item: SaleItem| -> Result<Sale, Box<EvalAltResult>> { Ok(s.add_item(item)) })
.register_fn("items", |s: Sale, items: Vec<SaleItem>| -> Result<Sale, Box<EvalAltResult>> { Ok(s.items(items)) })
.register_fn("notes", |s: Sale, notes: String| -> Result<Sale, Box<EvalAltResult>> { Ok(s.notes(notes)) })
.register_fn("set_base_id", |s: Sale, id_i64: i64| -> Result<Sale, Box<EvalAltResult>> { Ok(s.set_base_id(id_from_i64(id_i64)?)) })
// .register_fn("set_base_uuid", |s: Sale, uuid: Option<String>| -> Result<Sale, Box<EvalAltResult>> { Ok(s.set_base_uuid(uuid)) }) // UUID not in BaseModelData
.register_fn("set_base_created_at", |s: Sale, time: i64| -> Result<Sale, Box<EvalAltResult>> { Ok(s.set_base_created_at(time)) })
.register_fn("set_base_modified_at", |s: Sale, time: i64| -> Result<Sale, Box<EvalAltResult>> { Ok(s.set_base_modified_at(time)) })
.register_fn("add_base_comment", |s: Sale, comment_id_i64: i64| -> Result<Sale, Box<EvalAltResult>> { Ok(s.add_base_comment(id_from_i64(comment_id_i64)?)) })
.register_fn("set_base_comments", |s: Sale, comment_ids: Vec<i64>| -> Result<Sale, Box<EvalAltResult>> {
let u32_ids = comment_ids.into_iter().map(id_from_i64).collect::<Result<Vec<u32>, _>>()?;
Ok(s.set_base_comments(u32_ids))
});
// DB functions for Product
let captured_db_for_set_prod = Arc::clone(&db);
engine.register_fn("set_product", move |product: Product| -> Result<(), Box<EvalAltResult>> {
captured_db_for_set_prod.set(&product).map_err(|e| {
Box::new(EvalAltResult::ErrorRuntime(format!("Failed to set Product (ID: {}): {}", product.get_id(), e).into(), Position::NONE))
})
});
let captured_db_for_get_prod = Arc::clone(&db);
engine.register_fn("get_product_by_id", move |id_i64: i64| -> Result<Product, Box<EvalAltResult>> {
let id_u32 = id_i64 as u32;
captured_db_for_get_prod.get_by_id(id_u32)
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("Error getting Product (ID: {}): {}", id_u32, e).into(), Position::NONE)))?
.ok_or_else(|| Box::new(EvalAltResult::ErrorRuntime(format!("Product with ID {} not found", id_u32).into(), Position::NONE)))
});
// DB functions for Sale
let captured_db_for_set_sale = Arc::clone(&db);
engine.register_fn("set_sale", move |sale: Sale| -> Result<(), Box<EvalAltResult>> {
captured_db_for_set_sale.set(&sale).map_err(|e| {
Box::new(EvalAltResult::ErrorRuntime(format!("Failed to set Sale (ID: {}): {}", sale.get_id(), e).into(), Position::NONE))
})
});
let captured_db_for_get_sale = Arc::clone(&db);
engine.register_fn("get_sale_by_id", move |id_i64: i64| -> Result<Sale, Box<EvalAltResult>> {
let id_u32 = id_from_i64(id_i64)?;
captured_db_for_get_sale.get_by_id(id_u32)
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("Error getting Sale (ID: {}): {}", id_u32, e).into(), Position::NONE)))?
.ok_or_else(|| Box::new(EvalAltResult::ErrorRuntime(format!("Sale with ID {} not found", id_u32).into(), Position::NONE)))
});
// Mock DB functions for Shareholder
let captured_db_for_set_sh = Arc::clone(&db);
engine.register_fn("set_shareholder", move |shareholder: Shareholder| -> Result<(), Box<EvalAltResult>> {
captured_db_for_set_sh.set(&shareholder).map_err(|e| {
Box::new(EvalAltResult::ErrorRuntime(format!("Failed to set Shareholder (ID: {}): {}", shareholder.get_id(), e).into(), Position::NONE))
})
});
let captured_db_for_get_sh = Arc::clone(&db);
engine.register_fn("get_shareholder_by_id", move |id_i64: i64| -> Result<Shareholder, Box<EvalAltResult>> {
let id_u32 = id_i64 as u32;
captured_db_for_get_sh.get_by_id(id_u32)
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("Error getting Shareholder (ID: {}): {}", id_u32, e).into(), Position::NONE)))?
.ok_or_else(|| Box::new(EvalAltResult::ErrorRuntime(format!("Shareholder with ID {} not found", id_u32).into(), Position::NONE)))
});
// Mock DB functions for Company
let captured_db_for_set = Arc::clone(&db);
engine.register_fn("set_company", move |company: Company| -> Result<(), Box<EvalAltResult>> {
captured_db_for_set.set(&company).map_err(|e| {
Box::new(EvalAltResult::ErrorRuntime(format!("Failed to set Company (ID: {}): {}", company.get_id(), e).into(), Position::NONE))
})
});
let captured_db_for_get = Arc::clone(&db);
engine.register_fn("get_company_by_id", move |id_i64: i64| -> Result<Company, Box<EvalAltResult>> {
let id_u32 = id_i64 as u32; // Assuming direct conversion is fine, or use a helper like in flow
captured_db_for_get.get_by_id(id_u32)
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("Error getting Company (ID: {}): {}", id_u32, e).into(), Position::NONE)))?
.ok_or_else(|| Box::new(EvalAltResult::ErrorRuntime(format!("Company with ID {} not found", id_u32).into(), Position::NONE)))
});
engine.register_global_module(module.into());
}