#![allow(dead_code)]
use std::sync::Arc;
use vertep_core::datamodel::{DatamodelRegistry, Event, EventType, Value};
use vertep_core::ir::Chart;
use vertep_runtime::{Address, Node, NodeConfig, Shell, Storage, VirtualClock};
use vertep_store::MemoryStore;
pub const T0: i64 = 1_794_355_200_000;
pub fn ty(name: &str) -> String {
format!("https://example.org/charts/{name}")
}
pub fn chart(xml: &str) -> Chart {
let opts = vertep_scxml::ReadOptions::new()
.with_datamodels(&vertep_scxml::AnyDatamodel)
.with_resolver(&vertep_scxml::DeferResolver);
vertep_scxml::read(xml, &opts)
.unwrap_or_else(|e| panic!("chart reads: {e:?}"))
.chart
}
pub fn scxml(initial: &str, body: &str) -> Chart {
chart(&format!(
r#"<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:vt="https://w3id.org/vertep/vt#" version="1.0" initial="{initial}">{body}</scxml>"#
))
}
pub fn ecma_scxml(initial: &str, body: &str) -> Chart {
chart(&format!(
r#"<scxml xmlns="http://www.w3.org/2005/07/scxml" xmlns:vt="https://w3id.org/vertep/vt#" version="1.0" datamodel="ecmascript" initial="{initial}">{body}</scxml>"#
))
}
pub fn ecma() -> Arc<dyn DatamodelRegistry + Send + Sync> {
Arc::new(vertep_dm_ecma::EcmaRegistry)
}
pub fn node_on(store: Arc<dyn Storage>, clock: &VirtualClock, config: NodeConfig) -> Node {
let shell = Shell {
spawn: Arc::new(vertep_runtime::shell::TokioSpawn),
clock: Arc::new(clock.clone()),
sleep: Arc::new(clock.clone()),
};
Node::builder(store, shell)
.datamodels(ecma())
.config(config)
.build()
}
pub fn fresh() -> (Node, VirtualClock, Arc<MemoryStore>) {
let store = Arc::new(MemoryStore::new());
let clock = VirtualClock::new(T0);
let node = node_on(store.clone(), &clock, NodeConfig::default());
(node, clock, store)
}
pub fn ev(name: &str) -> Event {
Event::named(name, EventType::External)
}
pub fn ev_data(name: &str, data: Value) -> Event {
Event {
name: name.into(),
data,
..Event::default()
}
}
pub fn va(name: &str, key: &str) -> Address {
Address::virtual_actor(&ty(name), key).unwrap()
}
pub fn obj(kv: &[(&str, Value)]) -> Value {
Value::Object(
kv.iter()
.map(|(k, v)| ((*k).to_owned(), v.clone()))
.collect(),
)
}
struct NoStates;
impl vertep_core::datamodel::StateQuery for NoStates {
fn in_state(&self, _id: &str) -> bool {
false
}
}
pub fn data_of(snapshot: &Value, expr: &str) -> Option<Value> {
let mut dm = vertep_dm_ecma::create("ecmascript")?;
dm.restore(snapshot).ok()?;
dm.eval_value(expr, &NoStates).ok()
}
pub fn field(v: &Value, k: &str) -> Option<Value> {
match v {
Value::Object(kv) => kv.iter().find(|(key, _)| key == k).map(|(_, v)| v.clone()),
_ => None,
}
}