db/_archive/rhai.rs

1052 lines
33 KiB
Rust

use crate::db::Db;
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 super::collection::Collection as RhaiCollection;
use super::items::{
Book as RhaiBook, Image as RhaiImage, Markdown as RhaiMarkdown, Pdf as RhaiPdf,
Slide as RhaiSlide, Slideshow as RhaiSlides, TocEntry as RhaiTocEntry,
};
use crate::db::Collection as DbCollectionTrait;
use crate::db::hero::OurDB;
// 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_pretty(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>);
impl From<Vec<RhaiCollection>> for RhaiCollectionArray {
fn from(collections: Vec<RhaiCollection>) -> Self {
RhaiCollectionArray(collections)
}
}
#[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()
}
// --- Slideshow Functions ---
#[rhai_fn(name = "new_slide")]
pub fn new_slide() -> RhaiSlide {
RhaiSlide::new()
}
#[rhai_fn(name = "title", return_raw, global, pure)]
pub fn slide_title(
slide: &mut RhaiSlide,
title: String,
) -> Result<RhaiSlide, Box<EvalAltResult>> {
let owned = mem::take(slide);
*slide = owned.title(title);
Ok(slide.clone())
}
#[rhai_fn(name = "description", return_raw, global, pure)]
pub fn slide_description(
slide: &mut RhaiSlide,
description: String,
) -> Result<RhaiSlide, Box<EvalAltResult>> {
let owned = mem::take(slide);
*slide = owned.description(description);
Ok(slide.clone())
}
#[rhai_fn(name = "url", return_raw, global, pure)]
pub fn slide_url(slide: &mut RhaiSlide, url: String) -> Result<RhaiSlide, Box<EvalAltResult>> {
let owned = mem::take(slide);
*slide = owned.url(url);
Ok(slide.clone())
}
// --- Slideshow 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,
slide: RhaiSlide,
) -> Result<RhaiSlides, Box<EvalAltResult>> {
let owned = mem::take(slides);
*slides = owned.add_slide(slide);
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 = "slides", pure)]
pub fn get_slides_slides(slides: &mut RhaiSlides) -> Vec<RhaiSlide> {
slides.slides.clone()
}
}
pub fn register_library_rhai_module(engine: &mut Engine) {
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(())
},
);
// --- Slideshow 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!("Slideshow 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());
}