...
This commit is contained in:
parent
b37b9da8b5
commit
32f6d87454
207
herodb/src/models/biz/README.md
Normal file
207
herodb/src/models/biz/README.md
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
# Business Models
|
||||||
|
|
||||||
|
This directory contains the core business models used throughout the application for representing essential business objects like products, sales, and currency.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The business models are implemented as Rust structs and enums with serialization/deserialization support via Serde. These models implement the `SledModel` and `Storable` traits for persistence in the application's database layer.
|
||||||
|
|
||||||
|
## Model Relationships
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
||||||
|
│ Currency │◄────┤ Product │◄────┤ SaleItem │
|
||||||
|
└─────────────┘ └─────────────┘ └──────┬──────┘
|
||||||
|
▲ │
|
||||||
|
│ │
|
||||||
|
┌─────┴───────┐ │
|
||||||
|
│ProductComponent│ │
|
||||||
|
└─────────────┘ │
|
||||||
|
▼
|
||||||
|
┌─────────────┐
|
||||||
|
│ Sale │
|
||||||
|
└─────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
## Models
|
||||||
|
|
||||||
|
### Currency (Root Object)
|
||||||
|
|
||||||
|
Represents a monetary value with an amount and currency code.
|
||||||
|
|
||||||
|
**Properties:**
|
||||||
|
- `amount`: f64 - The monetary amount
|
||||||
|
- `currency_code`: String - The currency code (e.g., "USD", "EUR")
|
||||||
|
|
||||||
|
**Methods:**
|
||||||
|
- `new()` - Creates a new Currency instance
|
||||||
|
|
||||||
|
### Product
|
||||||
|
|
||||||
|
#### ProductType Enum
|
||||||
|
Categorizes products:
|
||||||
|
- `Product` - Physical product
|
||||||
|
- `Service` - Non-physical service
|
||||||
|
|
||||||
|
#### ProductStatus Enum
|
||||||
|
Tracks product availability:
|
||||||
|
- `Available` - Product can be purchased
|
||||||
|
- `Unavailable` - Product cannot be purchased
|
||||||
|
|
||||||
|
#### ProductComponent
|
||||||
|
Represents a component part of a product.
|
||||||
|
|
||||||
|
**Properties:**
|
||||||
|
- `id`: u32 - Unique identifier
|
||||||
|
- `name`: String - Component name
|
||||||
|
- `description`: String - Component description
|
||||||
|
- `quantity`: i32 - Number of this component
|
||||||
|
- `created_at`: DateTime<Utc> - Creation timestamp
|
||||||
|
- `updated_at`: DateTime<Utc> - Last update timestamp
|
||||||
|
|
||||||
|
**Methods:**
|
||||||
|
- `new()` - Creates a new ProductComponent with default timestamps
|
||||||
|
|
||||||
|
#### Product (Root Object)
|
||||||
|
Represents a product or service offered.
|
||||||
|
|
||||||
|
**Properties:**
|
||||||
|
- `id`: u32 - Unique identifier
|
||||||
|
- `name`: String - Product name
|
||||||
|
- `description`: String - Product description
|
||||||
|
- `price`: Currency - Product price
|
||||||
|
- `type_`: ProductType - Product or Service
|
||||||
|
- `category`: String - Product category
|
||||||
|
- `status`: ProductStatus - Available or Unavailable
|
||||||
|
- `created_at`: DateTime<Utc> - Creation timestamp
|
||||||
|
- `updated_at`: DateTime<Utc> - Last update timestamp
|
||||||
|
- `max_amount`: u16 - Maximum quantity available
|
||||||
|
- `purchase_till`: DateTime<Utc> - Deadline for purchasing
|
||||||
|
- `active_till`: DateTime<Utc> - When product/service expires
|
||||||
|
- `components`: Vec<ProductComponent> - List of product components
|
||||||
|
|
||||||
|
**Methods:**
|
||||||
|
- `new()` - Creates a new Product with default timestamps
|
||||||
|
- `add_component()` - Adds a component to this product
|
||||||
|
- `set_purchase_period()` - Updates purchase availability timeframe
|
||||||
|
- `set_active_period()` - Updates active timeframe
|
||||||
|
- `is_purchasable()` - Checks if product is available for purchase
|
||||||
|
- `is_active()` - Checks if product is still active
|
||||||
|
|
||||||
|
**Database Implementation:**
|
||||||
|
- Implements `Storable` trait for serialization
|
||||||
|
- Implements `SledModel` trait with:
|
||||||
|
- `get_id()` - Returns the ID as a string
|
||||||
|
- `db_prefix()` - Returns "product" as the database prefix
|
||||||
|
|
||||||
|
### Sale
|
||||||
|
|
||||||
|
#### SaleStatus Enum
|
||||||
|
Tracks the status of a sale:
|
||||||
|
- `Pending` - Sale is in progress
|
||||||
|
- `Completed` - Sale has been finalized
|
||||||
|
- `Cancelled` - Sale has been cancelled
|
||||||
|
|
||||||
|
#### SaleItem
|
||||||
|
Represents an item within a sale.
|
||||||
|
|
||||||
|
**Properties:**
|
||||||
|
- `id`: u32 - Unique identifier
|
||||||
|
- `sale_id`: u32 - Parent sale ID
|
||||||
|
- `product_id`: u32 - ID of the product sold
|
||||||
|
- `name`: String - Product name at time of sale
|
||||||
|
- `quantity`: i32 - Number of items purchased
|
||||||
|
- `unit_price`: Currency - Price per unit
|
||||||
|
- `subtotal`: Currency - Total price for this item (calculated)
|
||||||
|
- `active_till`: DateTime<Utc> - When item/service expires
|
||||||
|
|
||||||
|
**Methods:**
|
||||||
|
- `new()` - Creates a new SaleItem with calculated subtotal
|
||||||
|
|
||||||
|
#### Sale (Root Object)
|
||||||
|
Represents a complete sale transaction.
|
||||||
|
|
||||||
|
**Properties:**
|
||||||
|
- `id`: u32 - Unique identifier
|
||||||
|
- `company_id`: u32 - ID of the company making the sale
|
||||||
|
- `buyer_name`: String - Name of the buyer
|
||||||
|
- `buyer_email`: String - Email of the buyer
|
||||||
|
- `total_amount`: Currency - Total sale amount
|
||||||
|
- `status`: SaleStatus - Current sale status
|
||||||
|
- `sale_date`: DateTime<Utc> - When sale occurred
|
||||||
|
- `created_at`: DateTime<Utc> - Creation timestamp
|
||||||
|
- `updated_at`: DateTime<Utc> - Last update timestamp
|
||||||
|
- `items`: Vec<SaleItem> - List of items in the sale
|
||||||
|
|
||||||
|
**Methods:**
|
||||||
|
- `new()` - Creates a new Sale with default timestamps
|
||||||
|
- `add_item()` - Adds an item to the sale and updates total
|
||||||
|
- `update_status()` - Updates the status of the sale
|
||||||
|
|
||||||
|
**Database Implementation:**
|
||||||
|
- Implements `Storable` trait for serialization
|
||||||
|
- Implements `SledModel` trait with:
|
||||||
|
- `get_id()` - Returns the ID as a string
|
||||||
|
- `db_prefix()` - Returns "sale" as the database prefix
|
||||||
|
|
||||||
|
## Usage Examples
|
||||||
|
|
||||||
|
### Creating a Product
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// Create a currency
|
||||||
|
let price = Currency::new(29.99, "USD".to_string());
|
||||||
|
|
||||||
|
// Create a product
|
||||||
|
let mut product = Product::new(
|
||||||
|
1, // id
|
||||||
|
"Premium Service".to_string(), // name
|
||||||
|
"Our premium service offering".to_string(), // description
|
||||||
|
price, // price
|
||||||
|
ProductType::Service, // type
|
||||||
|
"Services".to_string(), // category
|
||||||
|
ProductStatus::Available, // status
|
||||||
|
100, // max_amount
|
||||||
|
30, // validity_days (service valid for 30 days)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Add a component
|
||||||
|
let component = ProductComponent::new(
|
||||||
|
1, // id
|
||||||
|
"Basic Support".to_string(), // name
|
||||||
|
"24/7 email support".to_string(), // description
|
||||||
|
1, // quantity
|
||||||
|
);
|
||||||
|
product.add_component(component);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Creating a Sale
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// Create a new sale
|
||||||
|
let mut sale = Sale::new(
|
||||||
|
1, // id
|
||||||
|
101, // company_id
|
||||||
|
"John Doe".to_string(), // buyer_name
|
||||||
|
"john.doe@example.com".to_string(), // buyer_email
|
||||||
|
"USD".to_string(), // currency_code
|
||||||
|
SaleStatus::Pending, // status
|
||||||
|
);
|
||||||
|
|
||||||
|
// Create a sale item
|
||||||
|
let now = Utc::now();
|
||||||
|
let item = SaleItem::new(
|
||||||
|
1, // id
|
||||||
|
1, // sale_id
|
||||||
|
1, // product_id
|
||||||
|
"Premium Service".to_string(), // name
|
||||||
|
1, // quantity
|
||||||
|
Currency::new(29.99, "USD".to_string()), // unit_price
|
||||||
|
now + Duration::days(30), // active_till
|
||||||
|
);
|
||||||
|
|
||||||
|
// Add the item to the sale
|
||||||
|
sale.add_item(item);
|
||||||
|
|
||||||
|
// Complete the sale
|
||||||
|
sale.update_status(SaleStatus::Completed);
|
20
herodb/src/models/biz/currency.rs
Normal file
20
herodb/src/models/biz/currency.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
use chrono::{DateTime, Utc, Duration};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use crate::core::{SledModel, Storable}; // Import Sled traits from new location
|
||||||
|
|
||||||
|
/// Currency represents a monetary value with amount and currency code
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct Currency {
|
||||||
|
pub amount: f64,
|
||||||
|
pub currency_code: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Currency {
|
||||||
|
/// Create a new currency with amount and code
|
||||||
|
pub fn new(amount: f64, currency_code: String) -> Self {
|
||||||
|
Self {
|
||||||
|
amount,
|
||||||
|
currency_code,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,22 +2,6 @@ use chrono::{DateTime, Utc, Duration};
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use crate::core::{SledModel, Storable}; // Import Sled traits from new location
|
use crate::core::{SledModel, Storable}; // Import Sled traits from new location
|
||||||
|
|
||||||
/// Currency represents a monetary value with amount and currency code
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
pub struct Currency {
|
|
||||||
pub amount: f64,
|
|
||||||
pub currency_code: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Currency {
|
|
||||||
/// Create a new currency with amount and code
|
|
||||||
pub fn new(amount: f64, currency_code: String) -> Self {
|
|
||||||
Self {
|
|
||||||
amount,
|
|
||||||
currency_code,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ProductType represents the type of a product
|
/// ProductType represents the type of a product
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
@ -1,199 +0,0 @@
|
|||||||
//! Examples demonstrating how to use the new DB implementation
|
|
||||||
|
|
||||||
// Core DB is now imported via the factory
|
|
||||||
use crate::zaz::models::*;
|
|
||||||
use crate::zaz::models::shareholder::ShareholderType;
|
|
||||||
use crate::zaz::factory::create_zaz_db;
|
|
||||||
use crate::zaz::rhai::{initialize_rhai_engine, run_script_file, run_example_script};
|
|
||||||
use rhai::{Engine, EvalAltResult};
|
|
||||||
use std::path::PathBuf;
|
|
||||||
use std::fs;
|
|
||||||
use chrono::Utc;
|
|
||||||
|
|
||||||
/// Creates a simple temporary directory
|
|
||||||
fn create_temp_dir() -> std::io::Result<PathBuf> {
|
|
||||||
let temp_dir = std::env::temp_dir();
|
|
||||||
let random_name = format!("db-example-{}", std::time::SystemTime::now()
|
|
||||||
.duration_since(std::time::UNIX_EPOCH)
|
|
||||||
.unwrap()
|
|
||||||
.as_millis());
|
|
||||||
let path = temp_dir.join(random_name);
|
|
||||||
fs::create_dir_all(&path)?;
|
|
||||||
Ok(path)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Example demonstrating basic CRUD operations with the DB
|
|
||||||
pub fn run_db_examples() -> Result<(), String> {
|
|
||||||
println!("Running DB examples...");
|
|
||||||
|
|
||||||
// Create a temporary directory for the DB (or use a permanent one)
|
|
||||||
let db_path = create_temp_dir().map_err(|e| format!("Failed to create temp dir: {}", e))?;
|
|
||||||
println!("Using DB path: {:?}", db_path);
|
|
||||||
|
|
||||||
// Create a DB instance
|
|
||||||
let db = create_zaz_db(db_path).map_err(|e| format!("Failed to create DB: {}", e))?;
|
|
||||||
|
|
||||||
// --- User Example ---
|
|
||||||
println!("\nRunning User example:");
|
|
||||||
let user = User::new(
|
|
||||||
1,
|
|
||||||
"John Doe".to_string(),
|
|
||||||
"john@example.com".to_string(),
|
|
||||||
"password123".to_string(),
|
|
||||||
"ACME Corp".to_string(),
|
|
||||||
"Admin".to_string(),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Insert user
|
|
||||||
db.set(&user).map_err(|e| format!("Failed to insert user: {}", e))?;
|
|
||||||
println!("Inserted user: {}", user.name);
|
|
||||||
|
|
||||||
// Get user
|
|
||||||
let retrieved_user: User = db.get(&user.id.to_string())
|
|
||||||
.map_err(|e| format!("Failed to get user: {}", e))?;
|
|
||||||
println!("Retrieved user: {} ({})", retrieved_user.name, retrieved_user.email);
|
|
||||||
|
|
||||||
// --- Company Example ---
|
|
||||||
println!("\nRunning Company example:");
|
|
||||||
let company = Company::new(
|
|
||||||
1,
|
|
||||||
"ACME Corporation".to_string(),
|
|
||||||
"REG12345".to_string(),
|
|
||||||
Utc::now(),
|
|
||||||
"12-31".to_string(),
|
|
||||||
"info@acme.com".to_string(),
|
|
||||||
"555-123-4567".to_string(),
|
|
||||||
"www.acme.com".to_string(),
|
|
||||||
"123 Main St, Metropolis".to_string(),
|
|
||||||
BusinessType::Global,
|
|
||||||
"Technology".to_string(),
|
|
||||||
"A leading technology company".to_string(),
|
|
||||||
CompanyStatus::Active,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Insert company
|
|
||||||
db.set(&company).map_err(|e| format!("Failed to insert company: {}", e))?;
|
|
||||||
println!("Inserted company: {}", company.name);
|
|
||||||
|
|
||||||
// Get company
|
|
||||||
let retrieved_company: Company = db.get(&company.id.to_string())
|
|
||||||
.map_err(|e| format!("Failed to get company: {}", e))?;
|
|
||||||
println!("Retrieved company: {} ({})", retrieved_company.name, retrieved_company.registration_number);
|
|
||||||
|
|
||||||
// --- Shareholder Example ---
|
|
||||||
println!("\nRunning Shareholder example:");
|
|
||||||
// Create the shareholder directly
|
|
||||||
let shareholder = Shareholder {
|
|
||||||
id: 1,
|
|
||||||
company_id: company.id,
|
|
||||||
user_id: user.id,
|
|
||||||
name: "John Doe".to_string(),
|
|
||||||
shares: 1000.0,
|
|
||||||
percentage: 25.0,
|
|
||||||
type_: ShareholderType::Individual, // Use the shared enum via re-export
|
|
||||||
since: Utc::now(),
|
|
||||||
created_at: Utc::now(),
|
|
||||||
updated_at: Utc::now(),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Insert shareholder
|
|
||||||
db.set(&shareholder).map_err(|e| format!("Failed to insert shareholder: {}", e))?;
|
|
||||||
println!("Inserted shareholder: {} ({}%)", shareholder.name, shareholder.percentage);
|
|
||||||
|
|
||||||
// Get shareholder
|
|
||||||
let retrieved_shareholder: Shareholder = db.get(&shareholder.id.to_string())
|
|
||||||
.map_err(|e| format!("Failed to get shareholder: {}", e))?;
|
|
||||||
println!("Retrieved shareholder: {} ({} shares)", retrieved_shareholder.name, retrieved_shareholder.shares);
|
|
||||||
|
|
||||||
// --- List Example ---
|
|
||||||
println!("\nListing all entities:");
|
|
||||||
|
|
||||||
let users: Vec<User> = db.list().map_err(|e| format!("Failed to list users: {}", e))?;
|
|
||||||
println!("Found {} users", users.len());
|
|
||||||
for user in &users {
|
|
||||||
println!("- User: {}", user.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
let companies: Vec<Company> = db.list().map_err(|e| format!("Failed to list companies: {}", e))?;
|
|
||||||
println!("Found {} companies", companies.len());
|
|
||||||
for company in &companies {
|
|
||||||
println!("- Company: {}", company.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
let shareholders: Vec<Shareholder> = db.list()
|
|
||||||
.map_err(|e| format!("Failed to list shareholders: {}", e))?;
|
|
||||||
println!("Found {} shareholders", shareholders.len());
|
|
||||||
for shareholder in &shareholders {
|
|
||||||
println!("- Shareholder: {} ({}%)", shareholder.name, shareholder.percentage);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- Delete Example ---
|
|
||||||
println!("\nDeleting entities:");
|
|
||||||
|
|
||||||
// Delete shareholder
|
|
||||||
db.delete::<Shareholder>(&shareholder.id.to_string())
|
|
||||||
.map_err(|e| format!("Failed to delete shareholder: {}", e))?;
|
|
||||||
println!("Deleted shareholder: {}", shareholder.name);
|
|
||||||
|
|
||||||
// Delete company
|
|
||||||
db.delete::<Company>(&company.id.to_string())
|
|
||||||
.map_err(|e| format!("Failed to delete company: {}", e))?;
|
|
||||||
println!("Deleted company: {}", company.name);
|
|
||||||
|
|
||||||
// Delete user
|
|
||||||
db.delete::<User>(&user.id.to_string())
|
|
||||||
.map_err(|e| format!("Failed to delete user: {}", e))?;
|
|
||||||
println!("Deleted user: {}", user.name);
|
|
||||||
|
|
||||||
// Verify deletion
|
|
||||||
let users_after_delete: Vec<User> = db.list()
|
|
||||||
.map_err(|e| format!("Failed to list users after delete: {}", e))?;
|
|
||||||
println!("Users remaining: {}", users_after_delete.len());
|
|
||||||
|
|
||||||
let companies_after_delete: Vec<Company> = db.list()
|
|
||||||
.map_err(|e| format!("Failed to list companies after delete: {}", e))?;
|
|
||||||
println!("Companies remaining: {}", companies_after_delete.len());
|
|
||||||
|
|
||||||
let shareholders_after_delete: Vec<Shareholder> = db.list()
|
|
||||||
.map_err(|e| format!("Failed to list shareholders after delete: {}", e))?;
|
|
||||||
println!("Shareholders remaining: {}", shareholders_after_delete.len());
|
|
||||||
|
|
||||||
println!("\nDB examples completed successfully!");
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Example demonstrating how to use Rhai scripts with models
|
|
||||||
pub fn run_rhai_examples() -> Result<(), String> {
|
|
||||||
println!("Running Rhai examples...");
|
|
||||||
|
|
||||||
// Run the test script that demonstrates using the model wrappers
|
|
||||||
// without database operations
|
|
||||||
let script_path = "src/zaz/rhai/test.rhai";
|
|
||||||
run_script_file(script_path)?;
|
|
||||||
|
|
||||||
// Run an example that demonstrates creating model objects
|
|
||||||
let temp_dir = create_temp_dir().map_err(|e| format!("Failed to create temp dir: {}", e))?;
|
|
||||||
println!("Using DB path for Rhai example: {:?}", temp_dir);
|
|
||||||
|
|
||||||
// Run the example script that uses the DB
|
|
||||||
run_example_script(temp_dir.to_str().unwrap())?;
|
|
||||||
|
|
||||||
println!("Rhai examples completed successfully!");
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Run a complete demonstration of Rhai integration with our models
|
|
||||||
pub fn run_rhai_demo() -> Result<(), String> {
|
|
||||||
println!("=====================================================");
|
|
||||||
println!("Starting Rhai demos for Zaz DB");
|
|
||||||
println!("=====================================================");
|
|
||||||
|
|
||||||
// Run the Rhai examples
|
|
||||||
run_rhai_examples()?;
|
|
||||||
|
|
||||||
println!("=====================================================");
|
|
||||||
println!("Rhai demo completed");
|
|
||||||
println!("=====================================================");
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
//! Command line examples and utilities for the zaz module
|
|
||||||
|
|
||||||
pub mod examples;
|
|
@ -1,22 +0,0 @@
|
|||||||
// Declare the models submodule
|
|
||||||
#[path = "models/lib.rs"] // Tell compiler where to find models module source
|
|
||||||
pub mod models;
|
|
||||||
|
|
||||||
// Add a factory module for DB creation
|
|
||||||
mod factory;
|
|
||||||
pub use factory::create_zaz_db;
|
|
||||||
|
|
||||||
// Expose the rhai module with wrappers
|
|
||||||
pub mod rhai;
|
|
||||||
pub use rhai::initialize_rhai_engine;
|
|
||||||
|
|
||||||
// Declare the examples module for the new DB implementation
|
|
||||||
#[path = "examples.rs"] // Tell compiler where to find the examples module
|
|
||||||
pub mod examples;
|
|
||||||
|
|
||||||
// Expose the cmd module
|
|
||||||
pub mod cmd;
|
|
||||||
|
|
||||||
// Include tests module when running tests
|
|
||||||
#[cfg(test)]
|
|
||||||
pub mod tests;
|
|
@ -1,13 +0,0 @@
|
|||||||
// Export all rhai wrapper modules
|
|
||||||
mod engine;
|
|
||||||
mod user;
|
|
||||||
mod company;
|
|
||||||
mod shareholder;
|
|
||||||
|
|
||||||
// Re-export key components
|
|
||||||
pub use engine::{create_rhai_engine, run_script_file, run_example_script};
|
|
||||||
|
|
||||||
// Public API
|
|
||||||
pub fn initialize_rhai_engine() -> rhai::Engine {
|
|
||||||
create_rhai_engine()
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
//! Simple binary to demonstrate Rhai wrapper functionality
|
|
||||||
|
|
||||||
use crate::zaz::cmd::examples::run_rhai_demo;
|
|
||||||
|
|
||||||
fn main() -> Result<(), String> {
|
|
||||||
println!("Running Rhai wrapper examples...");
|
|
||||||
run_rhai_demo()
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user