Skip to main content

ShapeEngine

Struct ShapeEngine 

Source
pub struct ShapeEngine {
    pub runtime: Runtime,
    pub default_data: DataFrame,
    /* private fields */
}
Expand description

The unified Shape execution engine

Fields§

§runtime: Runtime

The runtime environment

§default_data: DataFrame

Default data for expressions/assignments

Implementations§

Source§

impl ShapeEngine

Source

pub fn execute( &mut self, executor: &mut impl ProgramExecutor, source: &str, ) -> Result<ExecutionResult>

Execute a Shape program from source code (sync mode)

This method allows blocking data loads (REPL mode). For scripts/backtests, use execute_async() instead.

Source

pub async fn execute_async( &mut self, executor: &mut impl ProgramExecutor, source: &str, ) -> Result<ExecutionResult>

Execute a Shape program with async prefetching (Phase 6/8)

This method:

  1. Sets Async data mode (runtime data requests use cache, not blocking)
  2. Parses and analyzes the program
  3. Determines required data (symbols/timeframes)
  4. Prefetches data concurrently
  5. Executes synchronously using cached data
§Example
let provider = DataFrameAdapter::new(...);
let mut engine = ShapeEngine::with_async_provider(provider)?;
let result = engine.execute_async(&interpreter, "let sma = close.sma(20)").await?;
Source

pub async fn execute_repl( &mut self, executor: &mut impl ProgramExecutor, source: &str, ) -> Result<ExecutionResult>

Execute a REPL command with persistent state

Unlike execute_async, this uses incremental analysis where variables and functions persist across commands. Call init_repl() once before the first call to this method.

Source

pub fn parse_and_analyze(&mut self, source: &str) -> Result<Program>

Parse and analyze source code without executing it.

Returns the analyzed AST Program, ready for compilation. Used by the recompile-and-resume flow.

Source

pub fn execute_repl_command( &mut self, executor: &mut impl ProgramExecutor, command: &str, ) -> Result<ExecutionResult>

Execute a REPL command

Source§

impl ShapeEngine

Source

pub fn load_stdlib(&mut self) -> Result<()>

Load stdlib core modules only. Domain-specific modules (finance, iot, etc.) require explicit import.

Source§

impl ShapeEngine

Source

pub fn new() -> Result<Self>

Create a new Shape engine

Source

pub fn with_data(data: DataFrame) -> Result<Self>

Create engine with data

Source

pub fn with_async_provider(provider: SharedAsyncProvider) -> Result<Self>

Create engine with async data provider (Phase 6)

This constructor sets up the engine with an async data provider. Call execute_async() instead of execute() to use async prefetching.

Source

pub fn init_repl(&mut self)

Initialize REPL mode

Call this once after creating the engine and loading stdlib, but before executing any REPL commands. This configures output adapters for REPL-friendly display.

Source

pub fn capture_bootstrap_state(&self) -> Result<EngineBootstrapState>

Capture semantic/runtime state after stdlib bootstrap.

Call this on an engine that has already loaded stdlib.

Source

pub fn apply_bootstrap_state(&mut self, state: &EngineBootstrapState)

Apply a previously captured stdlib bootstrap state.

Source

pub fn set_script_path(&mut self, path: impl Into<String>)

Set the script path for snapshot metadata.

Source

pub fn script_path(&self) -> Option<&str>

Get the current script path, if set.

Source

pub fn enable_snapshot_store(&mut self, store: SnapshotStore)

Enable snapshotting with a content-addressed store.

Source

pub fn last_snapshot(&self) -> Option<&HashDigest>

Get last snapshot ID, if any.

Source

pub fn snapshot_store(&self) -> Option<&SnapshotStore>

Access the snapshot store (if configured).

Source

pub fn store_snapshot_blob<T: Serialize>(&self, value: &T) -> Result<HashDigest>

Store a serializable blob in the snapshot store and return its hash.

Source

pub fn snapshot_with_hashes( &mut self, vm_hash: Option<HashDigest>, bytecode_hash: Option<HashDigest>, ) -> Result<HashDigest>

Create a snapshot of semantic/runtime state, with optional VM/bytecode hashes supplied by the executor.

Source

pub fn load_snapshot( &self, snapshot_id: &HashDigest, ) -> Result<(SemanticSnapshot, ContextSnapshot, Option<HashDigest>, Option<HashDigest>)>

Load a snapshot and return its components (semantic/context + optional vm/bytecode hashes).

Source

pub fn apply_snapshot( &mut self, semantic: SemanticSnapshot, context: ContextSnapshot, ) -> Result<()>

Apply a semantic/context snapshot to the current engine.

Source

pub fn register_extension_modules(&mut self, modules: &[ParsedModuleSchema])

Register extension module namespaces with the runtime. Must be called before execute() so the module loader recognizes modules like duckdb.

Source

pub fn register_language_runtime_artifacts(&mut self)

Register Shape source artifacts bundled by loaded language runtime extensions.

Each language runtime extension (e.g. Python, TypeScript) may bundle a .shape module source that defines the extension’s own namespace. The namespace is the language identifier itself (e.g. "python", "typescript") – NOT "std::core::*".

Call this after loading extensions but before execute().

Source

pub fn set_source(&mut self, source: &str)

Set the current source text for error messages

Call this before execute() to enable source-contextualized error messages. The source is used during bytecode compilation to populate debug info.

Source

pub fn current_source(&self) -> Option<&str>

Get the current source text (if set)

Source

pub fn register_provider(&mut self, name: &str, provider: SharedAsyncProvider)

Register a data provider (Phase 8)

