Files
db/heromodels/src/models/library/rhai.rs
2025-08-21 14:05:01 +02:00

157 lines
5.1 KiB
Rust

use derive::FromVec;
use heromodels::db::Db;
use macros::{
register_authorized_create_by_id_fn, register_authorized_delete_by_id_fn,
register_authorized_get_by_id_fn, register_authorized_list_fn,
};
use rhai::plugin::*;
use rhai::{CustomType, Dynamic, Engine, EvalAltResult, Module, Position, TypeBuilder};
use serde::Serialize;
use serde_json;
use std::mem;
use std::sync::Arc;
use heromodels::db::hero::OurDB;
use heromodels::db::Collection as DbCollectionTrait;
use heromodels::models::library::collection::Collection as RhaiCollection;
use heromodels::models::library::items::{
Book as RhaiBook, Image as RhaiImage, Markdown as RhaiMarkdown, Pdf as RhaiPdf,
Slide as RhaiSlide, Slideshow as RhaiSlideshow, TocEntry as RhaiTocEntry,
};
/// Registers a `.json()` method for any type `T` that implements the required traits.
fn register_json_method<T>(engine: &mut Engine)
where
T: CustomType + Clone + Serialize,
{
let to_json_fn = |obj: &mut T| -> Result<String, Box<EvalAltResult>> {
match serde_json::to_string_pretty(obj) {
Ok(json_str) => Ok(json_str),
Err(e) => Err(format!("Failed to serialize to JSON: {}", e).into()),
}
};
engine.register_fn("json", to_json_fn);
}
// Wrapper types for arrays
#[derive(Debug, Clone, Serialize, CustomType, FromVec)]
#[rhai_type(name = "CollectionArray")]
pub struct RhaiCollectionArray(pub Vec<RhaiCollection>);
#[derive(Debug, Clone, Serialize, CustomType, FromVec)]
#[rhai_type(name = "ImageArray")]
pub struct RhaiImageArray(pub Vec<RhaiImage>);
#[derive(Debug, Clone, Serialize, CustomType, FromVec)]
#[rhai_type(name = "PdfArray")]
pub struct RhaiPdfArray(pub Vec<RhaiPdf>);
#[derive(Debug, Clone, Serialize, CustomType, FromVec)]
#[rhai_type(name = "MarkdownArray")]
pub struct RhaiMarkdownArray(pub Vec<RhaiMarkdown>);
#[derive(Debug, Clone, Serialize, CustomType, FromVec)]
#[rhai_type(name = "BookArray")]
pub struct RhaiBookArray(pub Vec<RhaiBook>);
#[derive(Debug, Clone, Serialize, CustomType, FromVec)]
#[rhai_type(name = "SlideshowArray")]
pub struct RhaiSlideshowArray(pub Vec<RhaiSlideshow>);
#[derive(Debug, Clone, Serialize, CustomType, FromVec)]
#[rhai_type(name = "TocEntryArray")]
pub struct RhaiTocEntryArray(pub Vec<RhaiTocEntry>);
#[export_module]
mod rhai_library_module {
use super::*;
// --- Collection Functions ---
#[rhai_fn(name = "new_collection", return_raw)]
pub fn new_collection() -> Result<RhaiCollection, Box<EvalAltResult>> {
Ok(RhaiCollection::new())
}
#[rhai_fn(name = "collection_title", return_raw)]
pub fn collection_title(
collection: &mut RhaiCollection,
title: String,
) -> Result<RhaiCollection, Box<EvalAltResult>> {
let owned = std::mem::take(collection);
*collection = owned.title(title);
Ok(collection.clone())
}
#[rhai_fn(name = "collection_description", return_raw)]
pub fn collection_description(
collection: &mut RhaiCollection,
description: String,
) -> Result<RhaiCollection, Box<EvalAltResult>> {
let owned = std::mem::take(collection);
*collection = owned.description(description);
Ok(collection.clone())
}
#[rhai_fn(name = "get_collection_id")]
pub fn get_collection_id(collection: &mut RhaiCollection) -> i64 {
collection.id() as i64
}
#[rhai_fn(name = "get_collection_title")]
pub fn get_collection_title(collection: &mut RhaiCollection) -> String {
collection.title().clone()
}
// --- Image Functions ---
#[rhai_fn(name = "new_image", return_raw)]
pub fn new_image() -> Result<RhaiImage, Box<EvalAltResult>> {
Ok(RhaiImage::new())
}
#[rhai_fn(name = "image_title", return_raw)]
pub fn image_title(
image: &mut RhaiImage,
title: String,
) -> Result<RhaiImage, Box<EvalAltResult>> {
let owned = std::mem::take(image);
*image = owned.title(title);
Ok(image.clone())
}
#[rhai_fn(name = "get_image_id")]
pub fn get_image_id(image: &mut RhaiImage) -> i64 {
image.id() as i64
}
// Additional functions would continue here...
}
pub fn register_library_rhai_module(engine: &mut Engine) {
let mut module = exported_module!(rhai_library_module);
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::<RhaiSlideshow>(engine);
register_json_method::<RhaiTocEntry>(engine);
register_json_method::<RhaiCollectionArray>(engine);
register_authorized_create_by_id_fn!(
module: &mut module,
rhai_fn_name: "save_collection",
resource_type_str: "Collection",
rhai_return_rust_type: heromodels::models::library::collection::Collection
);
register_authorized_get_by_id_fn!(
module: &mut module,
rhai_fn_name: "get_collection",
resource_type_str: "Collection",
rhai_return_rust_type: heromodels::models::library::collection::Collection
);
engine.register_global_module(module.into());
}