improve and add models
This commit is contained in:
parent
c3f6b91aa0
commit
00c4e6a1eb
@ -81,3 +81,8 @@ required-features = ["rhai"]
|
||||
name = "biz_rhai"
|
||||
path = "examples/biz_rhai/example.rs"
|
||||
required-features = ["rhai"]
|
||||
|
||||
[[example]]
|
||||
name = "library_rhai"
|
||||
path = "examples/library_rhai/example.rs"
|
||||
required-features = ["rhai"]
|
||||
|
38
heromodels/examples/library_rhai/example.rs
Normal file
38
heromodels/examples/library_rhai/example.rs
Normal file
@ -0,0 +1,38 @@
|
||||
use heromodels::db::hero::OurDB;
|
||||
use heromodels::models::register_library_rhai_module;
|
||||
use rhai::Engine;
|
||||
use std::sync::Arc;
|
||||
use std::{fs, path::Path};
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Initialize Rhai engine
|
||||
let mut engine = Engine::new();
|
||||
|
||||
// Initialize database with OurDB
|
||||
let db_path = "temp_library_db";
|
||||
// Clean up previous database file if it exists
|
||||
if Path::new(db_path).exists() {
|
||||
fs::remove_dir_all(db_path)?;
|
||||
}
|
||||
let db = Arc::new(OurDB::new(db_path, true).expect("Failed to create database"));
|
||||
|
||||
// Register the library module with Rhai
|
||||
register_library_rhai_module(&mut engine, db.clone());
|
||||
|
||||
// Load and evaluate the Rhai script
|
||||
let script_path = Path::new(file!()).parent().unwrap().join("library.rhai");
|
||||
let script = fs::read_to_string(&script_path)?;
|
||||
|
||||
println!("--- Running Library Rhai Script ---");
|
||||
match engine.eval::<()>(&script) {
|
||||
Ok(_) => println!("\n--- Script executed successfully! ---"),
|
||||
Err(e) => eprintln!("\n--- Script execution failed: {} ---", e),
|
||||
}
|
||||
|
||||
// Clean up the database file
|
||||
fs::remove_dir_all(db_path)?;
|
||||
println!("--- Cleaned up temporary database. ---");
|
||||
|
||||
|
||||
Ok(())
|
||||
}
|
78
heromodels/examples/library_rhai/library.rhai
Normal file
78
heromodels/examples/library_rhai/library.rhai
Normal file
@ -0,0 +1,78 @@
|
||||
// heromodels/examples/library_rhai/library.rhai
|
||||
|
||||
print("--- Testing Library Rhai Module ---");
|
||||
|
||||
// --- Image ---
|
||||
print("\n1. Creating and saving an image...");
|
||||
let my_image = new_image()
|
||||
.title("A Beautiful Sunset")
|
||||
.description("A photo taken from a drone.")
|
||||
.url("https://example.com/sunset.jpg")
|
||||
.width(1920)
|
||||
.height(1080);
|
||||
|
||||
let saved_image = save_image(my_image);
|
||||
print(" > Saved image with ID: " + saved_image.id);
|
||||
let image_id = saved_image.id;
|
||||
|
||||
// --- PDF ---
|
||||
print("\n2. Creating and saving a PDF...");
|
||||
let my_pdf = new_pdf()
|
||||
.title("Rust Programming Guide")
|
||||
.description("A comprehensive guide to Rust.")
|
||||
.url("https://example.com/rust.pdf")
|
||||
.page_count(500);
|
||||
|
||||
let saved_pdf = save_pdf(my_pdf);
|
||||
print(" > Saved PDF with ID: " + saved_pdf.id);
|
||||
let pdf_id = saved_pdf.id;
|
||||
|
||||
// --- Markdown ---
|
||||
print("\n3. Creating and saving a Markdown document...");
|
||||
let my_markdown = new_markdown()
|
||||
.title("Meeting Notes")
|
||||
.description("Notes from the weekly sync.")
|
||||
.content("# Meeting Notes\n\n- Discussed project status.\n- Planned next sprint.");
|
||||
|
||||
let saved_markdown = save_markdown(my_markdown);
|
||||
print(" > Saved Markdown with ID: " + saved_markdown.id);
|
||||
let markdown_id = saved_markdown.id;
|
||||
|
||||
// --- Collection ---
|
||||
print("\n4. Creating a collection and adding items...");
|
||||
let my_collection = new_collection()
|
||||
.title("My Awesome Collection")
|
||||
.description("A collection of various media.")
|
||||
.add_image(image_id)
|
||||
.add_pdf(pdf_id)
|
||||
.add_markdown(markdown_id);
|
||||
|
||||
let saved_collection = save_collection(my_collection);
|
||||
print(" > Saved collection with ID: " + saved_collection.id);
|
||||
let collection_id = saved_collection.id;
|
||||
|
||||
// --- Verification ---
|
||||
print("\n5. Verifying saved data...");
|
||||
let fetched_collection = get_collection(collection_id);
|
||||
print(" > Fetched collection: '" + fetched_collection.title + "'");
|
||||
print(" > Collection contains " + fetched_collection.images + " image(s).");
|
||||
print(" > Collection contains " + fetched_collection.pdfs + " pdf(s).");
|
||||
print(" > Collection contains " + fetched_collection.markdowns + " markdown(s).");
|
||||
|
||||
let fetched_image = get_image(image_id);
|
||||
print(" > Fetched image title: '" + fetched_image.title + "'");
|
||||
if (fetched_image.url != "https://example.com/sunset.jpg") {
|
||||
throw "Image URL mismatch!";
|
||||
}
|
||||
print(" > Image URL verified.");
|
||||
|
||||
// --- Deletion ---
|
||||
print("\n6. Cleaning up database...");
|
||||
delete_image(image_id);
|
||||
print(" > Deleted image with ID: " + image_id);
|
||||
delete_pdf(pdf_id);
|
||||
print(" > Deleted PDF with ID: " + pdf_id);
|
||||
delete_markdown(markdown_id);
|
||||
print(" > Deleted Markdown with ID: " + markdown_id);
|
||||
delete_collection(collection_id);
|
||||
print(" > Deleted collection with ID: " + collection_id);
|
@ -1,5 +1,5 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use heromodels_core::{BaseModelData, Model, IndexKey, IndexKeyBuilder, Index};
|
||||
use heromodels_core::{BaseModelData, Index};
|
||||
use rhai::{CustomType, TypeBuilder}; // For #[derive(CustomType)]
|
||||
use heromodels_core::BaseModelDataOps;
|
||||
use heromodels_derive::model;
|
||||
|
@ -1,7 +1,5 @@
|
||||
use serde::{Serialize, Deserialize};
|
||||
use heromodels_core::BaseModelData;
|
||||
use heromodels_core::Model;
|
||||
use heromodels_core::BaseModelDataOps;
|
||||
use heromodels_derive::model;
|
||||
|
||||
// ProductType represents the type of a product
|
||||
|
@ -1,5 +1,5 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use heromodels_core::{BaseModelData, Model, BaseModelDataOps};
|
||||
use heromodels_core::BaseModelData;
|
||||
use heromodels_derive::model;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
|
@ -1,4 +1,3 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
use heromodels_core::BaseModelData;
|
||||
use heromodels_derive::model;
|
||||
// Temporarily removed to fix compilation issues
|
||||
|
@ -2,7 +2,6 @@ use rhai::plugin::*;
|
||||
use rhai::{Engine, EvalAltResult, Position, Module, INT, Dynamic, Array};
|
||||
use std::sync::Arc;
|
||||
use std::mem;
|
||||
use chrono::{DateTime, Utc};
|
||||
use crate::db::Db;
|
||||
|
||||
use super::calendar::{Event, Attendee, Calendar, AttendanceStatus};
|
||||
@ -22,16 +21,6 @@ fn id_from_i64_to_u32(id_i64: i64) -> Result<u32, Box<EvalAltResult>> {
|
||||
)
|
||||
}
|
||||
|
||||
// Helper to convert i64 from Rhai to u64 for timestamps or other large numbers
|
||||
fn val_from_i64_to_u64(val_i64: i64) -> Result<u64, Box<EvalAltResult>> {
|
||||
u64::try_from(val_i64).map_err(|_|
|
||||
Box::new(EvalAltResult::ErrorArithmetic(
|
||||
format!("Failed to convert value '{}' to u64", val_i64).into(),
|
||||
Position::NONE
|
||||
))
|
||||
)
|
||||
}
|
||||
|
||||
#[export_module]
|
||||
mod rhai_calendar_module {
|
||||
// --- Event Functions ---
|
||||
|
86
heromodels/src/models/circle/circle.rs
Normal file
86
heromodels/src/models/circle/circle.rs
Normal file
@ -0,0 +1,86 @@
|
||||
use heromodels_core::BaseModelData;
|
||||
use heromodels_derive::model;
|
||||
// Temporarily removed to fix compilation issues
|
||||
// use rhai_autobind_macros::rhai_model_export;
|
||||
use rhai::{CustomType, TypeBuilder};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// Represents an event in a calendar
|
||||
#[model]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, CustomType, Default)]
|
||||
pub struct Circle {
|
||||
/// Base model data
|
||||
pub base_data: BaseModelData,
|
||||
#[index]
|
||||
pub title: String,
|
||||
pub ws_url: String,
|
||||
/// Optional description of the circle
|
||||
pub description: Option<String>,
|
||||
/// List of related circles
|
||||
pub circles: Vec<String>,
|
||||
/// Logo URL or symbol for the circle
|
||||
pub logo: Option<String>,
|
||||
/// Theme settings for the circle (colors, styling, etc.)
|
||||
pub theme: HashMap<String, String>,
|
||||
}
|
||||
|
||||
impl Circle {
|
||||
/// Creates a new circle
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
base_data: BaseModelData::new(),
|
||||
title: String::new(),
|
||||
ws_url: String::new(),
|
||||
description: None,
|
||||
circles: Vec::new(),
|
||||
logo: None,
|
||||
theme: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the title for the circle
|
||||
pub fn title(mut self, title: impl ToString) -> Self {
|
||||
self.title = title.to_string();
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the ws_url for the circle
|
||||
pub fn ws_url(mut self, ws_url: impl ToString) -> Self {
|
||||
self.ws_url = ws_url.to_string();
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the description for the circle
|
||||
pub fn description(mut self, description: impl ToString) -> Self {
|
||||
self.description = Some(description.to_string());
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the logo for the circle
|
||||
pub fn logo(mut self, logo: impl ToString) -> Self {
|
||||
self.logo = Some(logo.to_string());
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets a theme property for the circle
|
||||
pub fn theme_property(mut self, key: impl ToString, value: impl ToString) -> Self {
|
||||
self.theme.insert(key.to_string(), value.to_string());
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the entire theme for the circle
|
||||
pub fn theme(mut self, theme: HashMap<String, String>) -> Self {
|
||||
self.theme = theme;
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds a related circle
|
||||
pub fn add_circle(mut self, circle: String) -> Self {
|
||||
// Prevent duplicate circles
|
||||
if !self.circles.iter().any(|a| *a == circle) {
|
||||
self.circles.push(circle);
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
7
heromodels/src/models/circle/mod.rs
Normal file
7
heromodels/src/models/circle/mod.rs
Normal file
@ -0,0 +1,7 @@
|
||||
// Export calendar module
|
||||
pub mod circle;
|
||||
pub mod rhai;
|
||||
|
||||
// Re-export Calendar, Event, Attendee, and AttendanceStatus from the inner calendar module (calendar.rs) within src/models/calendar/mod.rs
|
||||
pub use self::circle::{Circle};
|
||||
pub use rhai::register_circle_rhai_module;
|
201
heromodels/src/models/circle/rhai.rs
Normal file
201
heromodels/src/models/circle/rhai.rs
Normal file
@ -0,0 +1,201 @@
|
||||
use rhai::plugin::*;
|
||||
use rhai::{Engine, EvalAltResult, Position, Module, INT, Dynamic, Array, CustomType};
|
||||
use std::sync::Arc;
|
||||
use std::mem;
|
||||
use crate::db::Db;
|
||||
|
||||
use super::circle::{Circle};
|
||||
type RhaiCircle = Circle;
|
||||
use crate::db::hero::OurDB;
|
||||
use crate::db::Collection;
|
||||
use serde::Serialize;
|
||||
use std::collections::HashMap;
|
||||
use serde_json;
|
||||
|
||||
/// Registers a `.json()` method for any type `T` that implements the required traits.
|
||||
fn register_json_method<T>(engine: &mut Engine)
|
||||
where
|
||||
// The type must be:
|
||||
T: CustomType + Clone + Serialize, // A clonable, serializable, custom type for Rhai
|
||||
{
|
||||
// This is the function that will be called when a script runs '.json()'
|
||||
let to_json_fn = |obj: &mut T| -> Result<String, Box<EvalAltResult>> {
|
||||
// Use serde_json to serialize the object to a pretty-formatted string.
|
||||
// The '?' will automatically convert any serialization error into a Rhai error.
|
||||
serde_json::to_string(obj).map_err(|e| e.to_string().into())
|
||||
};
|
||||
|
||||
// Register the function as a method named "json" for the type 'T'.
|
||||
engine.build_type::<T>().register_fn("json", to_json_fn);
|
||||
}
|
||||
|
||||
// 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
|
||||
))
|
||||
)
|
||||
}
|
||||
|
||||
#[export_module]
|
||||
mod rhai_circle_module {
|
||||
// --- Circle Functions ---
|
||||
#[rhai_fn(name = "new_circle")]
|
||||
pub fn new_circle() -> RhaiCircle {
|
||||
Circle::new()
|
||||
}
|
||||
|
||||
/// Sets the circle title
|
||||
#[rhai_fn(name = "title", return_raw, global, pure)]
|
||||
pub fn circle_title(circle: &mut RhaiCircle, title: String) -> Result<RhaiCircle, Box<EvalAltResult>> {
|
||||
let owned_circle = mem::take(circle);
|
||||
*circle = owned_circle.title(title);
|
||||
Ok(circle.clone())
|
||||
}
|
||||
|
||||
/// Sets the circle ws_url
|
||||
#[rhai_fn(name = "ws_url", return_raw, global, pure)]
|
||||
pub fn circle_ws_url(circle: &mut RhaiCircle, ws_url: String) -> Result<RhaiCircle, Box<EvalAltResult>> {
|
||||
let owned_circle = mem::take(circle);
|
||||
*circle = owned_circle.ws_url(ws_url);
|
||||
Ok(circle.clone())
|
||||
}
|
||||
|
||||
/// Sets the circle description
|
||||
#[rhai_fn(name = "description", return_raw, global, pure)]
|
||||
pub fn circle_description(circle: &mut RhaiCircle, description: String) -> Result<RhaiCircle, Box<EvalAltResult>> {
|
||||
let owned_circle = mem::take(circle);
|
||||
*circle = owned_circle.description(description);
|
||||
Ok(circle.clone())
|
||||
}
|
||||
|
||||
/// Sets the circle logo
|
||||
#[rhai_fn(name = "logo", return_raw, global, pure)]
|
||||
pub fn circle_logo(circle: &mut RhaiCircle, logo: String) -> Result<RhaiCircle, Box<EvalAltResult>> {
|
||||
let owned_circle = mem::take(circle);
|
||||
*circle = owned_circle.logo(logo);
|
||||
Ok(circle.clone())
|
||||
}
|
||||
|
||||
/// Sets the circle theme
|
||||
#[rhai_fn(name = "theme", return_raw, global, pure)]
|
||||
pub fn circle_theme(circle: &mut RhaiCircle, theme: HashMap<String, String>) -> Result<RhaiCircle, Box<EvalAltResult>> {
|
||||
let owned_circle = mem::take(circle);
|
||||
*circle = owned_circle.theme(theme);
|
||||
Ok(circle.clone())
|
||||
}
|
||||
|
||||
/// Adds an attendee to the circle
|
||||
#[rhai_fn(name = "add_circle", return_raw, global, pure)]
|
||||
pub fn circle_add_circle(circle: &mut RhaiCircle, added_circle: String) -> Result<RhaiCircle, Box<EvalAltResult>> {
|
||||
// Use take to get ownership of the circle
|
||||
let owned_circle = mem::take(circle);
|
||||
*circle = owned_circle.add_circle(added_circle);
|
||||
Ok(circle.clone())
|
||||
}
|
||||
|
||||
// Circle Getters
|
||||
#[rhai_fn(get = "id", pure)]
|
||||
pub fn get_circle_id(circle: &mut RhaiCircle) -> i64 { circle.base_data.id as i64 }
|
||||
#[rhai_fn(get = "created_at", pure)]
|
||||
pub fn get_circle_created_at(circle: &mut RhaiCircle) -> i64 { circle.base_data.created_at }
|
||||
#[rhai_fn(get = "modified_at", pure)]
|
||||
pub fn get_circle_modified_at(circle: &mut RhaiCircle) -> i64 { circle.base_data.modified_at }
|
||||
|
||||
#[rhai_fn(get = "title", pure)]
|
||||
pub fn get_circle_title(circle: &mut RhaiCircle) -> String { circle.title.clone() }
|
||||
#[rhai_fn(get = "description", pure)]
|
||||
pub fn get_circle_description(circle: &mut RhaiCircle) -> Option<String> { circle.description.clone() }
|
||||
#[rhai_fn(get = "circles", pure)]
|
||||
pub fn get_circle_circles(circle: &mut RhaiCircle) -> Vec<String> { circle.circles.clone() }
|
||||
#[rhai_fn(get = "ws_url", pure)]
|
||||
pub fn get_circle_ws_url(circle: &mut RhaiCircle) -> String { circle.ws_url.clone() }
|
||||
#[rhai_fn(get = "logo", pure)]
|
||||
pub fn get_circle_logo(circle: &mut RhaiCircle) -> Option<String> { circle.logo.clone() }
|
||||
#[rhai_fn(get = "theme", pure)]
|
||||
pub fn get_circle_theme(circle: &mut RhaiCircle) -> HashMap<String, String> { circle.theme.clone() }
|
||||
}
|
||||
|
||||
pub fn register_circle_rhai_module(engine: &mut Engine, db: Arc<OurDB>) {
|
||||
// Register the exported module globally
|
||||
let module = exported_module!(rhai_circle_module);
|
||||
engine.register_global_module(module.into());
|
||||
|
||||
// Create a module for database functions
|
||||
let mut db_module = Module::new();
|
||||
|
||||
// Manually register database functions as they need to capture 'db'
|
||||
let db_clone_set_circle = db.clone();
|
||||
db_module.set_native_fn("save_circle", move |circle: Circle| -> Result<Circle, Box<EvalAltResult>> {
|
||||
// Use the Collection trait method directly
|
||||
let result = db_clone_set_circle.set(&circle)
|
||||
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error set_circle: {}", e).into(), Position::NONE)))?;
|
||||
|
||||
// Return the updated circle with the correct ID
|
||||
Ok(result.1)
|
||||
});
|
||||
|
||||
register_json_method::<Circle>(engine);
|
||||
|
||||
// Manually register database functions as they need to capture 'db'
|
||||
let db_clone_delete_circle = db.clone();
|
||||
db_module.set_native_fn("delete_circle", move |circle: Circle| -> Result<(), Box<EvalAltResult>> {
|
||||
// Use the Collection trait method directly
|
||||
let result = db_clone_delete_circle.collection::<Circle>()
|
||||
.expect("can open circle collection")
|
||||
.delete_by_id(circle.base_data.id)
|
||||
.expect("can delete circle");
|
||||
|
||||
// Return the updated circle with the correct ID
|
||||
Ok(result)
|
||||
});
|
||||
|
||||
let db_clone_get_circle = db.clone();
|
||||
db_module.set_native_fn("get_circle", move || -> Result<Circle, Box<EvalAltResult>> {
|
||||
// Use the Collection trait method directly
|
||||
let all_circles: Vec<Circle> = db_clone_get_circle.get_all()
|
||||
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error get_circle: {}", e).into(), Position::NONE)))?;
|
||||
|
||||
if let Some(first_circle) = all_circles.first() {
|
||||
Ok(first_circle.clone())
|
||||
} else {
|
||||
Err(Box::new(EvalAltResult::ErrorRuntime("Circle not found".into(), Position::NONE)))
|
||||
}
|
||||
});
|
||||
|
||||
let db_clone_get_circle_by_id = db.clone();
|
||||
db_module.set_native_fn("get_circle_by_id", move |id_i64: INT| -> Result<Circle, Box<EvalAltResult>> {
|
||||
let id_u32 = id_from_i64_to_u32(id_i64)?;
|
||||
// Use the Collection trait method directly
|
||||
db_clone_get_circle_by_id.get_by_id(id_u32)
|
||||
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error get_circle_by_id: {}", e).into(), Position::NONE)))?
|
||||
.ok_or_else(|| Box::new(EvalAltResult::ErrorRuntime(format!("Circle with ID {} not found", id_u32).into(), Position::NONE)))
|
||||
});
|
||||
|
||||
// Add list_circles function to get all circles
|
||||
let db_clone_list_circles = db.clone();
|
||||
db_module.set_native_fn("list_circles", move || -> Result<Dynamic, Box<EvalAltResult>> {
|
||||
let collection = db_clone_list_circles.collection::<Circle>()
|
||||
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(
|
||||
format!("Failed to get circle collection: {:?}", e).into(),
|
||||
Position::NONE
|
||||
)))?;
|
||||
let circles = collection.get_all()
|
||||
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(
|
||||
format!("Failed to get all circles: {:?}", e).into(),
|
||||
Position::NONE
|
||||
)))?;
|
||||
let mut array = Array::new();
|
||||
for circle in circles {
|
||||
array.push(Dynamic::from(circle));
|
||||
}
|
||||
Ok(Dynamic::from(array))
|
||||
});
|
||||
|
||||
// Register the database module globally
|
||||
engine.register_global_module(db_module.into());
|
||||
|
||||
println!("Successfully registered circle Rhai module using export_module approach.");
|
||||
}
|
@ -80,13 +80,13 @@ impl Account {
|
||||
|
||||
/// Get the total value of all assets in the account
|
||||
pub fn total_value(&self) -> f64 {
|
||||
/// TODO: implement
|
||||
// TODO: implement
|
||||
0.0
|
||||
}
|
||||
|
||||
/// Find an asset by name
|
||||
pub fn find_asset_by_name(&self, name: &str) -> Option<&Asset> {
|
||||
/// TODO: implement
|
||||
pub fn find_asset_by_name(&self, _name: &str) -> Option<&Asset> {
|
||||
// TODO: implement
|
||||
return None
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use rhai::plugin::*;
|
||||
use rhai::{Engine, EvalAltResult, Position, Module, INT, Dynamic, Array};
|
||||
use std::sync::Arc;
|
||||
use std::mem;
|
||||
use chrono::{DateTime, Utc};
|
||||
use chrono::Utc;
|
||||
|
||||
use super::account::Account;
|
||||
use super::asset::{Asset, AssetType};
|
||||
@ -10,7 +10,6 @@ use super::marketplace::{Listing, Bid, ListingStatus, ListingType, BidStatus};
|
||||
|
||||
use crate::db::hero::OurDB;
|
||||
use crate::db::{Collection, Db};
|
||||
use heromodels_core::Model;
|
||||
|
||||
type RhaiAccount = Account;
|
||||
type RhaiAsset = Asset;
|
||||
@ -689,18 +688,8 @@ mod bid_module {
|
||||
Ok(bid.clone())
|
||||
}
|
||||
}
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Mutex;
|
||||
use rhai::ImmutableString;
|
||||
|
||||
// Custom error type for Rhai
|
||||
struct RhaiStringError(String);
|
||||
impl std::fmt::Debug for RhaiStringError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
// 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 ---
|
||||
|
@ -12,7 +12,6 @@ type RhaiSignatureRequirement = SignatureRequirement;
|
||||
use crate::db::hero::OurDB;
|
||||
use crate::db::Collection;
|
||||
use crate::db::Db;
|
||||
use heromodels_core::Model;
|
||||
|
||||
// Helper to convert i64 from Rhai to u32 for IDs
|
||||
fn id_from_i64_to_u32(id_i64: i64) -> Result<u32, Box<EvalAltResult>> {
|
||||
@ -24,16 +23,6 @@ fn id_from_i64_to_u32(id_i64: i64) -> Result<u32, Box<EvalAltResult>> {
|
||||
)
|
||||
}
|
||||
|
||||
// Helper to convert i64 from Rhai to u64 for timestamps or other large numbers
|
||||
fn val_from_i64_to_u64(val_i64: i64) -> Result<u64, Box<EvalAltResult>> {
|
||||
u64::try_from(val_i64).map_err(|_|
|
||||
Box::new(EvalAltResult::ErrorArithmetic(
|
||||
format!("Failed to convert value '{}' to u64", val_i64).into(),
|
||||
Position::NONE
|
||||
))
|
||||
)
|
||||
}
|
||||
|
||||
#[export_module]
|
||||
mod rhai_flow_module {
|
||||
// --- Flow Functions ---
|
||||
|
91
heromodels/src/models/library/collection.rs
Normal file
91
heromodels/src/models/library/collection.rs
Normal file
@ -0,0 +1,91 @@
|
||||
use heromodels_core::BaseModelData;
|
||||
use heromodels_derive::model;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use rhai::{CustomType, TypeBuilder};
|
||||
|
||||
/// Represents a collection of library items.
|
||||
#[model]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, CustomType)]
|
||||
pub struct Collection {
|
||||
/// Base model data
|
||||
pub base_data: BaseModelData,
|
||||
/// Title of the collection
|
||||
#[index]
|
||||
pub title: String,
|
||||
/// Optional description of the collection
|
||||
pub description: Option<String>,
|
||||
/// List of image item IDs belonging to this collection
|
||||
pub images: Vec<u32>,
|
||||
/// List of PDF item IDs belonging to this collection
|
||||
pub pdfs: Vec<u32>,
|
||||
/// List of Markdown item IDs belonging to this collection
|
||||
pub markdowns: Vec<u32>,
|
||||
/// List of Book item IDs belonging to this collection
|
||||
pub books: Vec<u32>,
|
||||
/// List of Slides item IDs belonging to this collection
|
||||
pub slides: Vec<u32>,
|
||||
}
|
||||
|
||||
impl Default for Collection {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
base_data: BaseModelData::new(),
|
||||
title: String::new(),
|
||||
description: None,
|
||||
images: Vec::new(),
|
||||
pdfs: Vec::new(),
|
||||
markdowns: Vec::new(),
|
||||
books: Vec::new(),
|
||||
slides: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Collection {
|
||||
/// Creates a new `Collection` with default values.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Sets the title of the collection.
|
||||
pub fn title(mut self, title: impl Into<String>) -> Self {
|
||||
self.title = title.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the description of the collection.
|
||||
pub fn description(mut self, description: impl Into<String>) -> Self {
|
||||
self.description = Some(description.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds an image ID to the collection.
|
||||
pub fn add_image(mut self, image_id: u32) -> Self {
|
||||
self.images.push(image_id);
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds a PDF ID to the collection.
|
||||
pub fn add_pdf(mut self, pdf_id: u32) -> Self {
|
||||
self.pdfs.push(pdf_id);
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds a markdown ID to the collection.
|
||||
pub fn add_markdown(mut self, markdown_id: u32) -> Self {
|
||||
self.markdowns.push(markdown_id);
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds a book ID to the collection.
|
||||
pub fn add_book(mut self, book_id: u32) -> Self {
|
||||
self.books.push(book_id);
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds a slides ID to the collection.
|
||||
pub fn add_slides(mut self, slides_id: u32) -> Self {
|
||||
self.slides.push(slides_id);
|
||||
self
|
||||
}
|
||||
}
|
369
heromodels/src/models/library/items.rs
Normal file
369
heromodels/src/models/library/items.rs
Normal file
@ -0,0 +1,369 @@
|
||||
use heromodels_core::BaseModelData;
|
||||
use heromodels_derive::model;
|
||||
use rhai::{CustomType, TypeBuilder};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Represents an Image library item.
|
||||
#[model]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, CustomType)]
|
||||
pub struct Image {
|
||||
/// Base model data
|
||||
pub base_data: BaseModelData,
|
||||
/// Title of the image
|
||||
#[index]
|
||||
pub title: String,
|
||||
/// Optional description of the image
|
||||
pub description: Option<String>,
|
||||
/// URL of the image
|
||||
pub url: String,
|
||||
/// Width of the image in pixels
|
||||
pub width: u32,
|
||||
/// Height of the image in pixels
|
||||
pub height: u32,
|
||||
}
|
||||
|
||||
impl Default for Image {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
base_data: BaseModelData::new(),
|
||||
title: String::new(),
|
||||
description: None,
|
||||
url: String::new(),
|
||||
width: 0,
|
||||
height: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Image {
|
||||
/// Creates a new `Image` with default values.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Sets the title of the image.
|
||||
pub fn title(mut self, title: impl Into<String>) -> Self {
|
||||
self.title = title.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the description of the image.
|
||||
pub fn description(mut self, description: impl Into<String>) -> Self {
|
||||
self.description = Some(description.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the URL of the image.
|
||||
pub fn url(mut self, url: impl Into<String>) -> Self {
|
||||
self.url = url.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the width of the image.
|
||||
pub fn width(mut self, width: u32) -> Self {
|
||||
self.width = width;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the height of the image.
|
||||
pub fn height(mut self, height: u32) -> Self {
|
||||
self.height = height;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a PDF document library item.
|
||||
#[model]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, CustomType)]
|
||||
pub struct Pdf {
|
||||
/// Base model data
|
||||
pub base_data: BaseModelData,
|
||||
/// Title of the PDF
|
||||
#[index]
|
||||
pub title: String,
|
||||
/// Optional description of the PDF
|
||||
pub description: Option<String>,
|
||||
/// URL of the PDF file
|
||||
pub url: String,
|
||||
/// Number of pages in the PDF
|
||||
pub page_count: u32,
|
||||
}
|
||||
|
||||
impl Default for Pdf {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
base_data: BaseModelData::new(),
|
||||
title: String::new(),
|
||||
description: None,
|
||||
url: String::new(),
|
||||
page_count: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Pdf {
|
||||
/// Creates a new `Pdf` with default values.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Sets the title of the PDF.
|
||||
pub fn title(mut self, title: impl Into<String>) -> Self {
|
||||
self.title = title.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the description of the PDF.
|
||||
pub fn description(mut self, description: impl Into<String>) -> Self {
|
||||
self.description = Some(description.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the URL of the PDF.
|
||||
pub fn url(mut self, url: impl Into<String>) -> Self {
|
||||
self.url = url.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the page count of the PDF.
|
||||
pub fn page_count(mut self, page_count: u32) -> Self {
|
||||
self.page_count = page_count;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a Markdown document library item.
|
||||
#[model]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, CustomType)]
|
||||
pub struct Markdown {
|
||||
/// Base model data
|
||||
pub base_data: BaseModelData,
|
||||
/// Title of the document
|
||||
#[index]
|
||||
pub title: String,
|
||||
/// Optional description of the document
|
||||
pub description: Option<String>,
|
||||
/// The markdown content
|
||||
pub content: String,
|
||||
}
|
||||
|
||||
impl Default for Markdown {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
base_data: BaseModelData::new(),
|
||||
title: String::new(),
|
||||
description: None,
|
||||
content: String::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Markdown {
|
||||
/// Creates a new `Markdown` document with default values.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Sets the title of the document.
|
||||
pub fn title(mut self, title: impl Into<String>) -> Self {
|
||||
self.title = title.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the description of the document.
|
||||
pub fn description(mut self, description: impl Into<String>) -> Self {
|
||||
self.description = Some(description.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the content of the document.
|
||||
pub fn content(mut self, content: impl Into<String>) -> Self {
|
||||
self.content = content.into();
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a table of contents entry for a book.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, CustomType)]
|
||||
pub struct TocEntry {
|
||||
/// Title of the chapter/section
|
||||
pub title: String,
|
||||
/// Page number (index in the pages array)
|
||||
pub page: u32,
|
||||
/// Optional subsections
|
||||
pub subsections: Vec<TocEntry>,
|
||||
}
|
||||
|
||||
impl Default for TocEntry {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
title: String::new(),
|
||||
page: 0,
|
||||
subsections: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TocEntry {
|
||||
/// Creates a new `TocEntry` with default values.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Sets the title of the TOC entry.
|
||||
pub fn title(mut self, title: impl Into<String>) -> Self {
|
||||
self.title = title.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the page number of the TOC entry.
|
||||
pub fn page(mut self, page: u32) -> Self {
|
||||
self.page = page;
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds a subsection to the TOC entry.
|
||||
pub fn add_subsection(mut self, subsection: TocEntry) -> Self {
|
||||
self.subsections.push(subsection);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a Book library item (collection of markdown pages with TOC).
|
||||
#[model]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, CustomType)]
|
||||
pub struct Book {
|
||||
/// Base model data
|
||||
pub base_data: BaseModelData,
|
||||
/// Title of the book
|
||||
#[index]
|
||||
pub title: String,
|
||||
/// Optional description of the book
|
||||
pub description: Option<String>,
|
||||
/// Table of contents
|
||||
pub table_of_contents: Vec<TocEntry>,
|
||||
/// Pages content (markdown strings)
|
||||
pub pages: Vec<String>,
|
||||
}
|
||||
|
||||
impl Default for Book {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
base_data: BaseModelData::new(),
|
||||
title: String::new(),
|
||||
description: None,
|
||||
table_of_contents: Vec::new(),
|
||||
pages: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Book {
|
||||
/// Creates a new `Book` with default values.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Sets the title of the book.
|
||||
pub fn title(mut self, title: impl Into<String>) -> Self {
|
||||
self.title = title.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the description of the book.
|
||||
pub fn description(mut self, description: impl Into<String>) -> Self {
|
||||
self.description = Some(description.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds a page to the book.
|
||||
pub fn add_page(mut self, content: impl Into<String>) -> Self {
|
||||
self.pages.push(content.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds a TOC entry to the book.
|
||||
pub fn add_toc_entry(mut self, entry: TocEntry) -> Self {
|
||||
self.table_of_contents.push(entry);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the table of contents.
|
||||
pub fn table_of_contents(mut self, toc: Vec<TocEntry>) -> Self {
|
||||
self.table_of_contents = toc;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets all pages at once.
|
||||
pub fn pages(mut self, pages: Vec<String>) -> Self {
|
||||
self.pages = pages;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a Slides library item (collection of images for slideshow).
|
||||
#[model]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, CustomType)]
|
||||
pub struct Slides {
|
||||
/// Base model data
|
||||
pub base_data: BaseModelData,
|
||||
/// Title of the slideshow
|
||||
#[index]
|
||||
pub title: String,
|
||||
/// Optional description of the slideshow
|
||||
pub description: Option<String>,
|
||||
/// List of slide image URLs
|
||||
pub slide_urls: Vec<String>,
|
||||
/// Optional slide titles/captions
|
||||
pub slide_titles: Vec<Option<String>>,
|
||||
}
|
||||
|
||||
impl Default for Slides {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
base_data: BaseModelData::new(),
|
||||
title: String::new(),
|
||||
description: None,
|
||||
slide_urls: Vec::new(),
|
||||
slide_titles: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Slides {
|
||||
/// Creates a new `Slides` with default values.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Sets the title of the slideshow.
|
||||
pub fn title(mut self, title: impl Into<String>) -> Self {
|
||||
self.title = title.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the description of the slideshow.
|
||||
pub fn description(mut self, description: impl Into<String>) -> Self {
|
||||
self.description = Some(description.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds a slide with URL and optional title.
|
||||
pub fn add_slide(mut self, url: impl Into<String>, title: Option<String>) -> Self {
|
||||
self.slide_urls.push(url.into());
|
||||
self.slide_titles.push(title);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets all slide URLs at once.
|
||||
pub fn slide_urls(mut self, urls: Vec<String>) -> Self {
|
||||
self.slide_urls = urls;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets all slide titles at once.
|
||||
pub fn slide_titles(mut self, titles: Vec<Option<String>>) -> Self {
|
||||
self.slide_titles = titles;
|
||||
self
|
||||
}
|
||||
}
|
4
heromodels/src/models/library/mod.rs
Normal file
4
heromodels/src/models/library/mod.rs
Normal file
@ -0,0 +1,4 @@
|
||||
pub mod collection;
|
||||
pub mod items;
|
||||
pub mod rhai;
|
||||
pub use rhai::register_library_rhai_module;
|
626
heromodels/src/models/library/rhai.rs
Normal file
626
heromodels/src/models/library/rhai.rs
Normal file
@ -0,0 +1,626 @@
|
||||
use rhai::plugin::*;
|
||||
use rhai::{Engine, EvalAltResult, CustomType, TypeBuilder, Position, Module, Dynamic, Array};
|
||||
use std::sync::Arc;
|
||||
use std::mem;
|
||||
use crate::db::Db;
|
||||
use serde::Serialize;
|
||||
use serde_json;
|
||||
|
||||
|
||||
use super::collection::{Collection as RhaiCollection};
|
||||
use super::items::{Image as RhaiImage, Pdf as RhaiPdf, Markdown as RhaiMarkdown, Book as RhaiBook, Slides as RhaiSlides, TocEntry as RhaiTocEntry};
|
||||
use crate::db::hero::OurDB;
|
||||
use crate::db::Collection as DbCollectionTrait;
|
||||
|
||||
// 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::ErrorMismatchDataType(
|
||||
"u32".to_string(), // Expected type
|
||||
format!("i64 value ({}) that cannot be represented as u32", id_i64), // Actual type/value description
|
||||
Position::NONE
|
||||
))
|
||||
)
|
||||
}
|
||||
|
||||
/// Registers a `.json()` method for any type `T` that implements the required traits.
|
||||
fn register_json_method<T>(engine: &mut Engine)
|
||||
where
|
||||
// The type must be:
|
||||
T: CustomType + Clone + Serialize, // A clonable, serializable, custom type for Rhai
|
||||
{
|
||||
// This is the function that will be called when a script runs '.json()'
|
||||
let to_json_fn = |obj: &mut T| -> Result<String, Box<EvalAltResult>> {
|
||||
// Use serde_json to serialize the object to a pretty-formatted string.
|
||||
// The '?' will automatically convert any serialization error into a Rhai error.
|
||||
serde_json::to_string(obj).map_err(|e| e.to_string().into())
|
||||
};
|
||||
|
||||
// Register the function as a method named "json" for the type 'T'.
|
||||
engine.build_type::<T>().register_fn("json", to_json_fn);
|
||||
}
|
||||
|
||||
// Wrapper type for a list of collections to enable .json() method via register_json_method
|
||||
#[derive(Debug, Clone, Serialize, CustomType)]
|
||||
#[rhai_type(name = "CollectionArray")]
|
||||
pub struct RhaiCollectionArray(pub Vec<RhaiCollection>);
|
||||
|
||||
|
||||
#[export_module]
|
||||
mod rhai_library_module {
|
||||
// --- Collection Functions ---
|
||||
#[rhai_fn(name = "new_collection")]
|
||||
pub fn new_collection() -> RhaiCollection {
|
||||
RhaiCollection::new()
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "title", return_raw, global, pure)]
|
||||
pub fn collection_title(collection: &mut RhaiCollection, title: String) -> Result<RhaiCollection, Box<EvalAltResult>> {
|
||||
let owned = mem::take(collection);
|
||||
*collection = owned.title(title);
|
||||
Ok(collection.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "description", return_raw, global, pure)]
|
||||
pub fn collection_description(collection: &mut RhaiCollection, description: String) -> Result<RhaiCollection, Box<EvalAltResult>> {
|
||||
let owned = mem::take(collection);
|
||||
*collection = owned.description(description);
|
||||
Ok(collection.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "add_image", return_raw, global, pure)]
|
||||
pub fn collection_add_image(collection: &mut RhaiCollection, image_id: i64) -> Result<RhaiCollection, Box<EvalAltResult>> {
|
||||
let id = id_from_i64_to_u32(image_id)?;
|
||||
let owned = mem::take(collection);
|
||||
*collection = owned.add_image(id);
|
||||
Ok(collection.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "add_pdf", return_raw, global, pure)]
|
||||
pub fn collection_add_pdf(collection: &mut RhaiCollection, pdf_id: i64) -> Result<RhaiCollection, Box<EvalAltResult>> {
|
||||
let id = id_from_i64_to_u32(pdf_id)?;
|
||||
let owned = mem::take(collection);
|
||||
*collection = owned.add_pdf(id);
|
||||
Ok(collection.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "add_markdown", return_raw, global, pure)]
|
||||
pub fn collection_add_markdown(collection: &mut RhaiCollection, markdown_id: i64) -> Result<RhaiCollection, Box<EvalAltResult>> {
|
||||
let id = id_from_i64_to_u32(markdown_id)?;
|
||||
let owned = mem::take(collection);
|
||||
*collection = owned.add_markdown(id);
|
||||
Ok(collection.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "add_book", return_raw, global, pure)]
|
||||
pub fn collection_add_book(collection: &mut RhaiCollection, book_id: i64) -> Result<RhaiCollection, Box<EvalAltResult>> {
|
||||
let id = id_from_i64_to_u32(book_id)?;
|
||||
let owned = mem::take(collection);
|
||||
*collection = owned.add_book(id);
|
||||
Ok(collection.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "add_slides", return_raw, global, pure)]
|
||||
pub fn collection_add_slides(collection: &mut RhaiCollection, slides_id: i64) -> Result<RhaiCollection, Box<EvalAltResult>> {
|
||||
let id = id_from_i64_to_u32(slides_id)?;
|
||||
let owned = mem::take(collection);
|
||||
*collection = owned.add_slides(id);
|
||||
Ok(collection.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(get = "id", pure)]
|
||||
pub fn get_collection_id(collection: &mut RhaiCollection) -> i64 { collection.base_data.id as i64 }
|
||||
|
||||
#[rhai_fn(get = "created_at", pure)]
|
||||
pub fn get_collection_created_at(collection: &mut RhaiCollection) -> i64 { collection.base_data.created_at }
|
||||
|
||||
#[rhai_fn(get = "modified_at", pure)]
|
||||
pub fn get_collection_modified_at(collection: &mut RhaiCollection) -> i64 { collection.base_data.modified_at }
|
||||
|
||||
#[rhai_fn(get = "title", pure)]
|
||||
pub fn get_collection_title(collection: &mut RhaiCollection) -> String { collection.title.clone() }
|
||||
|
||||
#[rhai_fn(get = "description", pure)]
|
||||
pub fn get_collection_description(collection: &mut RhaiCollection) -> Option<String> { collection.description.clone() }
|
||||
|
||||
#[rhai_fn(get = "images", pure)]
|
||||
pub fn get_collection_images(collection: &mut RhaiCollection) -> Vec<i64> { collection.images.clone().into_iter().map(|id| id as i64).collect() }
|
||||
|
||||
#[rhai_fn(get = "pdfs", pure)]
|
||||
pub fn get_collection_pdfs(collection: &mut RhaiCollection) -> Vec<i64> { collection.pdfs.clone().into_iter().map(|id| id as i64).collect() }
|
||||
|
||||
#[rhai_fn(get = "markdowns", pure)]
|
||||
pub fn get_collection_markdowns(collection: &mut RhaiCollection) -> Vec<i64> { collection.markdowns.clone().into_iter().map(|id| id as i64).collect() }
|
||||
|
||||
#[rhai_fn(get = "books", pure)]
|
||||
pub fn get_collection_books(collection: &mut RhaiCollection) -> Vec<i64> { collection.books.clone().into_iter().map(|id| id as i64).collect() }
|
||||
|
||||
#[rhai_fn(get = "slides", pure)]
|
||||
pub fn get_collection_slides(collection: &mut RhaiCollection) -> Vec<i64> { collection.slides.clone().into_iter().map(|id| id as i64).collect() }
|
||||
|
||||
// --- Image Functions ---
|
||||
#[rhai_fn(name = "new_image")]
|
||||
pub fn new_image() -> RhaiImage {
|
||||
RhaiImage::new()
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "title", return_raw, global, pure)]
|
||||
pub fn image_title(image: &mut RhaiImage, title: String) -> Result<RhaiImage, Box<EvalAltResult>> {
|
||||
let owned = mem::take(image);
|
||||
*image = owned.title(title);
|
||||
Ok(image.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "description", return_raw, global, pure)]
|
||||
pub fn image_description(image: &mut RhaiImage, description: String) -> Result<RhaiImage, Box<EvalAltResult>> {
|
||||
let owned = mem::take(image);
|
||||
*image = owned.description(description);
|
||||
Ok(image.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "url", return_raw, global, pure)]
|
||||
pub fn image_url(image: &mut RhaiImage, url: String) -> Result<RhaiImage, Box<EvalAltResult>> {
|
||||
let owned = mem::take(image);
|
||||
*image = owned.url(url);
|
||||
Ok(image.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "width", return_raw, global, pure)]
|
||||
pub fn image_width(image: &mut RhaiImage, width: i64) -> Result<RhaiImage, Box<EvalAltResult>> {
|
||||
let owned = mem::take(image);
|
||||
*image = owned.width(width as u32);
|
||||
Ok(image.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "height", return_raw, global, pure)]
|
||||
pub fn image_height(image: &mut RhaiImage, height: i64) -> Result<RhaiImage, Box<EvalAltResult>> {
|
||||
let owned = mem::take(image);
|
||||
*image = owned.height(height as u32);
|
||||
Ok(image.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(get = "id", pure)]
|
||||
pub fn get_image_id(image: &mut RhaiImage) -> i64 { image.base_data.id as i64 }
|
||||
|
||||
#[rhai_fn(get = "created_at", pure)]
|
||||
pub fn get_image_created_at(image: &mut RhaiImage) -> i64 { image.base_data.created_at }
|
||||
|
||||
#[rhai_fn(get = "modified_at", pure)]
|
||||
pub fn get_image_modified_at(image: &mut RhaiImage) -> i64 { image.base_data.modified_at }
|
||||
|
||||
#[rhai_fn(get = "title", pure)]
|
||||
pub fn get_image_title(image: &mut RhaiImage) -> String { image.title.clone() }
|
||||
|
||||
#[rhai_fn(get = "description", pure)]
|
||||
pub fn get_image_description(image: &mut RhaiImage) -> Option<String> { image.description.clone() }
|
||||
|
||||
#[rhai_fn(get = "url", pure)]
|
||||
pub fn get_image_url(image: &mut RhaiImage) -> String { image.url.clone() }
|
||||
|
||||
#[rhai_fn(get = "width", pure)]
|
||||
pub fn get_image_width(image: &mut RhaiImage) -> u32 { image.width }
|
||||
|
||||
#[rhai_fn(get = "height", pure)]
|
||||
pub fn get_image_height(image: &mut RhaiImage) -> u32 { image.height }
|
||||
|
||||
// --- Pdf Functions ---
|
||||
#[rhai_fn(name = "new_pdf")]
|
||||
pub fn new_pdf() -> RhaiPdf {
|
||||
RhaiPdf::new()
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "title", return_raw, global, pure)]
|
||||
pub fn pdf_title(pdf: &mut RhaiPdf, title: String) -> Result<RhaiPdf, Box<EvalAltResult>> {
|
||||
let owned = mem::take(pdf);
|
||||
*pdf = owned.title(title);
|
||||
Ok(pdf.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "description", return_raw, global, pure)]
|
||||
pub fn pdf_description(pdf: &mut RhaiPdf, description: String) -> Result<RhaiPdf, Box<EvalAltResult>> {
|
||||
let owned = mem::take(pdf);
|
||||
*pdf = owned.description(description);
|
||||
Ok(pdf.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "url", return_raw, global, pure)]
|
||||
pub fn pdf_url(pdf: &mut RhaiPdf, url: String) -> Result<RhaiPdf, Box<EvalAltResult>> {
|
||||
let owned = mem::take(pdf);
|
||||
*pdf = owned.url(url);
|
||||
Ok(pdf.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "page_count", return_raw, global, pure)]
|
||||
pub fn pdf_page_count(pdf: &mut RhaiPdf, page_count: i64) -> Result<RhaiPdf, Box<EvalAltResult>> {
|
||||
let owned = mem::take(pdf);
|
||||
*pdf = owned.page_count(page_count as u32);
|
||||
Ok(pdf.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(get = "id", pure)]
|
||||
pub fn get_pdf_id(pdf: &mut RhaiPdf) -> i64 { pdf.base_data.id as i64 }
|
||||
|
||||
#[rhai_fn(get = "created_at", pure)]
|
||||
pub fn get_pdf_created_at(pdf: &mut RhaiPdf) -> i64 { pdf.base_data.created_at }
|
||||
|
||||
#[rhai_fn(get = "modified_at", pure)]
|
||||
pub fn get_pdf_modified_at(pdf: &mut RhaiPdf) -> i64 { pdf.base_data.modified_at }
|
||||
|
||||
#[rhai_fn(get = "title", pure)]
|
||||
pub fn get_pdf_title(pdf: &mut RhaiPdf) -> String { pdf.title.clone() }
|
||||
|
||||
#[rhai_fn(get = "description", pure)]
|
||||
pub fn get_pdf_description(pdf: &mut RhaiPdf) -> Option<String> { pdf.description.clone() }
|
||||
|
||||
#[rhai_fn(get = "url", pure)]
|
||||
pub fn get_pdf_url(pdf: &mut RhaiPdf) -> String { pdf.url.clone() }
|
||||
|
||||
#[rhai_fn(get = "page_count", pure)]
|
||||
pub fn get_pdf_page_count(pdf: &mut RhaiPdf) -> u32 { pdf.page_count }
|
||||
|
||||
// --- Markdown Functions ---
|
||||
#[rhai_fn(name = "new_markdown")]
|
||||
pub fn new_markdown() -> RhaiMarkdown {
|
||||
RhaiMarkdown::new()
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "title", return_raw, global, pure)]
|
||||
pub fn markdown_title(markdown: &mut RhaiMarkdown, title: String) -> Result<RhaiMarkdown, Box<EvalAltResult>> {
|
||||
let owned = mem::take(markdown);
|
||||
*markdown = owned.title(title);
|
||||
Ok(markdown.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "description", return_raw, global, pure)]
|
||||
pub fn markdown_description(markdown: &mut RhaiMarkdown, description: String) -> Result<RhaiMarkdown, Box<EvalAltResult>> {
|
||||
let owned = mem::take(markdown);
|
||||
*markdown = owned.description(description);
|
||||
Ok(markdown.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "content", return_raw, global, pure)]
|
||||
pub fn markdown_content(markdown: &mut RhaiMarkdown, content: String) -> Result<RhaiMarkdown, Box<EvalAltResult>> {
|
||||
let owned = mem::take(markdown);
|
||||
*markdown = owned.content(content);
|
||||
Ok(markdown.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(get = "id", pure)]
|
||||
pub fn get_markdown_id(markdown: &mut RhaiMarkdown) -> i64 { markdown.base_data.id as i64 }
|
||||
|
||||
#[rhai_fn(get = "created_at", pure)]
|
||||
pub fn get_markdown_created_at(markdown: &mut RhaiMarkdown) -> i64 { markdown.base_data.created_at }
|
||||
|
||||
#[rhai_fn(get = "modified_at", pure)]
|
||||
pub fn get_markdown_modified_at(markdown: &mut RhaiMarkdown) -> i64 { markdown.base_data.modified_at }
|
||||
|
||||
#[rhai_fn(get = "title", pure)]
|
||||
pub fn get_markdown_title(markdown: &mut RhaiMarkdown) -> String { markdown.title.clone() }
|
||||
|
||||
#[rhai_fn(get = "description", pure)]
|
||||
pub fn get_markdown_description(markdown: &mut RhaiMarkdown) -> Option<String> { markdown.description.clone() }
|
||||
|
||||
#[rhai_fn(get = "content", pure)]
|
||||
pub fn get_markdown_content(markdown: &mut RhaiMarkdown) -> String { markdown.content.clone() }
|
||||
|
||||
// --- TocEntry Functions ---
|
||||
#[rhai_fn(name = "new_toc_entry")]
|
||||
pub fn new_toc_entry() -> RhaiTocEntry {
|
||||
RhaiTocEntry::new()
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "title", return_raw, global, pure)]
|
||||
pub fn toc_entry_title(entry: &mut RhaiTocEntry, title: String) -> Result<RhaiTocEntry, Box<EvalAltResult>> {
|
||||
let owned = mem::take(entry);
|
||||
*entry = owned.title(title);
|
||||
Ok(entry.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "page", return_raw, global, pure)]
|
||||
pub fn toc_entry_page(entry: &mut RhaiTocEntry, page: i64) -> Result<RhaiTocEntry, Box<EvalAltResult>> {
|
||||
let owned = mem::take(entry);
|
||||
*entry = owned.page(page as u32);
|
||||
Ok(entry.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "add_subsection", return_raw, global, pure)]
|
||||
pub fn toc_entry_add_subsection(entry: &mut RhaiTocEntry, subsection: RhaiTocEntry) -> Result<RhaiTocEntry, Box<EvalAltResult>> {
|
||||
let owned = mem::take(entry);
|
||||
*entry = owned.add_subsection(subsection);
|
||||
Ok(entry.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(get = "title", pure)]
|
||||
pub fn get_toc_entry_title(entry: &mut RhaiTocEntry) -> String { entry.title.clone() }
|
||||
|
||||
#[rhai_fn(get = "page", pure)]
|
||||
pub fn get_toc_entry_page(entry: &mut RhaiTocEntry) -> u32 { entry.page }
|
||||
|
||||
#[rhai_fn(get = "subsections", pure)]
|
||||
pub fn get_toc_entry_subsections(entry: &mut RhaiTocEntry) -> Vec<RhaiTocEntry> { entry.subsections.clone() }
|
||||
|
||||
// --- Book Functions ---
|
||||
#[rhai_fn(name = "new_book")]
|
||||
pub fn new_book() -> RhaiBook {
|
||||
RhaiBook::new()
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "title", return_raw, global, pure)]
|
||||
pub fn book_title(book: &mut RhaiBook, title: String) -> Result<RhaiBook, Box<EvalAltResult>> {
|
||||
let owned = mem::take(book);
|
||||
*book = owned.title(title);
|
||||
Ok(book.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "description", return_raw, global, pure)]
|
||||
pub fn book_description(book: &mut RhaiBook, description: String) -> Result<RhaiBook, Box<EvalAltResult>> {
|
||||
let owned = mem::take(book);
|
||||
*book = owned.description(description);
|
||||
Ok(book.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "add_page", return_raw, global, pure)]
|
||||
pub fn book_add_page(book: &mut RhaiBook, content: String) -> Result<RhaiBook, Box<EvalAltResult>> {
|
||||
let owned = mem::take(book);
|
||||
*book = owned.add_page(content);
|
||||
Ok(book.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "add_toc_entry", return_raw, global, pure)]
|
||||
pub fn book_add_toc_entry(book: &mut RhaiBook, entry: RhaiTocEntry) -> Result<RhaiBook, Box<EvalAltResult>> {
|
||||
let owned = mem::take(book);
|
||||
*book = owned.add_toc_entry(entry);
|
||||
Ok(book.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(get = "id", pure)]
|
||||
pub fn get_book_id(book: &mut RhaiBook) -> i64 { book.base_data.id as i64 }
|
||||
|
||||
#[rhai_fn(get = "created_at", pure)]
|
||||
pub fn get_book_created_at(book: &mut RhaiBook) -> i64 { book.base_data.created_at }
|
||||
|
||||
#[rhai_fn(get = "modified_at", pure)]
|
||||
pub fn get_book_modified_at(book: &mut RhaiBook) -> i64 { book.base_data.modified_at }
|
||||
|
||||
#[rhai_fn(get = "title", pure)]
|
||||
pub fn get_book_title(book: &mut RhaiBook) -> String { book.title.clone() }
|
||||
|
||||
#[rhai_fn(get = "description", pure)]
|
||||
pub fn get_book_description(book: &mut RhaiBook) -> Option<String> { book.description.clone() }
|
||||
|
||||
#[rhai_fn(get = "table_of_contents", pure)]
|
||||
pub fn get_book_table_of_contents(book: &mut RhaiBook) -> Vec<RhaiTocEntry> { book.table_of_contents.clone() }
|
||||
|
||||
#[rhai_fn(get = "pages", pure)]
|
||||
pub fn get_book_pages(book: &mut RhaiBook) -> Vec<String> { book.pages.clone() }
|
||||
|
||||
// --- Slides Functions ---
|
||||
#[rhai_fn(name = "new_slides")]
|
||||
pub fn new_slides() -> RhaiSlides {
|
||||
RhaiSlides::new()
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "title", return_raw, global, pure)]
|
||||
pub fn slides_title(slides: &mut RhaiSlides, title: String) -> Result<RhaiSlides, Box<EvalAltResult>> {
|
||||
let owned = mem::take(slides);
|
||||
*slides = owned.title(title);
|
||||
Ok(slides.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "description", return_raw, global, pure)]
|
||||
pub fn slides_description(slides: &mut RhaiSlides, description: String) -> Result<RhaiSlides, Box<EvalAltResult>> {
|
||||
let owned = mem::take(slides);
|
||||
*slides = owned.description(description);
|
||||
Ok(slides.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "add_slide", return_raw, global, pure)]
|
||||
pub fn slides_add_slide(slides: &mut RhaiSlides, url: String, title: String) -> Result<RhaiSlides, Box<EvalAltResult>> {
|
||||
let owned = mem::take(slides);
|
||||
let title_opt = if title.is_empty() { None } else { Some(title) };
|
||||
*slides = owned.add_slide(url, title_opt);
|
||||
Ok(slides.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(name = "add_slide", return_raw, global, pure)]
|
||||
pub fn slides_add_slide_no_title(slides: &mut RhaiSlides, url: String) -> Result<RhaiSlides, Box<EvalAltResult>> {
|
||||
let owned = mem::take(slides);
|
||||
*slides = owned.add_slide(url, None);
|
||||
Ok(slides.clone())
|
||||
}
|
||||
|
||||
#[rhai_fn(get = "id", pure)]
|
||||
pub fn get_slides_id(slides: &mut RhaiSlides) -> i64 { slides.base_data.id as i64 }
|
||||
|
||||
#[rhai_fn(get = "created_at", pure)]
|
||||
pub fn get_slides_created_at(slides: &mut RhaiSlides) -> i64 { slides.base_data.created_at }
|
||||
|
||||
#[rhai_fn(get = "modified_at", pure)]
|
||||
pub fn get_slides_modified_at(slides: &mut RhaiSlides) -> i64 { slides.base_data.modified_at }
|
||||
|
||||
#[rhai_fn(get = "title", pure)]
|
||||
pub fn get_slides_title(slides: &mut RhaiSlides) -> String { slides.title.clone() }
|
||||
|
||||
#[rhai_fn(get = "description", pure)]
|
||||
pub fn get_slides_description(slides: &mut RhaiSlides) -> Option<String> { slides.description.clone() }
|
||||
|
||||
#[rhai_fn(get = "slide_urls", pure)]
|
||||
pub fn get_slides_slide_urls(slides: &mut RhaiSlides) -> Vec<String> { slides.slide_urls.clone() }
|
||||
|
||||
#[rhai_fn(get = "slide_titles", pure)]
|
||||
pub fn get_slides_slide_titles(slides: &mut RhaiSlides) -> Vec<Option<String>> { slides.slide_titles.clone() }
|
||||
}
|
||||
|
||||
pub fn register_library_rhai_module(engine: &mut Engine, db: Arc<OurDB>) {
|
||||
let module = exported_module!(rhai_library_module);
|
||||
engine.register_global_module(module.into());
|
||||
|
||||
let mut db_module = Module::new();
|
||||
|
||||
register_json_method::<RhaiCollection>(engine);
|
||||
register_json_method::<RhaiImage>(engine);
|
||||
register_json_method::<RhaiPdf>(engine);
|
||||
register_json_method::<RhaiMarkdown>(engine);
|
||||
register_json_method::<RhaiBook>(engine);
|
||||
register_json_method::<RhaiSlides>(engine);
|
||||
register_json_method::<RhaiTocEntry>(engine);
|
||||
|
||||
// Register .json() method for our custom CollectionArray type
|
||||
register_json_method::<RhaiCollectionArray>(engine);
|
||||
|
||||
// --- Collection DB Functions ---
|
||||
let db_clone = db.clone();
|
||||
db_module.set_native_fn("save_collection", move |collection: RhaiCollection| -> Result<RhaiCollection, Box<EvalAltResult>> {
|
||||
let result = db_clone.set(&collection)
|
||||
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error: {:?}", e).into(), Position::NONE)))?;
|
||||
Ok(result.1)
|
||||
});
|
||||
|
||||
let db_clone = db.clone();
|
||||
db_module.set_native_fn("get_collection", move |id: i64| -> Result<RhaiCollection, Box<EvalAltResult>> {
|
||||
let collection_id = id_from_i64_to_u32(id)?;
|
||||
db_clone.get_by_id(collection_id)
|
||||
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error: {:?}", e).into(), Position::NONE)))?
|
||||
.ok_or_else(|| Box::new(EvalAltResult::ErrorRuntime(format!("Collection with ID {} not found", collection_id).into(), Position::NONE)))
|
||||
});
|
||||
|
||||
let db_clone_list_collections = db.clone();
|
||||
db_module.set_native_fn("list_collections", move || -> Result<RhaiCollectionArray, Box<EvalAltResult>> {
|
||||
let collections_vec: Vec<RhaiCollection> = db_clone_list_collections
|
||||
.collection::<RhaiCollection>()
|
||||
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error (list_collections - access): {:?}", e).into(), Position::NONE)))?
|
||||
.get_all()
|
||||
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error (list_collections - get_all): {:?}", e).into(), Position::NONE)))?;
|
||||
Ok(RhaiCollectionArray(collections_vec)) // Wrap in RhaiCollectionArray
|
||||
});
|
||||
|
||||
let db_clone = db.clone();
|
||||
db_module.set_native_fn("delete_collection", move |id: i64| -> Result<(), Box<EvalAltResult>> {
|
||||
let collection_id = id_from_i64_to_u32(id)?;
|
||||
db_clone.collection::<RhaiCollection>().unwrap().delete_by_id(collection_id)
|
||||
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error: {:?}", e).into(), Position::NONE)))?;
|
||||
Ok(())
|
||||
});
|
||||
|
||||
// --- Image DB Functions ---
|
||||
let db_clone = db.clone();
|
||||
db_module.set_native_fn("save_image", move |image: RhaiImage| -> Result<RhaiImage, Box<EvalAltResult>> {
|
||||
let result = db_clone.set(&image)
|
||||
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error: {:?}", e).into(), Position::NONE)))?;
|
||||
Ok(result.1)
|
||||
});
|
||||
|
||||
let db_clone = db.clone();
|
||||
db_module.set_native_fn("get_image", move |id: i64| -> Result<RhaiImage, Box<EvalAltResult>> {
|
||||
let image_id = id_from_i64_to_u32(id)?;
|
||||
db_clone.get_by_id(image_id)
|
||||
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error: {:?}", e).into(), Position::NONE)))?
|
||||
.ok_or_else(|| Box::new(EvalAltResult::ErrorRuntime(format!("Image with ID {} not found", image_id).into(), Position::NONE)))
|
||||
});
|
||||
|
||||
let db_clone = db.clone();
|
||||
db_module.set_native_fn("delete_image", move |id: i64| -> Result<(), Box<EvalAltResult>> {
|
||||
let image_id = id_from_i64_to_u32(id)?;
|
||||
db_clone.collection::<RhaiImage>().unwrap().delete_by_id(image_id)
|
||||
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error: {:?}", e).into(), Position::NONE)))?;
|
||||
Ok(())
|
||||
});
|
||||
|
||||
// --- Pdf DB Functions ---
|
||||
let db_clone = db.clone();
|
||||
db_module.set_native_fn("save_pdf", move |pdf: RhaiPdf| -> Result<RhaiPdf, Box<EvalAltResult>> {
|
||||
let result = db_clone.set(&pdf)
|
||||
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error: {:?}", e).into(), Position::NONE)))?;
|
||||
Ok(result.1)
|
||||
});
|
||||
|
||||
let db_clone = db.clone();
|
||||
db_module.set_native_fn("get_pdf", move |id: i64| -> Result<RhaiPdf, Box<EvalAltResult>> {
|
||||
let pdf_id = id_from_i64_to_u32(id)?;
|
||||
db_clone.get_by_id(pdf_id)
|
||||
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error: {:?}", e).into(), Position::NONE)))?
|
||||
.ok_or_else(|| Box::new(EvalAltResult::ErrorRuntime(format!("Pdf with ID {} not found", pdf_id).into(), Position::NONE)))
|
||||
});
|
||||
|
||||
let db_clone = db.clone();
|
||||
db_module.set_native_fn("delete_pdf", move |id: i64| -> Result<(), Box<EvalAltResult>> {
|
||||
let pdf_id = id_from_i64_to_u32(id)?;
|
||||
db_clone.collection::<RhaiPdf>().unwrap().delete_by_id(pdf_id)
|
||||
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error: {:?}", e).into(), Position::NONE)))?;
|
||||
Ok(())
|
||||
});
|
||||
|
||||
// --- Markdown DB Functions ---
|
||||
let db_clone = db.clone();
|
||||
db_module.set_native_fn("save_markdown", move |markdown: RhaiMarkdown| -> Result<RhaiMarkdown, Box<EvalAltResult>> {
|
||||
let result = db_clone.set(&markdown)
|
||||
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error: {:?}", e).into(), Position::NONE)))?;
|
||||
Ok(result.1)
|
||||
});
|
||||
|
||||
let db_clone = db.clone();
|
||||
db_module.set_native_fn("get_markdown", move |id: i64| -> Result<RhaiMarkdown, Box<EvalAltResult>> {
|
||||
let markdown_id = id_from_i64_to_u32(id)?;
|
||||
db_clone.get_by_id(markdown_id)
|
||||
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error: {:?}", e).into(), Position::NONE)))?
|
||||
.ok_or_else(|| Box::new(EvalAltResult::ErrorRuntime(format!("Markdown with ID {} not found", markdown_id).into(), Position::NONE)))
|
||||
});
|
||||
|
||||
let db_clone = db.clone();
|
||||
db_module.set_native_fn("delete_markdown", move |id: i64| -> Result<(), Box<EvalAltResult>> {
|
||||
let markdown_id = id_from_i64_to_u32(id)?;
|
||||
db_clone.collection::<RhaiMarkdown>().unwrap().delete_by_id(markdown_id)
|
||||
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error: {:?}", e).into(), Position::NONE)))?;
|
||||
Ok(())
|
||||
});
|
||||
|
||||
// --- Book DB Functions ---
|
||||
let db_clone = db.clone();
|
||||
db_module.set_native_fn("save_book", move |book: RhaiBook| -> Result<RhaiBook, Box<EvalAltResult>> {
|
||||
let result = db_clone.set(&book)
|
||||
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error: {:?}", e).into(), Position::NONE)))?;
|
||||
Ok(result.1)
|
||||
});
|
||||
|
||||
let db_clone = db.clone();
|
||||
db_module.set_native_fn("get_book", move |id: i64| -> Result<RhaiBook, Box<EvalAltResult>> {
|
||||
let book_id = id_from_i64_to_u32(id)?;
|
||||
db_clone.get_by_id(book_id)
|
||||
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error: {:?}", e).into(), Position::NONE)))?
|
||||
.ok_or_else(|| Box::new(EvalAltResult::ErrorRuntime(format!("Book with ID {} not found", book_id).into(), Position::NONE)))
|
||||
});
|
||||
|
||||
let db_clone = db.clone();
|
||||
db_module.set_native_fn("delete_book", move |id: i64| -> Result<(), Box<EvalAltResult>> {
|
||||
let book_id = id_from_i64_to_u32(id)?;
|
||||
db_clone.collection::<RhaiBook>().unwrap().delete_by_id(book_id)
|
||||
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error: {:?}", e).into(), Position::NONE)))?;
|
||||
Ok(())
|
||||
});
|
||||
|
||||
// --- Slides DB Functions ---
|
||||
let db_clone = db.clone();
|
||||
db_module.set_native_fn("save_slides", move |slides: RhaiSlides| -> Result<RhaiSlides, Box<EvalAltResult>> {
|
||||
let result = db_clone.set(&slides)
|
||||
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error: {:?}", e).into(), Position::NONE)))?;
|
||||
Ok(result.1)
|
||||
});
|
||||
|
||||
let db_clone = db.clone();
|
||||
db_module.set_native_fn("get_slides", move |id: i64| -> Result<RhaiSlides, Box<EvalAltResult>> {
|
||||
let slides_id = id_from_i64_to_u32(id)?;
|
||||
db_clone.get_by_id(slides_id)
|
||||
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error: {:?}", e).into(), Position::NONE)))?
|
||||
.ok_or_else(|| Box::new(EvalAltResult::ErrorRuntime(format!("Slides with ID {} not found", slides_id).into(), Position::NONE)))
|
||||
});
|
||||
|
||||
let db_clone = db.clone();
|
||||
db_module.set_native_fn("delete_slides", move |id: i64| -> Result<(), Box<EvalAltResult>> {
|
||||
let slides_id = id_from_i64_to_u32(id)?;
|
||||
db_clone.collection::<RhaiSlides>().unwrap().delete_by_id(slides_id)
|
||||
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error: {:?}", e).into(), Position::NONE)))?;
|
||||
Ok(())
|
||||
});
|
||||
|
||||
engine.register_global_module(db_module.into());
|
||||
}
|
@ -3,8 +3,10 @@ pub mod core;
|
||||
pub mod userexample;
|
||||
// pub mod productexample; // Temporarily remove as files are missing
|
||||
pub mod calendar;
|
||||
pub mod circle;
|
||||
pub mod governance;
|
||||
pub mod finance;
|
||||
pub mod library;
|
||||
pub mod legal;
|
||||
pub mod flow;
|
||||
pub mod biz;
|
||||
@ -15,18 +17,25 @@ pub use core::Comment;
|
||||
pub use userexample::User;
|
||||
// pub use productexample::Product; // Temporarily remove
|
||||
pub use calendar::{Calendar, Event, Attendee, AttendanceStatus};
|
||||
pub use circle::{Circle};
|
||||
pub use governance::{Proposal, ProposalStatus, VoteEventStatus, Ballot, VoteOption, AttachedFile};
|
||||
pub use finance::{Account, Asset, AssetType};
|
||||
pub use finance::marketplace::{Listing, ListingStatus, ListingType, Bid, BidStatus};
|
||||
pub use legal::{Contract, ContractRevision, ContractSigner, ContractStatus, SignerStatus};
|
||||
pub use flow::{Flow, FlowStep, SignatureRequirement};
|
||||
pub use biz::{Sale, SaleItem, SaleStatus};
|
||||
pub use library::items::{Image, Pdf, Markdown};
|
||||
pub use library::collection::Collection;
|
||||
|
||||
pub use flow::register_flow_rhai_module;
|
||||
#[cfg(feature = "rhai")]
|
||||
pub use calendar::register_calendar_rhai_module;
|
||||
#[cfg(feature = "rhai")]
|
||||
pub use circle::register_circle_rhai_module;
|
||||
pub use legal::register_legal_rhai_module;
|
||||
#[cfg(feature = "rhai")]
|
||||
pub use biz::register_biz_rhai_module;
|
||||
#[cfg(feature = "rhai")]
|
||||
pub use projects::register_projects_rhai_module;
|
||||
#[cfg(feature = "rhai")]
|
||||
pub use library::register_library_rhai_module;
|
||||
|
Loading…
Reference in New Issue
Block a user