1pub mod compiler;
4mod debug;
5mod exec;
6mod external_type;
7pub mod runtime;
8pub mod snapshot_diff;
9
10use std::path::PathBuf;
11
12use compiler::{Database, ItemSource, TypeError};
13use runtime::{binary, conv};
14use snafu::{ResultExt as _, Snafu};
15use tokio::fs;
16use wac_graph::{EncodeError, PlugError};
17use wasmtime::component::Val;
18
19pub type Result<T, E = Error> = std::result::Result<T, E>;
20
21#[derive(Debug, Snafu)]
22pub enum Error {
23 #[snafu(display("parse error: {}", message))]
24 Parse {
25 message: String,
27 },
28 #[snafu(display("type error"))]
29 Type { source: TypeError },
30 #[snafu(display("link error"))]
32 Link { source: anyhow::Error },
33 #[snafu(display("link plugging error"))]
34 LinkPlug { source: PlugError },
35 #[snafu(display("link encode error"))]
36 LinkEncode { source: EncodeError },
37 #[snafu(display("io error at {path}"))]
38 IO {
39 source: std::io::Error,
40 path: String,
41 },
42 #[snafu(display("execution error"))]
43 Exec { source: snafu::Whatever },
44}
45
46pub async fn run(src: &str, path_root: impl Into<PathBuf>) -> Result<Val> {
47 let mut item_source = ItemSource::default();
48 binary::register_binary_operator_functions(&mut item_source);
49 conv::register_conversion_funcs(&mut item_source);
50 let mut db = Database::new(path_root, src.to_string(), item_source);
51 let code = compiler::root_component(&mut db).await?;
52
53 if let Ok(prefix) = std::env::var("BLR_SNAPSHOT") {
54 let file_path = PathBuf::from(prefix).with_extension("blr.wasm");
56 fs::write(&file_path, &code).await.unwrap();
57 tracing::debug!(file_path = %file_path.display(), "snapshot saved");
58 }
59
60 exec::run_wasm(&code).await.context(ExecSnafu)
61}
62
63pub fn val_to_string(val: Val) -> String {
64 match val {
65 Val::S32(v) => v.to_string(),
66 Val::S64(v) => v.to_string(),
67 Val::Bool(v) => v.to_string(),
68 Val::S8(v) => v.to_string(),
69 Val::U8(v) => v.to_string(),
70 Val::S16(v) => v.to_string(),
71 Val::U16(v) => v.to_string(),
72 Val::U32(v) => v.to_string(),
73 Val::U64(v) => v.to_string(),
74 Val::Float32(v) => v.to_string(),
75 Val::Float64(v) => v.to_string(),
76 Val::Char(v) => v.to_string(),
77 Val::String(v) => v,
79 Val::List(_vals) => todo!(),
80 Val::Record(fields) => format!("{:?}", fields),
81 Val::Tuple(_vals) => todo!(),
82 Val::Variant(_, _val) => todo!(),
83 Val::Enum(_) => todo!(),
84 Val::Option(_val) => todo!(),
85 Val::Result(_val) => todo!(),
86 Val::Flags(_items) => todo!(),
87 Val::Resource(_resource_any) => todo!(),
88 Val::Future(_future_any) => todo!(),
89 Val::Stream(_stream_any) => todo!(),
90 Val::ErrorContext(_error_context_any) => todo!(),
91 }
92}