konjure_lang/lib.rs
1//! Konjure's reusable language: nominal types, algebraic enums, methods, traits, functions,
2//! and persistent ECS systems with typed lifecycle callbacks.
3//!
4//! The Rust implementation is shared unchanged by native and WASM clients. [`compile`]
5//! resolves supplied modules and checks every initializer, default, and function or
6//! callback body, including unused declarations. [`Machine`] preserves those checked
7//! types, validates runtime values and world operations, and publishes only accepted
8//! state. Source spans and deterministic snapshots are part of the public interface.
9//!
10//! ```
11//! use konjure_lang::{compile, Machine, Limits, Value};
12//! use std::collections::BTreeMap;
13//! let program = compile("func twice(x: f64) -> Res[f64, DataError] { ret Ok((x * 2)?); }", &BTreeMap::new()).unwrap();
14//! let mut machine = Machine::new(program, Limits::default())?;
15//! assert_eq!(machine.invoke("twice", vec![Value::Number(3.)])?.to_string(), "Ok(6)");
16//! # Ok::<(), Box<dyn std::error::Error>>(())
17//! ```
18//!
19//! Type methods are checked before any machine exists:
20//! ```
21//! use konjure_lang::compile;
22//! use std::collections::BTreeMap;
23//! let source = "type Counter { value: Number = 0; func read() -> Number { ret self.value; } }";
24//! assert!(compile(source, &BTreeMap::new()).is_ok());
25//! let invalid = "type Counter { func unused() -> Number { ret false; } }";
26//! assert!(compile(invalid, &BTreeMap::new()).is_err());
27//! ```
28//! Functions are ordinary statically typed values. Named language and registered
29//! native functions can be passed, returned, stored in lists and fields, and called
30//! through arbitrary expressions. Polymorphic builtins such as `print` specialize
31//! when an expected concrete function signature is available:
32//! ```
33//! use konjure_lang::{compile, Limits, Machine};
34//! use std::collections::BTreeMap;
35//! let source = r#"
36//! func report(output: func(String) -> Unit) -> Unit {
37//! output("hello");
38//! }
39//! report(print);
40//! "#;
41//! let machine = Machine::new(compile(source, &BTreeMap::new()).unwrap(), Limits::default())?;
42//! assert_eq!(machine.snapshot().logs, ["hello"]);
43//! # Ok::<(), Box<dyn std::error::Error>>(())
44//! ```
45//!
46//! `Button.action` stores `func() -> Res[Unit, DataError]`; `Slider.action` stores
47//! `func(Number) -> Res[Unit, DataError]`. Hosts invoke these Rust-owned values with
48//! [`Machine::invoke_component`], without reconstructing a function name from JSON.
49//! A read-only bound method captures a record copy. Mutating callbacks explicitly
50//! use `bind[T](entity).method` to retain the entity/component identity and commit
51//! receiver edits transactionally. The checker rejects capturing a mutating method
52//! from a copied record. Anonymous closures are not part of the current syntax.
53//!
54//! Numeric operations and indexing produce `Res[T, DataError]`; owned `get`
55//! methods produce `Opt[T]`. Exhaustive `match` handles cases, and `?` returns an
56//! error or absence from a compatible result-returning function. Ordinary
57//! [`Machine::invoke`] returns algebraic failures as values. Module initialization,
58//! system callbacks and [`spatial::SpatialRuntime`] actions are host transaction
59//! boundaries: an error result rejects that boundary with a source diagnostic.
60//! Resource exhaustion and violated host contracts remain host diagnostics.
61#![deny(missing_docs)]
62
63mod data;
64#[cfg(feature = "terminal-diagnostics")]
65pub mod diagnostics;
66pub mod inspection;
67pub mod live;
68pub use live::{
69 LiveClientMessage, LiveCommand, LiveDebugReport, LiveDebugStatus, LiveDiagnostic, LiveError,
70 LiveEvent, LiveHistory, LivePeer, LiveRole, LiveRuntime, LiveServerMessage, ProgramSource,
71};
72mod media_values;
73pub mod methods;
74mod patterns;
75#[cfg(feature = "terminal-diagnostics")]
76pub use diagnostics::render_diagnostic;
77pub mod ast;
78pub mod catalog;
79pub mod native;
80pub mod parser;
81mod program;
82mod runtime;
83pub mod spatial;
84mod typecheck;
85pub mod ui;
86mod value;
87pub use ast::{Diagnostic, IndexExpr, Span, Type};
88pub use native::{NativeFunction, NativeRegistry};
89pub use parser::{parse, tokenize};
90pub use program::{
91 ExpressionReference, MethodSymbol, Program, ProgramMetadata, Symbol, compile,
92 compile_with_registry,
93};
94pub use runtime::{EntitySnapshot, Limits, Machine, Snapshot, TraceEntry};
95pub use value::{ComponentReference, EnumValue, FunctionTarget, FunctionValue, RecordValue, Value};