improve model rhai scripts legibility

This commit is contained in:
timurgordon 2025-05-22 17:55:08 +03:00
parent 99f5d16f31
commit 478f497316
6 changed files with 34 additions and 161 deletions

View File

@ -4,4 +4,5 @@ temp_flow_rhai_db
temp_project_db
temp_governance_db
temp_legal_db
temp_legal_rhai_db
temp_legal_rhai_db
data

View File

@ -19,6 +19,8 @@ rhai_wrapper = { path = "../../rhaj/rhai_wrapper" }
rhai = { version = "1.21.0", features = ["std", "sync", "decimal", "internals"] } # Added "decimal" feature, sync for Arc<Mutex<>>
adapter_macros = { path = "../adapter_macros" }
rhai_client_macros = { path = "../rhai_client_macros" }
strum = "0.26"
strum_macros = "0.26"
[features]
default = []
@ -26,7 +28,6 @@ rhai = []
[dev-dependencies]
chrono = "0.4"
[[example]]
name = "calendar_example"
path = "examples/calendar_example/main.rs"

View File

@ -4,7 +4,6 @@ print("--- Testing Project Rhai Integration ---");
// Create a new project
let p1 = new_project()
.set_base_id(1)
.name("Project Alpha")
.description("This is the first test project.")
.owner_id(101)
@ -17,8 +16,6 @@ let p1 = new_project()
.status(Status::InProgress)
.priority(Priority::High)
.item_type(ItemType::Feature)
.set_base_created_at(1700000000)
.set_base_modified_at(1700000100)
.add_base_comment(1001);
print("Created project p1: " + p1);

View File

