Add Svelte docs site and WASM playground
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
use decodal_core::{Data, EmptyLoader, Engine};
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn evaluate(source: &str) -> String {
|
||||
match evaluate_inner(source) {
|
||||
Ok(output) => format!("{{\"ok\":true,\"output\":{}}}", json_string(&output)),
|
||||
Err(error) => format!("{{\"ok\":false,\"error\":{}}}", json_string(&error)),
|
||||
}
|
||||
}
|
||||
|
||||
fn evaluate_inner(source: &str) -> Result<String, String> {
|
||||
let mut engine = Engine::new(EmptyLoader);
|
||||
let module = engine
|
||||
.add_root_source("playground", "playground", source)
|
||||
.map_err(format_diagnostic)?;
|
||||
let value = engine.eval_module(module).map_err(format_diagnostic)?;
|
||||
let data = engine.materialize(&value).map_err(format_diagnostic)?;
|
||||
Ok(format_data(&data, 0))
|
||||
}
|
||||
|
||||
fn format_diagnostic(diagnostic: decodal_core::Diagnostic) -> String {
|
||||
format!(
|
||||
"{:?} at {}:{}..{}: {}",
|
||||
diagnostic.kind,
|
||||
diagnostic.span.source.0,
|
||||
diagnostic.span.start,
|
||||
diagnostic.span.end,
|
||||
diagnostic.message,
|
||||
)
|
||||
}
|
||||
|
||||
fn format_data(data: &Data, indent: usize) -> String {
|
||||
match data {
|
||||
Data::String(value) => json_string(value),
|
||||
Data::Int(value) => value.to_string(),
|
||||
Data::Float(value) => value.to_string(),
|
||||
Data::Bool(value) => value.to_string(),
|
||||
Data::Array(items) => {
|
||||
if items.is_empty() {
|
||||
return String::from("[]");
|
||||
}
|
||||
let mut out = String::from("[\n");
|
||||
for (index, item) in items.iter().enumerate() {
|
||||
out.push_str(&" ".repeat(indent + 2));
|
||||
out.push_str(&format_data(item, indent + 2));
|
||||
if index + 1 != items.len() {
|
||||
out.push(',');
|
||||
}
|
||||
out.push('\n');
|
||||
}
|
||||
out.push_str(&" ".repeat(indent));
|
||||
out.push(']');
|
||||
out
|
||||
}
|
||||
Data::Object(fields) => {
|
||||
if fields.is_empty() {
|
||||
return String::from("{}");
|
||||
}
|
||||
let mut out = String::from("{\n");
|
||||
for (index, field) in fields.iter().enumerate() {
|
||||
out.push_str(&" ".repeat(indent + 2));
|
||||
out.push_str(&json_string(&field.name));
|
||||
out.push_str(": ");
|
||||
out.push_str(&format_data(&field.value, indent + 2));
|
||||
if index + 1 != fields.len() {
|
||||
out.push(',');
|
||||
}
|
||||
out.push('\n');
|
||||
}
|
||||
out.push_str(&" ".repeat(indent));
|
||||
out.push('}');
|
||||
out
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn json_string(value: &str) -> String {
|
||||
let mut out = String::from("\"");
|
||||
for ch in value.chars() {
|
||||
match ch {
|
||||
'"' => out.push_str("\\\""),
|
||||
'\\' => out.push_str("\\\\"),
|
||||
'\n' => out.push_str("\\n"),
|
||||
'\r' => out.push_str("\\r"),
|
||||
'\t' => out.push_str("\\t"),
|
||||
ch if ch.is_control() => {
|
||||
use core::fmt::Write;
|
||||
let _ = write!(out, "\\u{:04x}", ch as u32);
|
||||
}
|
||||
ch => out.push(ch),
|
||||
}
|
||||
}
|
||||
out.push('"');
|
||||
out
|
||||
}
|
||||
Reference in New Issue
Block a user