pub mod compiler;
mod debug;
mod exec;
mod external_type;
pub mod runtime;
pub mod snapshot_diff;
use std::path::PathBuf;
use compiler::{Database, ItemSource, TypeError};
use runtime::{binary, conv};
use snafu::{ResultExt as _, Snafu};
use tokio::fs;
use wac_graph::{EncodeError, PlugError};
use wasmtime::component::Val;
pub type Result<T, E = Error> = std::result::Result<T, E>;
#[derive(Debug, Snafu)]
pub enum Error {
#[snafu(display("parse error: {}", message))]
Parse {
message: String,
},
#[snafu(display("type error"))]
Type { source: TypeError },
#[snafu(display("link error"))]
Link { source: anyhow::Error },
#[snafu(display("link plugging error"))]
LinkPlug { source: PlugError },
#[snafu(display("link encode error"))]
LinkEncode { source: EncodeError },
#[snafu(display("io error at {path}"))]
IO {
source: std::io::Error,
path: String,
},
#[snafu(display("execution error"))]
Exec { source: snafu::Whatever },
}
pub async fn run(src: &str, path_root: impl Into<PathBuf>) -> Result<Val> {
let mut item_source = ItemSource::default();
binary::register_binary_operator_functions(&mut item_source);
conv::register_conversion_funcs(&mut item_source);
let mut db = Database::new(path_root, src.to_string(), item_source);
let code = compiler::root_component(&mut db).await?;
if let Ok(prefix) = std::env::var("BLR_SNAPSHOT") {
let file_path = PathBuf::from(prefix).with_extension("blr.wasm");
fs::write(&file_path, &code).await.unwrap();
tracing::debug!(file_path = %file_path.display(), "snapshot saved");
}
exec::run_wasm(&code).await.context(ExecSnafu)
}
pub fn val_to_string(val: Val) -> String {
match val {
Val::S32(v) => v.to_string(),
Val::S64(v) => v.to_string(),
Val::Bool(v) => v.to_string(),
Val::S8(v) => v.to_string(),
Val::U8(v) => v.to_string(),
Val::S16(v) => v.to_string(),
Val::U16(v) => v.to_string(),
Val::U32(v) => v.to_string(),
Val::U64(v) => v.to_string(),
Val::Float32(v) => v.to_string(),
Val::Float64(v) => v.to_string(),
Val::Char(v) => v.to_string(),
Val::String(v) => v,
Val::List(_vals) => todo!(),
Val::Record(fields) => format!("{:?}", fields),
Val::Tuple(_vals) => todo!(),
Val::Variant(_, _val) => todo!(),
Val::Enum(_) => todo!(),
Val::Option(_val) => todo!(),
Val::Result(_val) => todo!(),
Val::Flags(_items) => todo!(),
Val::Resource(_resource_any) => todo!(),
Val::Future(_future_any) => todo!(),
Val::Stream(_stream_any) => todo!(),
Val::ErrorContext(_error_context_any) => todo!(),
}
}