# OSIRIS Code Structure ## 📁 Directory Organization ### Objects (`src/objects/`) Each OSIRIS object has its own directory with: - `mod.rs` - Object definition and core logic - `rhai.rs` - Rhai integration (CustomType, builder API) ``` src/objects/ ├── mod.rs # Module exports ├── note/ │ ├── mod.rs # Note object definition │ └── rhai.rs # Note Rhai integration └── event/ ├── mod.rs # Event object definition └── rhai.rs # Event Rhai integration ``` ### Rhai Support (`src/rhai_support/`) Core Rhai infrastructure (not object-specific): - `instance.rs` - OsirisInstance type for multi-instance support - `mod.rs` - Module exports and re-exports ``` src/rhai_support/ ├── mod.rs # Re-exports from object modules └── instance.rs # OsirisInstance implementation ``` ### Runner (`src/bin/runner/`) Standalone binary for running OSIRIS scripts: - `main.rs` - CLI and script execution - `engine.rs` - Engine factory with instance configuration ``` src/bin/runner/ ├── main.rs # CLI interface └── engine.rs # Engine configuration ``` ### Core (`src/`) Core OSIRIS functionality: - `store/` - GenericStore, HeroDbClient, BaseData - `index/` - Field indexing - `error/` - Error types - `config/` - Configuration - `interfaces/` - Traits and interfaces - `retrieve/` - Retrieval logic ## 🎯 Design Principles ### 1. **Co-location** Object-specific code lives with the object: ``` objects/note/ ├── mod.rs # Note struct, impl └── rhai.rs # Note Rhai support ``` ### 2. **Separation of Concerns** - **Objects** - Domain models and business logic - **Rhai Support** - Scripting integration - **Store** - Persistence layer - **Runner** - Execution environment ### 3. **Feature Gating** Rhai support is optional via `rhai-support` feature: ```rust #[cfg(feature = "rhai-support")] pub mod rhai; ``` ### 4. **Clean Exports** Clear module boundaries with re-exports: ```rust // src/objects/mod.rs pub mod note; pub use note::Note; // src/rhai_support/mod.rs pub use crate::objects::note::rhai::register_note_api; ``` ## 📝 Adding a New Object ### 1. Create Object Directory ```bash mkdir -p src/objects/task ``` ### 2. Create Object Definition (`mod.rs`) ```rust use crate::store::BaseData; use serde::{Deserialize, Serialize}; #[cfg(feature = "rhai-support")] pub mod rhai; #[derive(Debug, Clone, Serialize, Deserialize, crate::DeriveObject)] pub struct Task { pub base_data: BaseData, #[index] pub title: String, pub completed: bool, } impl Task { pub fn new(ns: String) -> Self { Self { base_data: BaseData::new(ns), title: String::new(), completed: false, } } } ``` ### 3. Create Rhai Integration (`rhai.rs`) ```rust use crate::objects::Task; use rhai::{CustomType, Engine, TypeBuilder}; impl CustomType for Task { fn build(mut builder: TypeBuilder) { builder .with_name("Task") .with_fn("new", |ns: String| Task::new(ns)) .with_fn("set_title", |task: &mut Task, title: String| { task.title = title; task.base_data.update_modified(); }) .with_fn("set_completed", |task: &mut Task, completed: bool| { task.completed = completed; task.base_data.update_modified(); }); } } pub fn register_task_api(engine: &mut Engine) { engine.build_type::(); // Builder pattern engine.register_fn("task", |ns: String| Task::new(ns)); engine.register_fn("title", |mut task: Task, title: String| { task.title = title; task.base_data.update_modified(); task }); engine.register_fn("completed", |mut task: Task, completed: bool| { task.completed = completed; task.base_data.update_modified(); task }); } ``` ### 4. Update Module Exports ```rust // src/objects/mod.rs pub mod task; pub use task::Task; // src/rhai_support/mod.rs pub use crate::objects::task::rhai::register_task_api; ``` ### 5. Register in Engine ```rust // src/bin/runner/engine.rs use osiris::rhai_support::register_task_api; register_task_api(&mut engine); ``` ### 6. Use in Scripts ```rhai let my_task = task("tasks") .title("Complete OSIRIS integration") .completed(true); my_instance.put_task(my_task); ``` ## 🔍 File Responsibilities ### Object `mod.rs` - Struct definition with `#[derive(DeriveObject)]` - Index fields marked with `#[index]` - Constructor methods (`new`, `with_id`) - Business logic methods - Builder pattern methods (optional) ### Object `rhai.rs` - `CustomType` implementation - `register_*_api` function - Rhai-specific builder methods - Type conversions for Rhai ### `rhai_support/instance.rs` - `OsirisInstance` struct - Multi-instance support - CRUD operations per instance - Async → Sync bridge ### `bin/runner/engine.rs` - `OsirisConfig` for instance configuration - `create_osiris_engine_with_config` function - Engine setup and registration ### `bin/runner/main.rs` - CLI argument parsing - Instance configuration from CLI - Script loading and execution ## 🎨 Benefits of This Structure ### 1. **Discoverability** All code for an object is in one place: ``` objects/note/ ├── mod.rs # "What is a Note?" └── rhai.rs # "How do I use Note in Rhai?" ``` ### 2. **Maintainability** Changes to an object are localized: - Add a field → Update `mod.rs` and `rhai.rs` - No hunting through multiple directories ### 3. **Scalability** Easy to add new objects: - Create directory - Add two files - Update exports - Done! ### 4. **Testability** Each object can have its own tests: ``` objects/note/ ├── mod.rs ├── rhai.rs └── tests.rs ``` ### 5. **Clear Dependencies** ``` Objects (domain) → Independent ↓ Rhai Support → Depends on Objects ↓ Runner → Depends on Rhai Support ``` ## 📊 Module Graph ``` osiris (lib) ├── objects/ │ ├── note/ │ │ ├── mod.rs (Note struct) │ │ └── rhai.rs (Note Rhai) │ └── event/ │ ├── mod.rs (Event struct) │ └── rhai.rs (Event Rhai) ├── rhai_support/ │ ├── instance.rs (OsirisInstance) │ └── mod.rs (re-exports) ├── store/ (GenericStore, BaseData) ├── index/ (FieldIndex) └── error/ (Error types) runner (bin) ├── main.rs (CLI) └── engine.rs (Engine factory) ``` ## ✅ Summary **Old Structure:** ``` src/rhai_support/ ├── note_rhai.rs ├── event_rhai.rs ├── engine.rs └── instance.rs ``` **New Structure:** ``` src/objects/ ├── note/ │ ├── mod.rs │ └── rhai.rs └── event/ ├── mod.rs └── rhai.rs src/rhai_support/ ├── instance.rs └── mod.rs (re-exports only) ``` **Benefits:** - ✅ Better organization - ✅ Co-located code - ✅ Easier to find things - ✅ Cleaner separation - ✅ Scalable structure