Registers a named provider for runtime data access.

§Example
let adapter = Arc::new(DataFrameAdapter::new(...));
engine.register_provider("data", adapter);
Source

pub fn set_default_provider(&mut self, name: &str) -> Result<()>

Set default data provider (Phase 8)

Sets which provider to use for runtime data access when no provider is specified.

Source

pub fn register_type_mapping(&mut self, type_name: &str, mapping: TypeMapping)

Register a type mapping (Phase 8)

Registers a type mapping that defines the expected DataFrame structure for a given type name. Type mappings enable validation and JIT optimization.

§Example
use shape_core::runtime::type_mapping::TypeMapping;

// Register the Candle type (from stdlib)
let candle_mapping = TypeMapping::new("Candle".to_string())
    .add_field("timestamp", "timestamp")
    .add_field("open", "open")
    .add_field("high", "high")
    .add_field("low", "low")
    .add_field("close", "close")
    .add_field("volume", "volume")
    .add_required("timestamp")
    .add_required("open")
    .add_required("high")
    .add_required("low")
    .add_required("close");

engine.register_type_mapping("Candle", candle_mapping);
Source

pub fn get_runtime(&self) -> &Runtime

Get the current runtime state (for REPL)

Source

pub fn get_runtime_mut(&mut self) -> &mut Runtime

Get mutable runtime (for REPL state updates)

Source

pub fn get_variable_format_hint(&self, name: &str) -> Option<String>

Get the format hint for a variable (if any)

Returns the format hint specified in the variable’s type annotation. Example: let rate: Number @ Percent = 0.05 → Some(“Percent”)

Source

pub fn format_value_string( &mut self, value: f64, type_name: &str, format_name: Option<&str>, params: &HashMap<String, Value>, ) -> Result<String>

Format a value using Shape runtime format evaluation

This uses the format definitions from stdlib (e.g., stdlib/core/formats.shape) instead of Rust fallback formatters.

§Arguments
  • value - The value to format (as f64 for numbers)
  • type_name - The Shape type name (“Number”, “String”, etc.)
  • format_name - Optional format name (e.g., “Percent”, “Currency”). Uses default if None.
  • params - Format parameters as JSON (e.g., {“decimals”: 1})
§Returns

Formatted string on success

§Example
let formatted = engine.format_value_string(
    0.1234,
    "Number",
    Some("Percent"),
    &HashMap::new()
)?;
assert_eq!(formatted, "12.34%");
Source

pub fn load_extension( &mut self, path: &Path, config: &Value, ) -> Result<LoadedExtension>

Load a data source extension from a shared library

§Arguments
  • path - Path to the extension shared library (.so, .dll, .dylib)
  • config - Configuration value for the extension
§Returns

Information about the loaded extension

§Safety

Loading extensions executes arbitrary code. Only load from trusted sources.

§Example
let info = engine.load_extension(Path::new("./libshape_ext_csv.so"), &json!({}))?;
println!("Loaded: {} v{}", info.name, info.version);
Source

pub fn unload_extension(&mut self, name: &str) -> bool

Unload an extension by name

§Arguments
  • name - Extension name to unload
§Returns

true if plugin was unloaded, false if not found

Source

pub fn list_extensions(&self) -> Vec<String>

List all loaded extension names

Source

pub fn get_extension_query_schema( &self, name: &str, ) -> Option<ParsedQuerySchema>

Get query schema for an extension (for LSP autocomplete)

§Arguments
  • name - Extension name
§Returns

The query schema if extension exists

Source

pub fn get_extension_output_schema( &self, name: &str, ) -> Option<ParsedOutputSchema>

Get output schema for an extension (for LSP autocomplete)

§Arguments
  • name - Extension name
§Returns

The output schema if extension exists

Source

pub fn get_extension(&self, name: &str) -> Option<Arc<ExtensionDataSource>>

Get an extension data source by name

Source

pub fn get_extension_module_schema( &self, module_name: &str, ) -> Option<ParsedModuleSchema>

Get extension module schema by module namespace.

Source

pub fn module_exports_from_extensions(&self) -> Vec<ModuleExports>

Build VM extension modules from loaded extension module capabilities.

Source

pub fn language_runtimes(&self) -> HashMap<String, Arc<PluginLanguageRuntime>>

Return all loaded language runtimes, keyed by language identifier.

Source

pub fn invoke_extension_module_nb( &self, module_name: &str, function: &str, args: &[ValueWord], ) -> Result<ValueWord>

Invoke one loaded module export via module namespace.

Source

pub fn invoke_extension_module_wire( &self, module_name: &str, function: &str, args: &[WireValue], ) -> Result<WireValue>

Invoke one loaded module export via module namespace.

Source

pub fn enable_progress_tracking(&mut self) -> Arc<ProgressRegistry>

Enable progress tracking and return the registry for subscriptions

Call this before executing code that may report progress. The returned registry can be used to subscribe to progress events.

§Example
let registry = engine.enable_progress_tracking();
let mut receiver = registry.subscribe();

// In a separate task
while let Ok(event) = receiver.recv().await {
    println!("Progress: {:?}", event);
}
Source

pub fn progress_registry(&self) -> Option<Arc<ProgressRegistry>>

Get the current progress registry if enabled

Source

pub fn has_pending_progress(&self) -> bool

Check if there are pending progress events

Source

pub fn poll_progress(&self) -> Option<ProgressEvent>

Poll for progress events (non-blocking)

Returns the next progress event if available, or None if queue is empty.

Trait Implementations§

Source§

impl Default for ShapeEngine

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more