initial commit
This commit is contained in:
101
core/engine/examples/calendar/calendar_script.rhai
Normal file
101
core/engine/examples/calendar/calendar_script.rhai
Normal file
@@ -0,0 +1,101 @@
|
||||
// calendar_script.rhai
|
||||
// Example Rhai script for working with Calendar models
|
||||
|
||||
// Constants for AttendanceStatus
|
||||
const NO_RESPONSE = "NoResponse";
|
||||
const ACCEPTED = "Accepted";
|
||||
const DECLINED = "Declined";
|
||||
const TENTATIVE = "Tentative";
|
||||
|
||||
// Create a new calendar using builder pattern
|
||||
let my_calendar = new_calendar()
|
||||
.name("Team Calendar")
|
||||
.description("Calendar for team events and meetings");
|
||||
|
||||
print(`Created calendar: ${my_calendar.name} (${my_calendar.id})`);
|
||||
|
||||
|
||||
// Add attendees to the event
|
||||
let alice = new_attendee()
|
||||
.with_contact_id(1)
|
||||
.with_status(NO_RESPONSE);
|
||||
let bob = new_attendee()
|
||||
.with_contact_id(2)
|
||||
.with_status(ACCEPTED);
|
||||
let charlie = new_attendee()
|
||||
.with_contact_id(3)
|
||||
.with_status(TENTATIVE);
|
||||
|
||||
|
||||
// Create a new event using builder pattern
|
||||
// Note: Timestamps are in seconds since epoch
|
||||
let now = timestamp_now();
|
||||
let one_hour = 60 * 60;
|
||||
let meeting = new_event()
|
||||
.title("Weekly Sync")
|
||||
.reschedule(now, now + one_hour)
|
||||
.location("Conference Room A")
|
||||
.description("Regular team sync meeting")
|
||||
.add_attendee(alice)
|
||||
.add_attendee(bob)
|
||||
.add_attendee(charlie)
|
||||
.save_event();
|
||||
|
||||
print(`Created event: ${meeting.title}`);
|
||||
|
||||
meeting.delete_event();
|
||||
|
||||
print(`Deleted event: ${meeting.title}`);
|
||||
|
||||
// Print attendees info
|
||||
let attendees = meeting.attendees;
|
||||
print(`Added attendees to the event`);
|
||||
|
||||
// Update Charlie's attendee status directly
|
||||
meeting.update_attendee_status(3, ACCEPTED);
|
||||
print(`Updated Charlie's status to: ${ACCEPTED}`);
|
||||
|
||||
// Add the event to the calendar
|
||||
my_calendar.add_event_to_calendar(meeting);
|
||||
// Print events info
|
||||
print(`Added event to calendar`);
|
||||
|
||||
// Save the calendar to the database
|
||||
let saved_calendar = my_calendar.save_calendar();
|
||||
print(`Calendar saved to database with ID: ${saved_calendar.id}`);
|
||||
|
||||
// Retrieve the calendar from the database using the ID from the saved calendar
|
||||
let retrieved_calendar = get_calendar_by_id(saved_calendar.id);
|
||||
if retrieved_calendar != () {
|
||||
print(`Retrieved calendar: ${retrieved_calendar.name}`);
|
||||
print(`Retrieved calendar successfully`);
|
||||
} else {
|
||||
print("Failed to retrieve calendar from database");
|
||||
}
|
||||
|
||||
// List all calendars in the database
|
||||
let all_calendars = list_calendars();
|
||||
print("\nListing all calendars in database:");
|
||||
let calendar_count = 0;
|
||||
for calendar in all_calendars {
|
||||
print(` - Calendar: ${calendar.name} (ID: ${calendar.id})`);
|
||||
calendar_count += 1;
|
||||
}
|
||||
print(`Total calendars: ${calendar_count}`);
|
||||
|
||||
// List all events in the database
|
||||
let all_events = list_events();
|
||||
print("\nListing all events in database:");
|
||||
let event_count = 0;
|
||||
for event in all_events {
|
||||
print(` - Event: ${event.title} (ID: ${event.id})`);
|
||||
event_count += 1;
|
||||
}
|
||||
print(`Total events: ${event_count}`);
|
||||
|
||||
// Helper function to get current timestamp
|
||||
fn timestamp_now() {
|
||||
// This would typically be provided by the host application
|
||||
// For this example, we'll use a fixed timestamp
|
||||
1685620800 // June 1, 2023, 12:00 PM
|
||||
}
|
70
core/engine/examples/calendar/example.rs
Normal file
70
core/engine/examples/calendar/example.rs
Normal file
@@ -0,0 +1,70 @@
|
||||
use engine::mock_db::create_mock_db;
|
||||
use engine::{create_heromodels_engine, eval_file};
|
||||
use rhai::Engine;
|
||||
|
||||
mod mock;
|
||||
use mock::seed_calendar_data;
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("Calendar Rhai Example");
|
||||
println!("=====================");
|
||||
|
||||
// Create a mock database
|
||||
let db = create_mock_db();
|
||||
|
||||
// Seed the database with some initial data
|
||||
seed_calendar_data(db.clone());
|
||||
|
||||
// Create the Rhai engine using our central engine creator
|
||||
let mut engine = create_heromodels_engine(db.clone());
|
||||
|
||||
// Register timestamp helper functions
|
||||
register_timestamp_helpers(&mut engine);
|
||||
|
||||
// Get the path to the script
|
||||
let manifest_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
let script_path = manifest_dir
|
||||
.join("examples")
|
||||
.join("calendar")
|
||||
.join("calendar_script.rhai");
|
||||
|
||||
println!("\nRunning script: {}", script_path.display());
|
||||
println!("---------------------");
|
||||
|
||||
// Run the script
|
||||
match eval_file(&engine, &script_path) {
|
||||
Ok(result) => {
|
||||
if !result.is_unit() {
|
||||
println!("\nScript returned: {:?}", result);
|
||||
}
|
||||
println!("\nScript executed successfully!");
|
||||
Ok(())
|
||||
}
|
||||
Err(err) => {
|
||||
eprintln!("\nError running script: {}", err);
|
||||
Err(Box::new(std::io::Error::new(
|
||||
std::io::ErrorKind::Other,
|
||||
err.to_string(),
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Register timestamp helper functions with the engine
|
||||
fn register_timestamp_helpers(engine: &mut Engine) {
|
||||
use chrono::{TimeZone, Utc};
|
||||
|
||||
// Function to get current timestamp
|
||||
engine.register_fn("timestamp_now", || Utc::now().timestamp() as i64);
|
||||
|
||||
// Function to format a timestamp
|
||||
engine.register_fn("format_timestamp", |ts: i64| {
|
||||
let dt = Utc
|
||||
.timestamp_opt(ts, 0)
|
||||
.single()
|
||||
.expect("Invalid timestamp");
|
||||
dt.format("%Y-%m-%d %H:%M:%S UTC").to_string()
|
||||
});
|
||||
|
||||
println!("Timestamp helper functions registered successfully.");
|
||||
}
|
60
core/engine/examples/calendar/mock.rs
Normal file
60
core/engine/examples/calendar/mock.rs
Normal file
@@ -0,0 +1,60 @@
|
||||
use chrono::Utc;
|
||||
use heromodels::db::hero::OurDB;
|
||||
use heromodels::db::{Collection, Db};
|
||||
use heromodels::models::calendar::{Calendar, Event};
|
||||
use heromodels_core::Model;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// Seed the mock database with calendar data
|
||||
pub fn seed_calendar_data(db: Arc<OurDB>) {
|
||||
// Create a calendar
|
||||
let calendar = Calendar::new(None, "Work Calendar".to_string())
|
||||
.description("My work schedule".to_string());
|
||||
|
||||
// Store the calendar in the database
|
||||
let (calendar_id, mut saved_calendar) = db
|
||||
.collection::<Calendar>()
|
||||
.expect("Failed to get Calendar collection")
|
||||
.set(&calendar)
|
||||
.expect("Failed to store calendar");
|
||||
|
||||
// Create an event
|
||||
let now = Utc::now().timestamp();
|
||||
let end_time = now + 3600; // Add 1 hour in seconds
|
||||
|
||||
let event = Event::new()
|
||||
.title("Team Meeting".to_string())
|
||||
.reschedule(now, end_time)
|
||||
.location("Conference Room A".to_string())
|
||||
.description("Weekly sync".to_string())
|
||||
.build();
|
||||
|
||||
// Store the event in the database first to get its ID
|
||||
let (event_id, saved_event) = db
|
||||
.collection()
|
||||
.expect("Failed to get Event collection")
|
||||
.set(&event)
|
||||
.expect("Failed to store event");
|
||||
|
||||
// Add the event ID to the calendar
|
||||
saved_calendar = saved_calendar.add_event(event_id as i64);
|
||||
|
||||
// Store the updated calendar in the database
|
||||
let (_calendar_id, final_calendar) = db
|
||||
.collection::<Calendar>()
|
||||
.expect("Failed to get Calendar collection")
|
||||
.set(&saved_calendar)
|
||||
.expect("Failed to store calendar");
|
||||
|
||||
println!("Mock database seeded with calendar data:");
|
||||
println!(
|
||||
" - Added calendar: {} (ID: {})",
|
||||
final_calendar.name,
|
||||
final_calendar.get_id()
|
||||
);
|
||||
println!(
|
||||
" - Added event: {} (ID: {})",
|
||||
saved_event.title,
|
||||
saved_event.get_id()
|
||||
);
|
||||
}
|
70
core/engine/examples/finance/example.rs
Normal file
70
core/engine/examples/finance/example.rs
Normal file
@@ -0,0 +1,70 @@
|
||||
use engine::mock_db::create_mock_db;
|
||||
use engine::{create_heromodels_engine, eval_file};
|
||||
use rhai::Engine;
|
||||
use std::path::Path;
|
||||
|
||||
mod mock;
|
||||
use mock::seed_finance_data;
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("Finance Rhai Example");
|
||||
println!("===================");
|
||||
|
||||
// Create a mock database
|
||||
let db = create_mock_db();
|
||||
|
||||
// Seed the database with some initial data
|
||||
seed_finance_data(db.clone());
|
||||
|
||||
// Create the Rhai engine using our central engine creator
|
||||
let mut engine = create_heromodels_engine(db.clone());
|
||||
|
||||
// Register timestamp helper functions
|
||||
register_timestamp_helpers(&mut engine);
|
||||
|
||||
// Get the path to the script
|
||||
let script_path = Path::new(file!())
|
||||
.parent()
|
||||
.unwrap()
|
||||
.join("finance_script.rhai");
|
||||
|
||||
println!("\nRunning script: {}", script_path.display());
|
||||
println!("---------------------");
|
||||
|
||||
// Run the script
|
||||
match eval_file(&engine, &script_path) {
|
||||
Ok(result) => {
|
||||
if !result.is_unit() {
|
||||
println!("\nScript returned: {:?}", result);
|
||||
}
|
||||
println!("\nScript executed successfully!");
|
||||
Ok(())
|
||||
}
|
||||
Err(err) => {
|
||||
eprintln!("\nError running script: {}", err);
|
||||
Err(Box::new(std::io::Error::new(
|
||||
std::io::ErrorKind::Other,
|
||||
err.to_string(),
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Register timestamp helper functions with the engine
|
||||
fn register_timestamp_helpers(engine: &mut Engine) {
|
||||
use chrono::{TimeZone, Utc};
|
||||
|
||||
// Function to get current timestamp
|
||||
engine.register_fn("timestamp_now", || Utc::now().timestamp() as i64);
|
||||
|
||||
// Function to format a timestamp
|
||||
engine.register_fn("format_timestamp", |ts: i64| {
|
||||
let dt = Utc
|
||||
.timestamp_opt(ts, 0)
|
||||
.single()
|
||||
.expect("Invalid timestamp");
|
||||
dt.format("%Y-%m-%d %H:%M:%S UTC").to_string()
|
||||
});
|
||||
|
||||
println!("Timestamp helper functions registered successfully.");
|
||||
}
|
202
core/engine/examples/finance/finance_script.rhai
Normal file
202
core/engine/examples/finance/finance_script.rhai
Normal file
@@ -0,0 +1,202 @@
|
||||
// finance_script.rhai
|
||||
// Example Rhai script for working with Finance models
|
||||
|
||||
// Constants for AssetType
|
||||
const NATIVE = "Native";
|
||||
const ERC20 = "Erc20";
|
||||
const ERC721 = "Erc721";
|
||||
const ERC1155 = "Erc1155";
|
||||
|
||||
// Constants for ListingStatus
|
||||
const ACTIVE = "Active";
|
||||
const SOLD = "Sold";
|
||||
const CANCELLED = "Cancelled";
|
||||
const EXPIRED = "Expired";
|
||||
|
||||
// Constants for ListingType
|
||||
const FIXED_PRICE = "FixedPrice";
|
||||
const AUCTION = "Auction";
|
||||
const EXCHANGE = "Exchange";
|
||||
|
||||
// Constants for BidStatus
|
||||
const BID_ACTIVE = "Active";
|
||||
const BID_ACCEPTED = "Accepted";
|
||||
const BID_REJECTED = "Rejected";
|
||||
const BID_CANCELLED = "Cancelled";
|
||||
|
||||
// Create a new account using builder pattern
|
||||
let alice_account = new_account()
|
||||
.name("Alice's Account")
|
||||
.user_id(101)
|
||||
.description("Alice's primary trading account")
|
||||
.ledger("ethereum")
|
||||
.address("0x1234567890abcdef1234567890abcdef12345678")
|
||||
.pubkey("0xabcdef1234567890abcdef1234567890abcdef12");
|
||||
|
||||
print(`Created account: ${alice_account.get_name()} (User ID: ${alice_account.get_user_id()})`);
|
||||
|
||||
// Save the account to the database
|
||||
let saved_alice = set_account(alice_account);
|
||||
print(`Account saved to database with ID: ${saved_alice.get_id()}`);
|
||||
|
||||
// Create a new asset using builder pattern
|
||||
let token_asset = new_asset()
|
||||
.name("HERO Token")
|
||||
.description("Herocode governance token")
|
||||
.amount(1000.0)
|
||||
.address("0x9876543210abcdef9876543210abcdef98765432")
|
||||
.asset_type(ERC20)
|
||||
.decimals(18);
|
||||
|
||||
print(`Created asset: ${token_asset.get_name()} (${token_asset.get_amount()} ${token_asset.get_asset_type()})`);
|
||||
|
||||
// Save the asset to the database
|
||||
let saved_token = set_asset(token_asset);
|
||||
print(`Asset saved to database with ID: ${saved_token.get_id()}`);
|
||||
|
||||
// Add the asset to Alice's account
|
||||
saved_alice = saved_alice.add_asset(saved_token.get_id());
|
||||
saved_alice = set_account(saved_alice);
|
||||
print(`Added asset ${saved_token.get_name()} to ${saved_alice.get_name()}`);
|
||||
|
||||
// Create a new NFT asset
|
||||
let nft_asset = new_asset()
|
||||
.name("Herocode #42")
|
||||
.description("Unique digital collectible")
|
||||
.amount(1.0)
|
||||
.address("0xabcdef1234567890abcdef1234567890abcdef12")
|
||||
.asset_type(ERC721)
|
||||
.decimals(0);
|
||||
|
||||
// Save the NFT to the database
|
||||
let saved_nft = set_asset(nft_asset);
|
||||
print(`NFT saved to database with ID: ${saved_nft.get_id()}`);
|
||||
|
||||
// Create Bob's account
|
||||
let bob_account = new_account()
|
||||
.name("Bob's Account")
|
||||
.user_id(102)
|
||||
.description("Bob's trading account")
|
||||
.ledger("ethereum")
|
||||
.address("0xfedcba0987654321fedcba0987654321fedcba09")
|
||||
.pubkey("0x654321fedcba0987654321fedcba0987654321fe");
|
||||
|
||||
// Save Bob's account
|
||||
let saved_bob = set_account(bob_account);
|
||||
print(`Created and saved Bob's account with ID: ${saved_bob.get_id()}`);
|
||||
|
||||
// Create a listing for the NFT
|
||||
let nft_listing = new_listing()
|
||||
.seller_id(saved_alice.get_id())
|
||||
.asset_id(saved_nft.get_id())
|
||||
.price(0.5)
|
||||
.currency("ETH")
|
||||
.listing_type(AUCTION)
|
||||
.title("Rare Herocode NFT")
|
||||
.description("One of a kind digital collectible")
|
||||
.image_url("https://example.com/nft/42.png")
|
||||
.expires_at(timestamp_now() + 86400) // 24 hours from now
|
||||
.add_tag("rare")
|
||||
.add_tag("collectible")
|
||||
.add_tag("digital art")
|
||||
.set_listing();
|
||||
|
||||
// Save the listing
|
||||
print(`Created listing: ${nft_listing.get_title()} (ID: ${nft_listing.get_id()})`);
|
||||
print(`Listing status: ${nft_listing.get_status()}, Type: ${nft_listing.get_listing_type()}`);
|
||||
print(`Listing price: ${nft_listing.get_price()} ${nft_listing.get_currency()}`);
|
||||
|
||||
// Create a bid from Bob
|
||||
let bob_bid = new_bid()
|
||||
.listing_id(nft_listing.get_id().to_string())
|
||||
.bidder_id(saved_bob.get_id())
|
||||
.amount(1.5)
|
||||
.currency("ETH")
|
||||
.set_bid();
|
||||
|
||||
// Save the bid
|
||||
print(`Created bid from ${saved_bob.get_name()} for ${bob_bid.get_amount()} ${bob_bid.get_currency()}`);
|
||||
|
||||
// Add the bid to the listing
|
||||
nft_listing.add_bid(bob_bid);
|
||||
nft_listing.set_listing();
|
||||
print(`Added bid to listing ${nft_listing.get_title()}`);
|
||||
|
||||
// Create another bid with higher amount
|
||||
let charlie_account = new_account()
|
||||
.name("Charlie's Account")
|
||||
.user_id(103)
|
||||
.description("Charlie's trading account")
|
||||
.ledger("ethereum")
|
||||
.address("0x1122334455667788991122334455667788990011")
|
||||
.pubkey("0x8877665544332211887766554433221188776655");
|
||||
|
||||
let saved_charlie = set_account(charlie_account);
|
||||
print(`Created and saved Charlie's account with ID: ${saved_charlie.get_id()}`);
|
||||
|
||||
let charlie_bid = new_bid()
|
||||
.listing_id(nft_listing.get_id().to_string())
|
||||
.bidder_id(saved_charlie.get_id())
|
||||
.amount(2.5)
|
||||
.currency("ETH")
|
||||
.set_bid();
|
||||
|
||||
print(`Created higher bid from ${saved_charlie.get_name()} for ${charlie_bid.get_amount()} ${charlie_bid.get_currency()}`);
|
||||
|
||||
// Add the higher bid to the listing
|
||||
nft_listing.add_bid(charlie_bid)
|
||||
.set_listing();
|
||||
|
||||
|
||||
|
||||
print(`Added higher bid to listing ${nft_listing.get_title()}`);
|
||||
|
||||
nft_listing.sale_price(2.5)
|
||||
.set_listing();
|
||||
|
||||
// Complete the sale to the highest bidder (Charlie)
|
||||
nft_listing.complete_sale(saved_charlie.get_id())
|
||||
.set_listing();
|
||||
|
||||
print(`Completed sale of ${nft_listing.get_title()} to ${saved_charlie.get_name()}`);
|
||||
print(`New listing status: ${saved_listing.get_status()}`);
|
||||
|
||||
// Retrieve the listing from the database
|
||||
let retrieved_listing = get_listing_by_id(saved_listing.get_id());
|
||||
print(`Retrieved listing: ${retrieved_listing.get_title()} (Status: ${retrieved_listing.get_status()})`);
|
||||
|
||||
// Create a fixed price listing
|
||||
let token_listing = new_listing()
|
||||
.seller_id(saved_alice.get_id())
|
||||
.asset_id(saved_token.get_id())
|
||||
.price(100.0)
|
||||
.currency("USDC")
|
||||
.listing_type(FIXED_PRICE)
|
||||
.title("HERO Tokens for Sale")
|
||||
.description("100 HERO tokens at fixed price")
|
||||
.set_listing();
|
||||
|
||||
// Save the fixed price listing
|
||||
print(`Created fixed price listing: ${token_listing.get_title()} (ID: ${token_listing.get_id()})`);
|
||||
|
||||
// Cancel the listing
|
||||
token_listing.cancel();
|
||||
token_listing.set_listing();
|
||||
print(`Cancelled listing: ${token_listing.get_title()}`);
|
||||
print(`Listing status: ${token_listing.get_status()}`);
|
||||
|
||||
// Print summary of all accounts
|
||||
print("\nAccount Summary:");
|
||||
print(`Alice (ID: ${saved_alice.get_id()}): ${saved_alice.get_assets().len()} assets`);
|
||||
print(`Bob (ID: ${saved_bob.get_id()}): ${saved_bob.get_assets().len()} assets`);
|
||||
print(`Charlie (ID: ${saved_charlie.get_id()}): ${saved_charlie.get_assets().len()} assets`);
|
||||
|
||||
// Print summary of all listings
|
||||
print("\nListing Summary:");
|
||||
print(`NFT Auction (ID: ${nft_listing.get_id()}): ${nft_listing.get_status()}`);
|
||||
print(`Token Sale (ID: ${token_listing.get_id()}): ${token_listing.get_status()}`);
|
||||
|
||||
// Print summary of all bids
|
||||
print("\nBid Summary:");
|
||||
print(`Bob's bid: ${bob_bid.get_amount()} ${bob_bid.get_currency()} (Status: ${bob_bid.get_status()})`);
|
||||
print(`Charlie's bid: ${charlie_bid.get_amount()} ${charlie_bid.get_currency()} (Status: ${charlie_bid.get_status()})`);
|
111
core/engine/examples/finance/mock.rs
Normal file
111
core/engine/examples/finance/mock.rs
Normal file
@@ -0,0 +1,111 @@
|
||||
use heromodels::db::hero::OurDB;
|
||||
use heromodels::db::{Collection, Db};
|
||||
use heromodels::models::finance::account::Account;
|
||||
use heromodels::models::finance::asset::{Asset, AssetType};
|
||||
use heromodels::models::finance::marketplace::{Listing, ListingType};
|
||||
use heromodels_core::Model;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// Seed the mock database with finance data
|
||||
pub fn seed_finance_data(db: Arc<OurDB>) {
|
||||
// Create a user account
|
||||
let account = Account::new()
|
||||
.name("Demo Account")
|
||||
.user_id(1)
|
||||
.description("Demo trading account")
|
||||
.ledger("ethereum")
|
||||
.address("0x1234567890abcdef1234567890abcdef12345678")
|
||||
.pubkey("0xabcdef1234567890abcdef1234567890abcdef12");
|
||||
|
||||
// Store the account in the database
|
||||
let (account_id, mut updated_account) = db
|
||||
.collection::<Account>()
|
||||
.expect("Failed to get Account collection")
|
||||
.set(&account)
|
||||
.expect("Failed to store account");
|
||||
|
||||
// Create an ERC20 token asset
|
||||
let token_asset = Asset::new()
|
||||
.name("HERO Token")
|
||||
.description("Herocode governance token")
|
||||
.amount(1000.0)
|
||||
.address("0x9876543210abcdef9876543210abcdef98765432")
|
||||
.asset_type(AssetType::Erc20)
|
||||
.decimals(18);
|
||||
|
||||
// Store the token asset in the database
|
||||
let (token_id, updated_token) = db
|
||||
.collection::<Asset>()
|
||||
.expect("Failed to get Asset collection")
|
||||
.set(&token_asset)
|
||||
.expect("Failed to store token asset");
|
||||
|
||||
// Create an NFT asset
|
||||
let nft_asset = Asset::new()
|
||||
.name("Herocode #1")
|
||||
.description("Unique digital collectible")
|
||||
.amount(1.0)
|
||||
.address("0xabcdef1234567890abcdef1234567890abcdef12")
|
||||
.asset_type(AssetType::Erc721)
|
||||
.decimals(0);
|
||||
|
||||
// Store the NFT asset in the database
|
||||
let (nft_id, updated_nft) = db
|
||||
.collection::<Asset>()
|
||||
.expect("Failed to get Asset collection")
|
||||
.set(&nft_asset)
|
||||
.expect("Failed to store NFT asset");
|
||||
|
||||
// Add assets to the account
|
||||
updated_account = updated_account.add_asset(token_id);
|
||||
updated_account = updated_account.add_asset(nft_id);
|
||||
|
||||
// Update the account in the database
|
||||
let (_, final_account) = db
|
||||
.collection::<Account>()
|
||||
.expect("Failed to get Account collection")
|
||||
.set(&updated_account)
|
||||
.expect("Failed to store updated account");
|
||||
|
||||
// Create a listing for the NFT
|
||||
let listing = Listing::new()
|
||||
.seller_id(account_id)
|
||||
.asset_id(nft_id)
|
||||
.price(0.5)
|
||||
.currency("ETH")
|
||||
.listing_type(ListingType::Auction)
|
||||
.title("Rare Herocode NFT".to_string())
|
||||
.description("One of a kind digital collectible".to_string())
|
||||
.image_url(Some("https://example.com/nft/1.png".to_string()))
|
||||
.add_tag("rare".to_string())
|
||||
.add_tag("collectible".to_string());
|
||||
|
||||
// Store the listing in the database
|
||||
let (_listing_id, updated_listing) = db
|
||||
.collection::<Listing>()
|
||||
.expect("Failed to get Listing collection")
|
||||
.set(&listing)
|
||||
.expect("Failed to store listing");
|
||||
|
||||
println!("Mock database seeded with finance data:");
|
||||
println!(
|
||||
" - Added account: {} (ID: {})",
|
||||
final_account.name,
|
||||
final_account.get_id()
|
||||
);
|
||||
println!(
|
||||
" - Added token asset: {} (ID: {})",
|
||||
updated_token.name,
|
||||
updated_token.get_id()
|
||||
);
|
||||
println!(
|
||||
" - Added NFT asset: {} (ID: {})",
|
||||
updated_nft.name,
|
||||
updated_nft.get_id()
|
||||
);
|
||||
println!(
|
||||
" - Added listing: {} (ID: {})",
|
||||
updated_listing.title,
|
||||
updated_listing.get_id()
|
||||
);
|
||||
}
|
162
core/engine/examples/flow/example.rs
Normal file
162
core/engine/examples/flow/example.rs
Normal file
@@ -0,0 +1,162 @@
|
||||
use engine::mock_db::create_mock_db;
|
||||
use engine::{create_heromodels_engine, eval_file};
|
||||
use heromodels::models::flow::{Flow, FlowStep, SignatureRequirement};
|
||||
use heromodels_core::Model;
|
||||
use rhai::Scope;
|
||||
use std::path::Path;
|
||||
|
||||
mod mock;
|
||||
use mock::seed_flow_data;
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("Flow Rhai Example");
|
||||
println!("=================");
|
||||
|
||||
// Create a mock database
|
||||
let db = create_mock_db();
|
||||
|
||||
// Seed the database with initial data
|
||||
seed_flow_data(db.clone());
|
||||
|
||||
// Create the Rhai engine with all modules registered
|
||||
let engine = create_heromodels_engine(db.clone());
|
||||
|
||||
// Get the path to the script
|
||||
let script_path = Path::new(file!())
|
||||
.parent()
|
||||
.unwrap()
|
||||
.join("flow_script.rhai");
|
||||
|
||||
println!("\nRunning script: {}", script_path.display());
|
||||
println!("---------------------");
|
||||
|
||||
// Run the script
|
||||
match eval_file(&engine, &script_path.to_string_lossy()) {
|
||||
Ok(result) => {
|
||||
if !result.is_unit() {
|
||||
println!("\nScript returned: {:?}", result);
|
||||
}
|
||||
println!("\nScript executed successfully!");
|
||||
}
|
||||
Err(err) => {
|
||||
eprintln!("\nError running script: {}", err);
|
||||
return Err(Box::new(std::io::Error::new(
|
||||
std::io::ErrorKind::Other,
|
||||
err.to_string(),
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
// Demonstrate direct Rust interaction with the Rhai-exposed flow functionality
|
||||
println!("\nDirect Rust interaction with Rhai-exposed flow functionality");
|
||||
println!("----------------------------------------------------------");
|
||||
|
||||
// Create a new scope
|
||||
let mut scope = Scope::new();
|
||||
|
||||
// Create a new flow using the Rhai function
|
||||
let result = engine.eval::<Flow>("new_flow(0, \"Direct Rust Flow\")");
|
||||
match result {
|
||||
Ok(mut flow) => {
|
||||
println!(
|
||||
"Created flow from Rust: {} (ID: {})",
|
||||
flow.name,
|
||||
flow.get_id()
|
||||
);
|
||||
|
||||
// Set flow status using the builder pattern
|
||||
flow = flow.status("active".to_string());
|
||||
println!("Set flow status to: {}", flow.status);
|
||||
|
||||
// Create a new flow step using the Rhai function
|
||||
let result = engine.eval::<FlowStep>("new_flow_step(0, 1)");
|
||||
|
||||
match result {
|
||||
Ok(mut step) => {
|
||||
println!(
|
||||
"Created flow step from Rust: Step Order {} (ID: {})",
|
||||
step.step_order,
|
||||
step.get_id()
|
||||
);
|
||||
|
||||
// Set step description
|
||||
step = step.description("Direct Rust Step".to_string());
|
||||
println!(
|
||||
"Set step description to: {}",
|
||||
step.description
|
||||
.clone()
|
||||
.unwrap_or_else(|| "None".to_string())
|
||||
);
|
||||
|
||||
// Create a signature requirement using the Rhai function
|
||||
let result = engine.eval::<SignatureRequirement>(
|
||||
"new_signature_requirement(0, 1, \"Direct Rust Signer\", \"Please sign this document\")"
|
||||
);
|
||||
|
||||
match result {
|
||||
Ok(req) => {
|
||||
println!(
|
||||
"Created signature requirement from Rust: Public Key {} (ID: {})",
|
||||
req.public_key,
|
||||
req.get_id()
|
||||
);
|
||||
|
||||
// Add the step to the flow using the builder pattern
|
||||
flow = flow.add_step(step);
|
||||
println!(
|
||||
"Added step to flow. Flow now has {} steps",
|
||||
flow.steps.len()
|
||||
);
|
||||
|
||||
// Save the flow to the database using the Rhai function
|
||||
let save_flow_script = "fn save_it(f) { return db::save_flow(f); }";
|
||||
let save_flow_ast = engine.compile(save_flow_script).unwrap();
|
||||
let result = engine.call_fn::<Flow>(
|
||||
&mut scope,
|
||||
&save_flow_ast,
|
||||
"save_it",
|
||||
(flow,),
|
||||
);
|
||||
match result {
|
||||
Ok(saved_flow) => {
|
||||
println!(
|
||||
"Saved flow to database with ID: {}",
|
||||
saved_flow.get_id()
|
||||
);
|
||||
}
|
||||
Err(err) => eprintln!("Error saving flow: {}", err),
|
||||
}
|
||||
|
||||
// Save the signature requirement to the database using the Rhai function
|
||||
let save_req_script =
|
||||
"fn save_it(r) { return db::save_signature_requirement(r); }";
|
||||
let save_req_ast = engine.compile(save_req_script).unwrap();
|
||||
let result = engine.call_fn::<SignatureRequirement>(
|
||||
&mut scope,
|
||||
&save_req_ast,
|
||||
"save_it",
|
||||
(req,),
|
||||
);
|
||||
match result {
|
||||
Ok(saved_req) => {
|
||||
println!(
|
||||
"Saved signature requirement to database with ID: {}",
|
||||
saved_req.get_id()
|
||||
);
|
||||
}
|
||||
Err(err) => {
|
||||
eprintln!("Error saving signature requirement: {}", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(err) => eprintln!("Error creating signature requirement: {}", err),
|
||||
}
|
||||
}
|
||||
Err(err) => eprintln!("Error creating flow step: {}", err),
|
||||
}
|
||||
}
|
||||
Err(err) => eprintln!("Error creating flow: {}", err),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
111
core/engine/examples/flow/flow_script.rhai
Normal file
111
core/engine/examples/flow/flow_script.rhai
Normal file
@@ -0,0 +1,111 @@
|
||||
// flow_script.rhai
|
||||
// Example Rhai script for working with Flow models
|
||||
|
||||
// Constants for Flow status
|
||||
const STATUS_DRAFT = "draft";
|
||||
const STATUS_ACTIVE = "active";
|
||||
const STATUS_COMPLETED = "completed";
|
||||
const STATUS_CANCELLED = "cancelled";
|
||||
|
||||
// Create a new flow using builder pattern
|
||||
let my_flow = new_flow(0, "flow-123");
|
||||
name(my_flow, "Document Approval Flow");
|
||||
status(my_flow, STATUS_DRAFT);
|
||||
|
||||
print(`Created flow: ${get_flow_name(my_flow)} (ID: ${get_flow_id(my_flow)})`);
|
||||
print(`Status: ${get_flow_status(my_flow)}`);
|
||||
|
||||
// Create flow steps using builder pattern
|
||||
let step1 = new_flow_step(0, 1);
|
||||
description(step1, "Initial review by legal team");
|
||||
status(step1, STATUS_DRAFT);
|
||||
|
||||
let step2 = new_flow_step(0, 2);
|
||||
description(step2, "Approval by department head");
|
||||
status(step2, STATUS_DRAFT);
|
||||
|
||||
let step3 = new_flow_step(0, 3);
|
||||
description(step3, "Final signature by CEO");
|
||||
status(step3, STATUS_DRAFT);
|
||||
|
||||
// Create signature requirements using builder pattern
|
||||
let req1 = new_signature_requirement(0, get_flow_step_id(step1), "legal@example.com", "Please review this document");
|
||||
signed_by(req1, "Legal Team");
|
||||
status(req1, STATUS_DRAFT);
|
||||
|
||||
let req2 = new_signature_requirement(0, get_flow_step_id(step2), "dept@example.com", "Department approval needed");
|
||||
signed_by(req2, "Department Head");
|
||||
status(req2, STATUS_DRAFT);
|
||||
|
||||
let req3 = new_signature_requirement(0, get_flow_step_id(step3), "ceo@example.com", "Final approval required");
|
||||
signed_by(req3, "CEO");
|
||||
status(req3, STATUS_DRAFT);
|
||||
|
||||
print(`Created flow steps with signature requirements`);
|
||||
|
||||
// Add steps to the flow
|
||||
let flow_with_steps = my_flow;
|
||||
add_step(flow_with_steps, step1);
|
||||
add_step(flow_with_steps, step2);
|
||||
add_step(flow_with_steps, step3);
|
||||
|
||||
print(`Added steps to flow. Flow now has ${get_flow_steps(flow_with_steps).len()} steps`);
|
||||
|
||||
// Activate the flow
|
||||
let active_flow = flow_with_steps;
|
||||
status(active_flow, STATUS_ACTIVE);
|
||||
print(`Updated flow status to: ${get_flow_status(active_flow)}`);
|
||||
|
||||
// Save the flow to the database
|
||||
let saved_flow = db::save_flow(active_flow);
|
||||
print(`Flow saved to database with ID: ${get_flow_id(saved_flow)}`);
|
||||
|
||||
// Save signature requirements to the database
|
||||
let saved_req1 = db::save_signature_requirement(req1);
|
||||
let saved_req2 = db::save_signature_requirement(req2);
|
||||
let saved_req3 = db::save_signature_requirement(req3);
|
||||
print(`Signature requirements saved to database with IDs: ${get_signature_requirement_id(saved_req1)}, ${get_signature_requirement_id(saved_req2)}, ${get_signature_requirement_id(saved_req3)}`);
|
||||
|
||||
// Retrieve the flow from the database
|
||||
let retrieved_flow = db::get_flow_by_id(get_flow_id(saved_flow));
|
||||
print(`Retrieved flow: ${get_flow_name(retrieved_flow)}`);
|
||||
print(`It has ${get_flow_steps(retrieved_flow).len()} steps`);
|
||||
|
||||
// Complete the flow
|
||||
let completed_flow = retrieved_flow;
|
||||
status(completed_flow, STATUS_COMPLETED);
|
||||
print(`Updated retrieved flow status to: ${get_flow_status(completed_flow)}`);
|
||||
|
||||
// Save the updated flow
|
||||
db::save_flow(completed_flow);
|
||||
print("Updated flow saved to database");
|
||||
|
||||
// List all flows in the database
|
||||
let all_flows = db::list_flows();
|
||||
print("\nListing all flows in database:");
|
||||
let flow_count = 0;
|
||||
for flow in all_flows {
|
||||
print(` - Flow: ${get_flow_name(flow)} (ID: ${get_flow_id(flow)})`);
|
||||
flow_count += 1;
|
||||
}
|
||||
print(`Total flows: ${flow_count}`);
|
||||
|
||||
// List all signature requirements
|
||||
let all_reqs = db::list_signature_requirements();
|
||||
print("\nListing all signature requirements in database:");
|
||||
let req_count = 0;
|
||||
for req in all_reqs {
|
||||
print(` - Requirement for step ${get_signature_requirement_flow_step_id(req)} (ID: ${get_signature_requirement_id(req)})`);
|
||||
req_count += 1;
|
||||
}
|
||||
print(`Total signature requirements: ${req_count}`);
|
||||
|
||||
// Clean up - delete the flow
|
||||
db::delete_flow(get_flow_id(completed_flow));
|
||||
print(`Deleted flow with ID: ${get_flow_id(completed_flow)}`);
|
||||
|
||||
// Clean up - delete signature requirements
|
||||
db::delete_signature_requirement(get_signature_requirement_id(saved_req1));
|
||||
db::delete_signature_requirement(get_signature_requirement_id(saved_req2));
|
||||
db::delete_signature_requirement(get_signature_requirement_id(saved_req3));
|
||||
print("Deleted all signature requirements");
|
65
core/engine/examples/flow/mock.rs
Normal file
65
core/engine/examples/flow/mock.rs
Normal file
@@ -0,0 +1,65 @@
|
||||
use heromodels::db::hero::OurDB;
|
||||
use heromodels::db::{Collection, Db};
|
||||
use heromodels::models::flow::{Flow, FlowStep, SignatureRequirement};
|
||||
use heromodels_core::Model;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// Seed the mock database with flow data
|
||||
#[cfg(feature = "flow")]
|
||||
pub fn seed_flow_data(db: Arc<OurDB>) {
|
||||
// Create a flow
|
||||
let flow = Flow::new(None, "Onboarding Flow".to_string())
|
||||
.description("New employee onboarding process".to_string())
|
||||
.status("active".to_string());
|
||||
|
||||
// Create a signature requirement first
|
||||
let sig_req = SignatureRequirement::new(
|
||||
None,
|
||||
1,
|
||||
"hr_manager_pubkey".to_string(),
|
||||
"Please sign the employment contract".to_string(),
|
||||
);
|
||||
let (sig_req_id, saved_sig_req) = db
|
||||
.collection::<SignatureRequirement>()
|
||||
.expect("Failed to get SignatureRequirement collection")
|
||||
.set(&sig_req)
|
||||
.expect("Failed to store signature requirement");
|
||||
|
||||
// Create a flow step and add the signature requirement
|
||||
let step = FlowStep::new(None, 1)
|
||||
.description("Complete HR paperwork".to_string())
|
||||
.add_signature_requirement(sig_req_id);
|
||||
|
||||
let (step_id, saved_step) = db
|
||||
.collection::<FlowStep>()
|
||||
.expect("Failed to get FlowStep collection")
|
||||
.set(&step)
|
||||
.expect("Failed to store flow step");
|
||||
|
||||
// Add the step to the flow
|
||||
let flow_with_step = flow.add_step(step_id);
|
||||
|
||||
// Store the flow
|
||||
let (_flow_id, saved_flow) = db
|
||||
.collection::<Flow>()
|
||||
.expect("Failed to get Flow collection")
|
||||
.set(&flow_with_step)
|
||||
.expect("Failed to store flow");
|
||||
|
||||
println!("Mock database seeded with flow data:");
|
||||
println!(
|
||||
" - Added flow: {} (ID: {})",
|
||||
saved_flow.name,
|
||||
saved_flow.get_id()
|
||||
);
|
||||
println!(
|
||||
" - Added step with order: {} (ID: {})",
|
||||
saved_step.step_order,
|
||||
saved_step.get_id()
|
||||
);
|
||||
println!(
|
||||
" - Added signature requirement for: {} (ID: {})",
|
||||
saved_sig_req.public_key,
|
||||
saved_sig_req.get_id()
|
||||
);
|
||||
}
|
Reference in New Issue
Block a user