Major Changes:
- Moved Rhai support from rhai_support/ to rhai/ module
- Implemented context-based execution with signatory access control
- Added TypeRegistry for dynamic type registration and object creation
- Refactored engine to use context (Vec<String>) instead of instance
- Removed old runner binary (moved to runner_rust crate)
Rhai Module:
- engine.rs: Core Rhai engine with context-based get_context()
- functions.rs: Rhai function bindings (create_note, create_event, etc.)
- mod.rs: Module exports and organization
Store Improvements:
- TypeRegistry for registering object types and creators
- Generic store uses type registry for dynamic object creation
- Improved error handling and type safety
Documentation:
- RHAI_REFACTOR_COMPLETE.md: Refactoring details
- SIGNATORY_ACCESS_CONTROL.md: Context-based access control
- TYPE_REGISTRY_DESIGN.md: Type registry architecture
- REFACTORING_COMPLETE.md: Overall refactoring summary
- TESTS_COMPLETE.md: Testing documentation
Build Status: ✅ Compiles successfully with minor warnings
114 lines
3.1 KiB
Rust
114 lines
3.1 KiB
Rust
use crate::error::Result;
|
|
use crate::store::BaseData;
|
|
use serde::{Deserialize, Serialize};
|
|
use std::fmt::Debug;
|
|
|
|
/// Represents an index key for an object field
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
pub struct IndexKey {
|
|
/// The name of the index key (field name)
|
|
pub name: &'static str,
|
|
|
|
/// The value of the index key for this object instance
|
|
pub value: String,
|
|
}
|
|
|
|
impl IndexKey {
|
|
pub fn new(name: &'static str, value: impl ToString) -> Self {
|
|
Self {
|
|
name,
|
|
value: value.to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Core trait that all OSIRIS objects must implement
|
|
/// Similar to heromodels Model trait but adapted for OSIRIS
|
|
pub trait Object: Debug + Clone + Serialize + for<'de> Deserialize<'de> + Send + Sync {
|
|
/// Get the object type name (used for routing/identification)
|
|
fn object_type() -> &'static str
|
|
where
|
|
Self: Sized;
|
|
|
|
/// Get a reference to the base data
|
|
fn base_data(&self) -> &BaseData;
|
|
|
|
/// Get a mutable reference to the base data
|
|
fn base_data_mut(&mut self) -> &mut BaseData;
|
|
|
|
/// Get the unique ID for this object
|
|
fn id(&self) -> &str {
|
|
&self.base_data().id
|
|
}
|
|
|
|
/// Set the unique ID for this object
|
|
fn set_id(&mut self, id: impl ToString) {
|
|
self.base_data_mut().id = id.to_string();
|
|
}
|
|
|
|
/// Get the namespace for this object
|
|
fn namespace(&self) -> &str {
|
|
&self.base_data().ns
|
|
}
|
|
|
|
/// Returns a list of index keys for this object instance
|
|
/// These are generated from fields marked with #[index]
|
|
/// The default implementation returns base_data indexes only
|
|
fn index_keys(&self) -> Vec<IndexKey> {
|
|
let base = self.base_data();
|
|
let mut keys = Vec::new();
|
|
|
|
// Index MIME type if present
|
|
if let Some(mime) = &base.mime {
|
|
keys.push(IndexKey::new("mime", mime));
|
|
}
|
|
|
|
keys
|
|
}
|
|
|
|
/// Return a list of field names which have an index applied
|
|
/// This should be implemented by the derive macro
|
|
fn indexed_fields() -> Vec<&'static str>
|
|
where
|
|
Self: Sized,
|
|
{
|
|
Vec::new()
|
|
}
|
|
|
|
/// Get the full-text searchable content for this object
|
|
/// Override this to provide custom searchable text
|
|
fn searchable_text(&self) -> Option<String> {
|
|
None
|
|
}
|
|
|
|
/// Serialize the object to JSON
|
|
fn to_json(&self) -> Result<String> {
|
|
serde_json::to_string(self).map_err(Into::into)
|
|
}
|
|
|
|
/// Deserialize the object from JSON
|
|
fn from_json(json: &str) -> Result<Self>
|
|
where
|
|
Self: Sized,
|
|
{
|
|
serde_json::from_str(json).map_err(Into::into)
|
|
}
|
|
|
|
/// Update the modified timestamp
|
|
fn touch(&mut self) {
|
|
self.base_data_mut().update_modified();
|
|
}
|
|
}
|
|
|
|
/// Trait for objects that can be stored in OSIRIS
|
|
/// This is automatically implemented for all types that implement Object
|
|
pub trait Storable: Object {
|
|
/// Prepare the object for storage (update timestamps, etc.)
|
|
fn prepare_for_storage(&mut self) {
|
|
self.touch();
|
|
}
|
|
}
|
|
|
|
// Blanket implementation
|
|
impl<T: Object> Storable for T {}
|