remove rhai dsls

This commit is contained in:
Timur Gordon
2025-06-25 03:27:22 +02:00
parent f2dfde5e8f
commit 149c177def
52 changed files with 120 additions and 7077 deletions

View File

@@ -1,973 +0,0 @@
use chrono::Utc;
use rhai::plugin::*;
use rhai::{Array, Dynamic, Engine, EvalAltResult, INT, Module, Position};
use std::mem;
use std::sync::Arc;
use super::account::Account;
use super::asset::{Asset, AssetType};
use super::marketplace::{Bid, BidStatus, Listing, ListingStatus, ListingType};
use crate::db::hero::OurDB;
use crate::db::{Collection, Db};
type RhaiAccount = Account;
type RhaiAsset = Asset;
type RhaiListing = Listing;
type RhaiBid = Bid;
// Helper to convert i64 from Rhai to u32 for IDs
fn id_from_i64_to_u32(id_i64: i64) -> Result<u32, Box<EvalAltResult>> {
u32::try_from(id_i64).map_err(|_| {
Box::new(EvalAltResult::ErrorArithmetic(
format!("Failed to convert ID '{}' to u32", id_i64).into(),
Position::NONE,
))
})
}
// Helper functions for enum conversions
// AssetType conversions
fn asset_type_to_string(asset_type: &AssetType) -> String {
match asset_type {
AssetType::Native => "Native".to_string(),
AssetType::Erc20 => "Erc20".to_string(),
AssetType::Erc721 => "Erc721".to_string(),
AssetType::Erc1155 => "Erc1155".to_string(),
}
}
fn string_to_asset_type(s: &str) -> Result<AssetType, Box<EvalAltResult>> {
match s {
"Native" => Ok(AssetType::Native),
"Erc20" => Ok(AssetType::Erc20),
"Erc721" => Ok(AssetType::Erc721),
"Erc1155" => Ok(AssetType::Erc1155),
_ => Err(Box::new(EvalAltResult::ErrorRuntime(
format!(
"Invalid asset type: '{}'. Expected one of: Native, Erc20, Erc721, Erc1155",
s
)
.into(),
Position::NONE,
))),
}
}
// ListingStatus conversions
fn listing_status_to_string(status: &ListingStatus) -> String {
match status {
ListingStatus::Active => "Active".to_string(),
ListingStatus::Sold => "Sold".to_string(),
ListingStatus::Cancelled => "Cancelled".to_string(),
ListingStatus::Expired => "Expired".to_string(),
}
}
fn string_to_listing_status(s: &str) -> Result<ListingStatus, Box<EvalAltResult>> {
match s {
"Active" => Ok(ListingStatus::Active),
"Sold" => Ok(ListingStatus::Sold),
"Cancelled" => Ok(ListingStatus::Cancelled),
"Expired" => Ok(ListingStatus::Expired),
_ => Err(Box::new(EvalAltResult::ErrorRuntime(
format!(
"Invalid listing status: '{}'. Expected one of: Active, Sold, Cancelled, Expired",
s
)
.into(),
Position::NONE,
))),
}
}
// ListingType conversions
fn listing_type_to_string(lt: &ListingType) -> String {
match lt {
ListingType::FixedPrice => "FixedPrice".to_string(),
ListingType::Auction => "Auction".to_string(),
ListingType::Exchange => "Exchange".to_string(),
}
}
fn string_to_listing_type(s: &str) -> Result<ListingType, Box<EvalAltResult>> {
match s {
"FixedPrice" => Ok(ListingType::FixedPrice),
"Auction" => Ok(ListingType::Auction),
"Exchange" => Ok(ListingType::Exchange),
_ => Err(Box::new(EvalAltResult::ErrorRuntime(
format!(
"Invalid listing type: '{}'. Expected one of: FixedPrice, Auction, Exchange",
s
)
.into(),
Position::NONE,
))),
}
}
// BidStatus conversions
fn bid_status_to_string(status: &BidStatus) -> String {
match status {
BidStatus::Active => "Active".to_string(),
BidStatus::Accepted => "Accepted".to_string(),
BidStatus::Rejected => "Rejected".to_string(),
BidStatus::Cancelled => "Cancelled".to_string(),
}
}
fn string_to_bid_status(s: &str) -> Result<BidStatus, Box<EvalAltResult>> {
match s {
"Active" => Ok(BidStatus::Active),
"Accepted" => Ok(BidStatus::Accepted),
"Rejected" => Ok(BidStatus::Rejected),
"Cancelled" => Ok(BidStatus::Cancelled),
_ => Err(Box::new(EvalAltResult::ErrorRuntime(
format!(
"Invalid bid status: '{}'. Expected one of: Active, Accepted, Rejected, Cancelled",
s
)
.into(),
Position::NONE,
))),
}
}
// Account module
#[export_module]
mod account_module {
use super::*;
// Constructor
#[rhai_fn(return_raw, global)]
pub fn new_account() -> Result<RhaiAccount, Box<EvalAltResult>> {
Ok(Account::new())
}
// Getters
#[rhai_fn(global, pure)]
pub fn get_id(account: &mut RhaiAccount) -> INT {
account.base_data.id as INT
}
#[rhai_fn(global, pure)]
pub fn get_created_at(account: &mut RhaiAccount) -> INT {
account.base_data.created_at
}
#[rhai_fn(global, pure)]
pub fn get_name(account: &mut RhaiAccount) -> String {
account.name.clone()
}
#[rhai_fn(global, pure)]
pub fn get_user_id(account: &mut RhaiAccount) -> INT {
account.user_id as INT
}
#[rhai_fn(global, pure)]
pub fn get_description(account: &mut RhaiAccount) -> String {
account.description.clone()
}
#[rhai_fn(global, pure)]
pub fn get_ledger(account: &mut RhaiAccount) -> String {
account.ledger.clone()
}
#[rhai_fn(global, pure)]
pub fn get_address(account: &mut RhaiAccount) -> String {
account.address.clone()
}
#[rhai_fn(global, pure)]
pub fn get_pubkey(account: &mut RhaiAccount) -> String {
account.pubkey.clone()
}
#[rhai_fn(global, pure)]
pub fn get_assets(account: &mut RhaiAccount) -> Array {
let mut assets_array = Array::new();
for asset_id in &account.assets {
assets_array.push(Dynamic::from(*asset_id as INT));
}
assets_array
}
// Setters using builder pattern with proper mutability handling
#[rhai_fn(return_raw, global)]
pub fn name(
account: &mut RhaiAccount,
name: String,
) -> Result<RhaiAccount, Box<EvalAltResult>> {
let mut acc = mem::take(account);
acc = acc.name(name);
*account = acc;
Ok(account.clone())
}
#[rhai_fn(return_raw, global)]
pub fn user_id(
account: &mut RhaiAccount,
user_id: INT,
) -> Result<RhaiAccount, Box<EvalAltResult>> {
let user_id = id_from_i64_to_u32(user_id)?;
let mut acc = mem::take(account);
acc = acc.user_id(user_id);
*account = acc;
Ok(account.clone())
}
#[rhai_fn(return_raw, global)]
pub fn description(
account: &mut RhaiAccount,
description: String,
) -> Result<RhaiAccount, Box<EvalAltResult>> {
let mut acc = mem::take(account);
acc = acc.description(description);
*account = acc;
Ok(account.clone())
}
#[rhai_fn(return_raw, global)]
pub fn ledger(
account: &mut RhaiAccount,
ledger: String,
) -> Result<RhaiAccount, Box<EvalAltResult>> {
let mut acc = mem::take(account);
acc = acc.ledger(ledger);
*account = acc;
Ok(account.clone())
}
#[rhai_fn(return_raw, global)]
pub fn address(
account: &mut RhaiAccount,
address: String,
) -> Result<RhaiAccount, Box<EvalAltResult>> {
let mut acc = mem::take(account);
acc = acc.address(address);
*account = acc;
Ok(account.clone())
}
#[rhai_fn(return_raw, global)]
pub fn pubkey(
account: &mut RhaiAccount,
pubkey: String,
) -> Result<RhaiAccount, Box<EvalAltResult>> {
let mut acc = mem::take(account);
acc = acc.pubkey(pubkey);
*account = acc;
Ok(account.clone())
}
#[rhai_fn(return_raw, global)]
pub fn add_asset(
account: &mut RhaiAccount,
asset_id: INT,
) -> Result<RhaiAccount, Box<EvalAltResult>> {
let asset_id = id_from_i64_to_u32(asset_id)?;
let mut acc = mem::take(account);
acc = acc.add_asset(asset_id);
*account = acc;
Ok(account.clone())
}
}
// Asset module
#[export_module]
mod asset_module {
use super::*;
// Constructor
#[rhai_fn(return_raw, global)]
pub fn new_asset() -> Result<RhaiAsset, Box<EvalAltResult>> {
Ok(Asset::new())
}
// Getters
#[rhai_fn(global, pure)]
pub fn get_id(asset: &mut RhaiAsset) -> INT {
asset.base_data.id as INT
}
#[rhai_fn(global, pure)]
pub fn get_created_at(asset: &mut RhaiAsset) -> INT {
asset.base_data.created_at
}
#[rhai_fn(global, pure)]
pub fn get_name(asset: &mut RhaiAsset) -> String {
asset.name.clone()
}
#[rhai_fn(global, pure)]
pub fn get_description(asset: &mut RhaiAsset) -> String {
asset.description.clone()
}
#[rhai_fn(global, pure)]
pub fn get_amount(asset: &mut RhaiAsset) -> f64 {
asset.amount
}
#[rhai_fn(global, pure)]
pub fn get_address(asset: &mut RhaiAsset) -> String {
asset.address.clone()
}
#[rhai_fn(global, pure)]
pub fn get_asset_type(asset: &mut RhaiAsset) -> String {
asset_type_to_string(&asset.asset_type)
}
#[rhai_fn(global, pure)]
pub fn get_decimals(asset: &mut RhaiAsset) -> INT {
asset.decimals as INT
}
// Setters using builder pattern with proper mutability handling
#[rhai_fn(return_raw, global)]
pub fn name(asset: &mut RhaiAsset, name: String) -> Result<RhaiAsset, Box<EvalAltResult>> {
let mut ast = mem::take(asset);
ast = ast.name(name);
*asset = ast;
Ok(asset.clone())
}
#[rhai_fn(return_raw, global)]
pub fn description(
asset: &mut RhaiAsset,
description: String,
) -> Result<RhaiAsset, Box<EvalAltResult>> {
let mut ast = mem::take(asset);
ast = ast.description(description);
*asset = ast;
Ok(asset.clone())
}
#[rhai_fn(return_raw, global)]
pub fn amount(asset: &mut RhaiAsset, amount: f64) -> Result<RhaiAsset, Box<EvalAltResult>> {
let mut ast = mem::take(asset);
ast = ast.amount(amount);
*asset = ast;
Ok(asset.clone())
}
#[rhai_fn(return_raw, global)]
pub fn address(
asset: &mut RhaiAsset,
address: String,
) -> Result<RhaiAsset, Box<EvalAltResult>> {
let mut ast = mem::take(asset);
ast = ast.address(address);
*asset = ast;
Ok(asset.clone())
}
#[rhai_fn(return_raw, global)]
pub fn asset_type(
asset: &mut RhaiAsset,
asset_type_str: String,
) -> Result<RhaiAsset, Box<EvalAltResult>> {
let asset_type_enum = string_to_asset_type(&asset_type_str)?;
let mut ast = mem::take(asset);
ast = ast.asset_type(asset_type_enum);
*asset = ast;
Ok(asset.clone())
}
#[rhai_fn(return_raw, global)]
pub fn decimals(asset: &mut RhaiAsset, decimals: INT) -> Result<RhaiAsset, Box<EvalAltResult>> {
if decimals < 0 || decimals > 255 {
return Err(Box::new(EvalAltResult::ErrorArithmetic(
format!("Decimals value must be between 0 and 255, got {}", decimals).into(),
Position::NONE,
)));
}
let mut ast = mem::take(asset);
ast = ast.decimals(decimals as u8);
*asset = ast;
Ok(asset.clone())
}
}
// Listing module
#[export_module]
mod listing_module {
use super::*;
// Constructor
#[rhai_fn(return_raw, global)]
pub fn new_listing() -> Result<RhaiListing, Box<EvalAltResult>> {
Ok(Listing::new())
}
// Getters
#[rhai_fn(global, pure)]
pub fn get_id(listing: &mut RhaiListing) -> INT {
listing.base_data.id as INT
}
#[rhai_fn(global, pure)]
pub fn get_created_at(listing: &mut RhaiListing) -> INT {
listing.base_data.created_at
}
#[rhai_fn(global, pure)]
pub fn get_seller_id(listing: &mut RhaiListing) -> INT {
// Parse the seller_id string to u32, then to INT
listing.seller_id.parse::<u32>().unwrap_or(0) as INT
}
#[rhai_fn(global, pure)]
pub fn get_asset_id(listing: &mut RhaiListing) -> INT {
// Parse the asset_id string to u32, then to INT
listing.asset_id.parse::<u32>().unwrap_or(0) as INT
}
#[rhai_fn(global, pure)]
pub fn get_price(listing: &mut RhaiListing) -> f64 {
listing.price
}
#[rhai_fn(global, pure)]
pub fn get_currency(listing: &mut RhaiListing) -> String {
listing.currency.clone()
}
#[rhai_fn(global, pure)]
pub fn get_listing_type(listing: &mut RhaiListing) -> String {
listing_type_to_string(&listing.listing_type)
}
#[rhai_fn(global, pure)]
pub fn get_status(listing: &mut RhaiListing) -> String {
listing_status_to_string(&listing.status)
}
#[rhai_fn(global, pure)]
pub fn get_title(listing: &mut RhaiListing) -> String {
listing.title.clone()
}
#[rhai_fn(global, pure)]
pub fn get_description(listing: &mut RhaiListing) -> String {
listing.description.clone()
}
#[rhai_fn(global, pure)]
pub fn get_image_url(listing: &mut RhaiListing) -> String {
listing.image_url.clone().unwrap_or_else(|| "".to_string())
}
#[rhai_fn(global, pure)]
pub fn get_end_date(listing: &mut RhaiListing) -> INT {
listing.expires_at.map_or(0, |d| d.timestamp())
}
#[rhai_fn(global, pure)]
pub fn get_tags(listing: &mut RhaiListing) -> Array {
let mut tags_array = Array::new();
for tag in &listing.tags {
tags_array.push(Dynamic::from(tag.clone()));
}
tags_array
}
#[rhai_fn(global, pure)]
pub fn get_bids(listing: &mut RhaiListing) -> Array {
let mut bids_array = Array::new();
for bid in &listing.bids {
bids_array.push(Dynamic::from(bid.clone()));
}
bids_array
}
// Setters using builder pattern with proper mutability handling
#[rhai_fn(return_raw, global)]
pub fn seller_id(
listing: &mut RhaiListing,
seller_id: INT,
) -> Result<RhaiListing, Box<EvalAltResult>> {
let seller_id = id_from_i64_to_u32(seller_id)?;
let mut lst = mem::take(listing);
lst = lst.seller_id(seller_id);
*listing = lst;
Ok(listing.clone())
}
#[rhai_fn(return_raw, global)]
pub fn asset_id(
listing: &mut RhaiListing,
asset_id: INT,
) -> Result<RhaiListing, Box<EvalAltResult>> {
let asset_id = id_from_i64_to_u32(asset_id)?;
let mut lst = mem::take(listing);
lst = lst.asset_id(asset_id);
*listing = lst;
Ok(listing.clone())
}
#[rhai_fn(return_raw, global)]
pub fn price(listing: &mut RhaiListing, price: f64) -> Result<RhaiListing, Box<EvalAltResult>> {
let mut lst = mem::take(listing);
lst = lst.price(price);
*listing = lst;
Ok(listing.clone())
}
#[rhai_fn(return_raw, global)]
pub fn currency(
listing: &mut RhaiListing,
currency: String,
) -> Result<RhaiListing, Box<EvalAltResult>> {
let mut lst = mem::take(listing);
lst = lst.currency(currency);
*listing = lst;
Ok(listing.clone())
}
#[rhai_fn(return_raw, global)]
pub fn listing_type(
listing: &mut RhaiListing,
listing_type_str: String,
) -> Result<RhaiListing, Box<EvalAltResult>> {
let listing_type_enum = string_to_listing_type(&listing_type_str)?;
let mut lst = mem::take(listing);
lst = lst.listing_type(listing_type_enum);
*listing = lst;
Ok(listing.clone())
}
#[rhai_fn(return_raw, global)]
pub fn title(
listing: &mut RhaiListing,
title: String,
) -> Result<RhaiListing, Box<EvalAltResult>> {
let mut lst = mem::take(listing);
lst = lst.title(title);
*listing = lst;
Ok(listing.clone())
}
#[rhai_fn(return_raw, global)]
pub fn description(
listing: &mut RhaiListing,
description: String,
) -> Result<RhaiListing, Box<EvalAltResult>> {
let mut lst = mem::take(listing);
lst = lst.description(description);
*listing = lst;
Ok(listing.clone())
}
#[rhai_fn(return_raw, global)]
pub fn image_url(
listing: &mut RhaiListing,
image_url: String,
) -> Result<RhaiListing, Box<EvalAltResult>> {
let mut lst = mem::take(listing);
lst = lst.image_url(Some(image_url));
*listing = lst;
Ok(listing.clone())
}
#[rhai_fn(return_raw, global)]
pub fn expires_at(
listing: &mut RhaiListing,
end_date_ts: INT,
) -> Result<RhaiListing, Box<EvalAltResult>> {
use chrono::TimeZone;
let end_date = chrono::Utc
.timestamp_opt(end_date_ts, 0)
.single()
.ok_or_else(|| {
Box::new(EvalAltResult::ErrorRuntime(
format!("Invalid timestamp: {}", end_date_ts).into(),
Position::NONE,
))
})?;
let mut lst = mem::take(listing);
lst = lst.expires_at(Some(end_date));
*listing = lst;
Ok(listing.clone())
}
#[rhai_fn(return_raw, global)]
pub fn add_tag(
listing: &mut RhaiListing,
tag: String,
) -> Result<RhaiListing, Box<EvalAltResult>> {
let mut lst = mem::take(listing);
lst = lst.add_tag(tag);
*listing = lst;
Ok(listing.clone())
}
#[rhai_fn(return_raw, global)]
pub fn add_bid(
listing: &mut RhaiListing,
bid: RhaiBid,
) -> Result<RhaiListing, Box<EvalAltResult>> {
let lst = mem::take(listing);
match lst.clone().add_bid(bid) {
Ok(updated_lst) => {
*listing = updated_lst;
Ok(listing.clone())
}
Err(err) => {
// Put back the original listing since the add_bid failed
*listing = lst;
Err(Box::new(EvalAltResult::ErrorRuntime(
format!("Failed to add bid: {}", err).into(),
Position::NONE,
)))
}
}
}
#[rhai_fn(return_raw, global)]
pub fn complete_sale(
listing: &mut RhaiListing,
buyer_id: INT,
) -> Result<RhaiListing, Box<EvalAltResult>> {
let buyer_id = id_from_i64_to_u32(buyer_id)?;
let lst = mem::take(listing);
// First set the buyer_id and sale_price
let lst_with_buyer = lst.clone().buyer_id(buyer_id);
// Now complete the sale
match lst_with_buyer.complete_sale() {
Ok(updated_lst) => {
*listing = updated_lst;
Ok(listing.clone())
}
Err(err) => {
// Put back the original listing since the complete_sale failed
*listing = lst;
Err(Box::new(EvalAltResult::ErrorRuntime(
format!("Failed to complete sale: {}", err).into(),
Position::NONE,
)))
}
}
}
#[rhai_fn(return_raw, global)]
pub fn cancel(listing: &mut RhaiListing) -> Result<RhaiListing, Box<EvalAltResult>> {
let lst = mem::take(listing);
match lst.clone().cancel() {
Ok(updated_lst) => {
*listing = updated_lst;
Ok(listing.clone())
}
Err(err) => {
// Put back the original listing since the cancel failed
*listing = lst;
Err(Box::new(EvalAltResult::ErrorRuntime(
format!("Failed to cancel listing: {}", err).into(),
Position::NONE,
)))
}
}
}
#[rhai_fn(return_raw, global)]
pub fn check_expiration(listing: &mut RhaiListing) -> Result<RhaiListing, Box<EvalAltResult>> {
let mut lst = mem::take(listing);
lst = lst.check_expiration();
*listing = lst;
Ok(listing.clone())
}
}
// Bid module
#[export_module]
mod bid_module {
use super::*;
// Constructor
#[rhai_fn(return_raw, global)]
pub fn new_bid() -> Result<RhaiBid, Box<EvalAltResult>> {
Ok(Bid::new())
}
// Getters
#[rhai_fn(global, pure)]
pub fn get_listing_id(bid: &mut RhaiBid) -> String {
bid.listing_id.clone()
}
#[rhai_fn(global, pure)]
pub fn get_bidder_id(bid: &mut RhaiBid) -> INT {
bid.bidder_id as INT
}
#[rhai_fn(global, pure)]
pub fn get_amount(bid: &mut RhaiBid) -> f64 {
bid.amount
}
#[rhai_fn(global, pure)]
pub fn get_currency(bid: &mut RhaiBid) -> String {
bid.currency.clone()
}
#[rhai_fn(global, pure)]
pub fn get_status(bid: &mut RhaiBid) -> String {
bid_status_to_string(&bid.status)
}
#[rhai_fn(global, pure)]
pub fn get_created_at(bid: &mut RhaiBid) -> INT {
bid.created_at.timestamp()
}
// Setters using builder pattern with proper mutability handling
#[rhai_fn(return_raw, global)]
pub fn listing_id(
bid: &mut RhaiBid,
listing_id: String,
) -> Result<RhaiBid, Box<EvalAltResult>> {
let mut b = mem::take(bid);
b = b.listing_id(listing_id);
*bid = b;
Ok(bid.clone())
}
#[rhai_fn(return_raw, global)]
pub fn bidder_id(bid: &mut RhaiBid, bidder_id: INT) -> Result<RhaiBid, Box<EvalAltResult>> {
let bidder_id = id_from_i64_to_u32(bidder_id)?;
let mut b = mem::take(bid);
b = b.bidder_id(bidder_id);
*bid = b;
Ok(bid.clone())
}
#[rhai_fn(return_raw, global)]
pub fn amount(bid: &mut RhaiBid, amount: f64) -> Result<RhaiBid, Box<EvalAltResult>> {
let mut b = mem::take(bid);
b = b.amount(amount);
*bid = b;
Ok(bid.clone())
}
#[rhai_fn(return_raw, global)]
pub fn currency(bid: &mut RhaiBid, currency: String) -> Result<RhaiBid, Box<EvalAltResult>> {
let mut b = mem::take(bid);
b = b.currency(currency);
*bid = b;
Ok(bid.clone())
}
#[rhai_fn(return_raw, global)]
pub fn update_status(
bid: &mut RhaiBid,
status_str: String,
) -> Result<RhaiBid, Box<EvalAltResult>> {
let status = string_to_bid_status(&status_str)?;
let mut b = mem::take(bid);
b = b.status(status);
*bid = b;
Ok(bid.clone())
}
}
use rhai::ImmutableString;
// Register all Rhai functions for the finance module
pub fn register_finance_rhai_module(engine: &mut Engine, db: Arc<OurDB>) {
// --- Register model-specific modules with the engine ---
let account_module = exported_module!(account_module);
engine.register_global_module(account_module.into());
let asset_module = exported_module!(asset_module);
engine.register_global_module(asset_module.into());
let listing_module = exported_module!(listing_module);
engine.register_global_module(listing_module.into());
let bid_module = exported_module!(bid_module);
engine.register_global_module(bid_module.into());
// --- Global Helper Functions (Enum conversions) ---
engine.register_fn("str_to_asset_type", |s: ImmutableString| {
self::string_to_asset_type(s.as_str())
});
engine.register_fn("asset_type_to_str", self::asset_type_to_string);
engine.register_fn("str_to_listing_status", |s: ImmutableString| {
self::string_to_listing_status(s.as_str())
});
engine.register_fn("listing_status_to_str", self::listing_status_to_string);
engine.register_fn("str_to_listing_type", |s: ImmutableString| {
self::string_to_listing_type(s.as_str())
});
engine.register_fn("listing_type_to_str", self::listing_type_to_string);
engine.register_fn("str_to_bid_status", |s: ImmutableString| {
self::string_to_bid_status(s.as_str())
});
engine.register_fn("bid_status_to_str", self::bid_status_to_string);
// --- Database interaction functions (registered in a separate db_module) ---
let mut db_module = Module::new();
// Account DB functions
let db_set_account = Arc::clone(&db);
db_module.set_native_fn(
"set_account",
move |account: Account| -> Result<INT, Box<EvalAltResult>> {
let collection = db_set_account.collection::<Account>().map_err(|e| {
Box::new(EvalAltResult::ErrorRuntime(
format!("Failed to get Account collection: {:?}", e).into(),
Position::NONE,
))
})?;
collection
.set(&account)
.map(|(id, _)| id as INT)
.map_err(|e| {
Box::new(EvalAltResult::ErrorRuntime(
format!("Failed to save Account: {:?}", e).into(),
Position::NONE,
))
})
},
);
let db_get_account = Arc::clone(&db);
db_module.set_native_fn(
"get_account_by_id",
move |id_rhai: INT| -> Result<Dynamic, Box<EvalAltResult>> {
let id_u32 = id_from_i64_to_u32(id_rhai)?;
let collection = db_get_account.collection::<Account>().map_err(|e| {
Box::new(EvalAltResult::ErrorRuntime(
format!("Failed to get Account collection: {:?}", e).into(),
Position::NONE,
))
})?;
collection
.get_by_id(id_u32)
.map(|opt_account| {
opt_account
.map(Dynamic::from)
.unwrap_or_else(|| Dynamic::UNIT)
})
.map_err(|e| {
Box::new(EvalAltResult::ErrorRuntime(
format!("Failed to get Account with ID {}: {:?}", id_rhai, e).into(),
Position::NONE,
))
})
},
);
// Asset DB functions
let db_set_asset = Arc::clone(&db);
db_module.set_native_fn(
"set_asset",
move |asset: Asset| -> Result<INT, Box<EvalAltResult>> {
let collection = db_set_asset.collection::<Asset>().map_err(|e| {
Box::new(EvalAltResult::ErrorRuntime(
format!("Failed to get Asset collection: {:?}", e).into(),
Position::NONE,
))
})?;
collection
.set(&asset)
.map(|(id, _)| id as INT)
.map_err(|e| {
Box::new(EvalAltResult::ErrorRuntime(
format!("Failed to save Asset: {:?}", e).into(),
Position::NONE,
))
})
},
);
let db_get_asset = Arc::clone(&db);
db_module.set_native_fn(
"get_asset_by_id",
move |id_rhai: INT| -> Result<Dynamic, Box<EvalAltResult>> {
let id_u32 = id_from_i64_to_u32(id_rhai)?;
let collection = db_get_asset.collection::<Asset>().map_err(|e| {
Box::new(EvalAltResult::ErrorRuntime(
format!("Failed to get Asset collection: {:?}", e).into(),
Position::NONE,
))
})?;
collection
.get_by_id(id_u32)
.map(|opt_asset| {
opt_asset
.map(Dynamic::from)
.unwrap_or_else(|| Dynamic::UNIT)
})
.map_err(|e| {
Box::new(EvalAltResult::ErrorRuntime(
format!("Failed to get Asset with ID {}: {:?}", id_rhai, e).into(),
Position::NONE,
))
})
},
);
// Listing DB functions
let db_set_listing = Arc::clone(&db);
db_module.set_native_fn(
"set_listing",
move |listing: Listing| -> Result<INT, Box<EvalAltResult>> {
let collection = db_set_listing.collection::<Listing>().map_err(|e| {
Box::new(EvalAltResult::ErrorRuntime(
format!("Failed to get Listing collection: {:?}", e).into(),
Position::NONE,
))
})?;
collection
.set(&listing)
.map(|(id, _)| id as INT)
.map_err(|e| {
Box::new(EvalAltResult::ErrorRuntime(
format!("Failed to save Listing: {:?}", e).into(),
Position::NONE,
))
})
},
);
let db_get_listing = Arc::clone(&db);
db_module.set_native_fn(
"get_listing_by_id",
move |id_rhai: INT| -> Result<Dynamic, Box<EvalAltResult>> {
let id_u32 = id_from_i64_to_u32(id_rhai)?;
let collection = db_get_listing.collection::<Listing>().map_err(|e| {
Box::new(EvalAltResult::ErrorRuntime(
format!("Failed to get Listing collection: {:?}", e).into(),
Position::NONE,
))
})?;
collection
.get_by_id(id_u32)
.map(|opt_listing| {
opt_listing
.map(Dynamic::from)
.unwrap_or_else(|| Dynamic::UNIT)
})
.map_err(|e| {
Box::new(EvalAltResult::ErrorRuntime(
format!("Failed to get Listing with ID {}: {:?}", id_rhai, e).into(),
Position::NONE,
))
})
},
);
engine.register_global_module(db_module.into());
// Global timestamp function for scripts to get current time
engine.register_fn("timestamp", || Utc::now().timestamp());
println!("Successfully registered finance Rhai module.");
}