use crate::db::Db; use rhailib_macros::{ register_authorized_create_by_id_fn, register_authorized_delete_by_id_fn, register_authorized_get_by_id_fn, }; use rhai::plugin::*; use rhai::{Array, Dynamic, Engine, EvalAltResult, Module}; use std::mem; use std::sync::Arc; use crate::models::calendar::{AttendanceStatus, Attendee, Calendar, Event}; type RhaiCalendar = Calendar; type RhaiEvent = Event; type RhaiAttendee = Attendee; use crate::db::hero::OurDB; use crate::db::Collection; #[export_module] mod rhai_calendar_module { use super::{AttendanceStatus, RhaiAttendee, RhaiCalendar, RhaiEvent}; // --- Attendee Builder --- #[rhai_fn(name = "new_attendee", return_raw)] pub fn new_attendee(contact_id: i64) -> Result> { Ok(Attendee::new(contact_id as u32)) } #[rhai_fn(name = "status", return_raw)] pub fn set_attendee_status( attendee: &mut RhaiAttendee, status_str: String, ) -> Result> { let status = match status_str.to_lowercase().as_str() { "accepted" => AttendanceStatus::Accepted, "declined" => AttendanceStatus::Declined, "tentative" => AttendanceStatus::Tentative, "noresponse" => AttendanceStatus::NoResponse, _ => { return Err(EvalAltResult::ErrorSystem( "Invalid Status".to_string(), "Must be one of: Accepted, Declined, Tentative, NoResponse".into(), ) .into()) } }; let owned = std::mem::take(attendee); *attendee = owned.status(status); Ok(attendee.clone()) } // --- Event Builder --- #[rhai_fn(name = "new_event", return_raw)] pub fn new_event() -> Result> { Ok(Event::new()) } #[rhai_fn(name = "title", return_raw)] pub fn set_event_title( event: &mut RhaiEvent, title: String, ) -> Result> { let owned = std::mem::take(event); *event = owned.title(title); Ok(event.clone()) } #[rhai_fn(name = "description", return_raw)] pub fn set_event_description( event: &mut RhaiEvent, description: String, ) -> Result> { let owned = std::mem::take(event); *event = owned.description(description); Ok(event.clone()) } #[rhai_fn(name = "location", return_raw)] pub fn set_event_location( event: &mut RhaiEvent, location: String, ) -> Result> { let owned = std::mem::take(event); *event = owned.location(location); Ok(event.clone()) } #[rhai_fn(name = "add_attendee", return_raw)] pub fn add_event_attendee( event: &mut RhaiEvent, attendee: RhaiAttendee, ) -> Result> { let owned = std::mem::take(event); *event = owned.add_attendee(attendee); Ok(event.clone()) } #[rhai_fn(name = "reschedule", return_raw)] pub fn reschedule_event( event: &mut RhaiEvent, start_time: i64, end_time: i64, ) -> Result> { let owned = std::mem::take(event); *event = owned.reschedule(start_time, end_time); Ok(event.clone()) } // --- Calendar Builder --- #[rhai_fn(name = "new_calendar", return_raw)] pub fn new_calendar(name: String) -> Result> { Ok(Calendar::new().name(name)) } #[rhai_fn(name = "calendar_name", return_raw)] pub fn set_calendar_name( calendar: &mut RhaiCalendar, name: String, ) -> Result> { let owned = std::mem::take(calendar); *calendar = owned.name(name); Ok(calendar.clone()) } #[rhai_fn(name = "calendar_description", return_raw)] pub fn set_calendar_description( calendar: &mut RhaiCalendar, description: String, ) -> Result> { let owned = std::mem::take(calendar); *calendar = owned.description(description); Ok(calendar.clone()) } #[rhai_fn(name = "add_event", return_raw)] pub fn add_calendar_event( calendar: &mut RhaiCalendar, event_id: i64, ) -> Result> { let owned = std::mem::take(calendar); *calendar = owned.add_event(event_id as u32); Ok(calendar.clone()) } // --- Getters --- // Calendar #[rhai_fn(name = "get_calendar_id")] pub fn get_calendar_id(c: &mut RhaiCalendar) -> i64 { c.base.id as i64 } #[rhai_fn(name = "get_calendar_name")] pub fn get_calendar_name(c: &mut RhaiCalendar) -> String { c.name.clone() } #[rhai_fn(name = "get_calendar_description")] pub fn get_calendar_description(c: &mut RhaiCalendar) -> Option { c.description.clone() } #[rhai_fn(name = "get_calendar_events")] pub fn get_calendar_events(c: &mut RhaiCalendar) -> Array { c.events.iter().map(|id| Dynamic::from(*id as i64)).collect() } // Event #[rhai_fn(name = "get_event_id")] pub fn get_event_id(e: &mut RhaiEvent) -> i64 { e.base.id as i64 } #[rhai_fn(name = "get_event_title")] pub fn get_event_title(e: &mut RhaiEvent) -> String { e.title.clone() } #[rhai_fn(name = "get_event_description")] pub fn get_event_description(e: &mut RhaiEvent) -> Option { e.description.clone() } #[rhai_fn(name = "get_event_start_time")] pub fn get_event_start_time(e: &mut RhaiEvent) -> i64 { e.start_time } #[rhai_fn(name = "get_event_end_time")] pub fn get_event_end_time(e: &mut RhaiEvent) -> i64 { e.end_time } #[rhai_fn(name = "get_event_attendees")] pub fn get_event_attendees(e: &mut RhaiEvent) -> Array { e.attendees.iter().map(|a| Dynamic::from(a.clone())).collect() } #[rhai_fn(name = "get_event_location")] pub fn get_event_location(e: &mut RhaiEvent) -> Option { e.location.clone() } // Attendee #[rhai_fn(name = "get_attendee_contact_id")] pub fn get_attendee_contact_id(a: &mut RhaiAttendee) -> i64 { a.contact_id as i64 } #[rhai_fn(name = "get_attendee_status")] pub fn get_attendee_status(a: &mut RhaiAttendee) -> String { format!("{:?}", a.status) } } pub fn register_calendar_rhai_module(engine: &mut Engine) { let mut module = exported_module!(rhai_calendar_module); register_authorized_create_by_id_fn!( module: &mut module, rhai_fn_name: "save_calendar", resource_type_str: "Calendar", rhai_return_rust_type: heromodels::models::calendar::Calendar ); register_authorized_get_by_id_fn!( module: &mut module, rhai_fn_name: "get_calendar", resource_type_str: "Calendar", rhai_return_rust_type: heromodels::models::calendar::Calendar ); register_authorized_delete_by_id_fn!( module: &mut module, rhai_fn_name: "delete_calendar", resource_type_str: "Calendar", rhai_return_rust_type: heromodels::models::calendar::Calendar ); register_authorized_create_by_id_fn!( module: &mut module, rhai_fn_name: "save_event", resource_type_str: "Event", rhai_return_rust_type: heromodels::models::calendar::Event ); register_authorized_get_by_id_fn!( module: &mut module, rhai_fn_name: "get_event", resource_type_str: "Event", rhai_return_rust_type: heromodels::models::calendar::Event ); register_authorized_delete_by_id_fn!( module: &mut module, rhai_fn_name: "delete_event", resource_type_str: "Event", rhai_return_rust_type: heromodels::models::calendar::Event ); engine.register_global_module(module.into()); }