@ -1,14 +1,13 @@
// heromodels/src/models/projects/base.rs
use serde::{Deserialize, Serialize};
use heromodels_core::{BaseModelData, Model};
use heromodels_core::{BaseModelData, Model, BaseModelDataOps};
#[cfg(feature = "rhai")]
use rhai::{CustomType, TypeBuilder}; // Removed Engine, EvalAltResult, Dynamic, Position, ImmutableString
use rhai::{CustomType, TypeBuilder};
use strum_macros::Display; // Made unconditional as Display derive is used on non-rhai-gated enums
// --- Enums ---
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
// #[cfg_attr(feature = "rhai", derive(CustomType))] // Removed derive for enum
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Display)]
pub enum Priority {
Critical,
High,
@ -17,40 +16,13 @@ pub enum Priority {
None,
}
#[cfg(feature = "rhai")]
impl CustomType for Priority {
fn build(mut builder: TypeBuilder<Self>) { // Takes mut builder, returns ()
println!("DEBUG: CustomType::build for Priority called!");
builder
.with_name("Priority")
.with_fn("to_string", |p_mut: &mut Priority| {
let rust_string = ToString::to_string(p_mut);
println!("DEBUG: Priority.to_string() in Rust (via Rhai) produced: '{}'", rust_string);
rust_string
});
}
}
impl Default for Priority {
fn default() -> Self {
Priority::None
}
}
impl ToString for Priority {
fn to_string(&self) -> String {
match self {
Priority::Critical => "Critical".to_string(),
Priority::High => "High".to_string(),
Priority::Medium => "Medium".to_string(),
Priority::Low => "Low".to_string(),
Priority::None => "None".to_string(),
}
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
// #[cfg_attr(feature = "rhai", derive(CustomType))] // Removed derive for enum
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Display)]
pub enum Status {
Todo,
InProgress,
@ -59,40 +31,13 @@ pub enum Status {
Archived,
}
#[cfg(feature = "rhai")]
impl CustomType for Status {
fn build(mut builder: TypeBuilder<Self>) { // Takes mut builder, returns ()
println!("DEBUG: CustomType::build for Status called!");
builder
.with_name("Status")
.with_fn("to_string", |s_mut: &mut Status| {
let rust_string = ToString::to_string(s_mut);
println!("DEBUG: Status.to_string() in Rust (via Rhai) produced: '{}'", rust_string);
rust_string
});
}
}
impl Default for Status {
fn default() -> Self {
Status::Todo
}
}
impl ToString for Status {
fn to_string(&self) -> String {
match self {
Status::Todo => "Todo".to_string(),
Status::InProgress => "InProgress".to_string(),
Status::Review => "Review".to_string(),
Status::Done => "Done".to_string(),
Status::Archived => "Archived".to_string(),
}
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
// #[cfg_attr(feature = "rhai", derive(CustomType))] // Removed derive for enum
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Display)]
pub enum ItemType {
Epic,
Story,
@ -102,39 +47,12 @@ pub enum ItemType {
Feature,
}
#[cfg(feature = "rhai")]
impl CustomType for ItemType {
fn build(mut builder: TypeBuilder<Self>) { // Takes mut builder, returns ()
println!("DEBUG: CustomType::build for ItemType called!");
builder
.with_name("ItemType")
.with_fn("to_string", |it_mut: &mut ItemType| {
let rust_string = ToString::to_string(it_mut);
println!("DEBUG: ItemType.to_string() in Rust (via Rhai) produced: '{}'", rust_string);
rust_string
});
}
}
impl Default for ItemType {
fn default() -> Self {
ItemType::Task
}
}
impl ToString for ItemType {
fn to_string(&self) -> String {
match self {
ItemType::Epic => "Epic".to_string(),
ItemType::Story => "Story".to_string(),
ItemType::Task => "Task".to_string(),
ItemType::Bug => "Bug".to_string(),
ItemType::Improvement => "Improvement".to_string(),
ItemType::Feature => "Feature".to_string(),
}
}
}
// --- Structs ---
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
@ -154,6 +72,12 @@ pub struct Project {
pub item_type: ItemType,
}
impl BaseModelDataOps for Project {
fn get_base_data_mut(&mut self) -> &mut BaseModelData {
&mut self.base_data
}
}
impl Model for Project {
fn get_id(&self) -> u32 {
self.base_data.id
@ -252,28 +176,6 @@ impl Project {
self.item_type = item_type;
self
}
// Base model builder methods
pub fn set_base_id(mut self, id: u32) -> Self {
self.base_data.id = id;
self
}
pub fn set_base_created_at(mut self, time: i64) -> Self {
self.base_data.created_at = time;
self
}
pub fn set_base_modified_at(mut self, time: i64) -> Self {
self.base_data.modified_at = time;
self
}
pub fn add_base_comment(mut self, comment_id: u32) -> Self {
self.base_data.comments.push(comment_id);
self
}
pub fn set_base_comments(mut self, comment_ids: Vec<u32>) -> Self {
self.base_data.comments = comment_ids;
self
}
}
@ -285,6 +187,12 @@ pub struct Label {
pub color: String, // Hex color code
}
impl BaseModelDataOps for Label {
fn get_base_data_mut(&mut self) -> &mut BaseModelData {
&mut self.base_data
}
}
impl Model for Label {
fn get_id(&self) -> u32 {
self.base_data.id
@ -315,27 +223,5 @@ impl Label {
self.color = color;
self
}
// Base model builder methods
pub fn set_base_id(mut self, id: u32) -> Self {
self.base_data.id = id;
self
}
pub fn set_base_created_at(mut self, time: i64) -> Self {
self.base_data.created_at = time;
self
}
pub fn set_base_modified_at(mut self, time: i64) -> Self {
self.base_data.modified_at = time;
self
}
pub fn add_base_comment(mut self, comment_id: u32) -> Self {
self.base_data.comments.push(comment_id);
self
}
pub fn set_base_comments(mut self, comment_ids: Vec<u32>) -> Self {
self.base_data.comments = comment_ids;
self
}
}

View File

@ -1,11 +1,10 @@
// heromodels/src/models/projects/rhai.rs
use rhai::{Engine, EvalAltResult, Position, Dynamic};
use crate::db::Db; // Added to bring Db trait and .collection() method into scope
use rhai::{Engine, EvalAltResult, Dynamic, Position};
use std::sync::Arc;
use crate::db::hero::OurDB; // Corrected path
use heromodels_core::Model; // Added
use crate::db::Collection;
use crate::db::hero::OurDB;
use heromodels_core::{Model, BaseModelDataOps};
use crate::db::{Db, Collection};
// Import models from the projects::base module
@ -59,8 +58,13 @@ pub fn register_projects_rhai_module(engine: &mut Engine, db: Arc<OurDB>) {
// --- Enum Type Registration ---
engine.register_type_with_name::<Priority>("Priority");
engine.register_fn("to_string", |p: &mut Priority| ToString::to_string(p));
engine.register_type_with_name::<Status>("Status");
engine.register_fn("to_string", |s: &mut Status| ToString::to_string(s));
engine.register_type_with_name::<ItemType>("ItemType");
engine.register_fn("to_string", |it: &mut ItemType| ToString::to_string(it));
// --- Project Registration ---
engine.register_type_with_name::<Project>("Project");
@ -201,26 +205,7 @@ pub fn register_projects_rhai_module(engine: &mut Engine, db: Arc<OurDB>) {
engine.register_fn("priority", |p: Project, priority: Priority| -> Result<Project, Box<EvalAltResult>> { Ok(p.priority(priority)) });
engine.register_fn("item_type", |p: Project, item_type: ItemType| -> Result<Project, Box<EvalAltResult>> { Ok(p.item_type(item_type)) });
// Base ModelData builders
engine.register_fn("set_base_id", |p: Project, id_i64: i64| -> Result<Project, Box<EvalAltResult>> { Ok(p.set_base_id(id_from_i64(id_i64)?)) });
engine.register_fn("set_base_created_at", |p: Project, time: i64| -> Result<Project, Box<EvalAltResult>> { Ok(p.set_base_created_at(time)) });
engine.register_fn("set_base_modified_at", |p: Project, time: i64| -> Result<Project, Box<EvalAltResult>> { Ok(p.set_base_modified_at(time)) });
engine.register_fn("add_base_comment", |p: Project, comment_id_i64: i64| -> Result<Project, Box<EvalAltResult>> { Ok(p.add_base_comment(id_from_i64(comment_id_i64)?)) });
engine.register_fn("set_base_comments", |p: Project, comment_ids_i64: rhai::Array| -> Result<Project, Box<EvalAltResult>> {
let ids = comment_ids_i64
.into_iter()
.map(|id_dyn: Dynamic| {
let val_i64 = id_dyn.clone().try_cast::<i64>().ok_or_else(|| {
Box::new(EvalAltResult::ErrorMismatchDataType(
"Expected integer for ID".to_string(),
id_dyn.type_name().to_string(),
Position::NONE,
))
})?;
id_from_i64(val_i64)
})
.collect::<Result<Vec<u32>, Box<EvalAltResult>>>()?;
Ok(p.set_base_comments(ids))
});
// --- Database Interaction Functions ---
let db_clone_set = db.clone();

View File

@ -145,6 +145,9 @@ impl BaseModelData {
}
}
pub mod base_data_builder;
pub use base_data_builder::BaseModelDataOps;
/// Builder for BaseModelData
pub struct BaseModelDataBuilder {
id: u32,