From 921bd4d7045e524f75a629cb5dc0e0b471ba1d4d Mon Sep 17 00:00:00 2001 From: Mark Date: Thu, 21 Sep 2023 12:03:28 -0700 Subject: [PATCH] Added proper WASM api --- src/lib.rs | 84 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 74 insertions(+), 10 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index d0737fc..ceed6cc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,28 +10,92 @@ mod context; mod formattedtext; mod errors; mod evaluate; +mod promptbuffer; pub use crate::formattedtext::FormattedText; pub use crate::context::Context; pub use crate::errors::DaisyError; pub use crate::evaluate::evaluate; +pub use crate::promptbuffer::PromptBuffer; + cfg_if::cfg_if! { if #[cfg(target_arch = "wasm32")] { use wasm_bindgen::prelude::*; + #[derive(Debug)] + pub struct State { + pub context: Context, + pub promptbuffer: PromptBuffer + } + #[wasm_bindgen] - pub fn dostr(x: String) -> String{ - let mut context = Context::new(); - let x = x.trim().to_string(); - let r = do_string(&mut context, &x); - - match r { - Ok(t) | Err(t) => { - return t.write(); - } - } + pub extern fn daisy_init() -> *mut State { + Box::into_raw(Box::new(State { + context: Context::new(), + promptbuffer: PromptBuffer::new(64) + })) + } + + #[wasm_bindgen] + pub extern fn daisy_free(state: *mut State) { + unsafe { drop(Box::from_raw(state)) }; + } + + #[wasm_bindgen] + pub fn daisy_prompt(state: *mut State) -> String { + let t = unsafe { (*state).promptbuffer.write_prompt(&mut (*state).context) }; + return t.write(); + } + + + #[wasm_bindgen] + pub fn daisy_char(state: *mut State, s: String) -> String { + let mut out = FormattedText::new("".to_string()); + + match &s[..] { + "\r" => { + // Print again without cursor, in case we pressed enter + // while inside a substitution + let t = unsafe { (*state).promptbuffer.write_prompt_nocursor(&mut (*state).context) }; + out += t; + + + let in_str = unsafe { (*state).promptbuffer.enter() }; + out += FormattedText::new("\n".to_string()); + if in_str == "" { + return format!("\r\n{}", daisy_prompt(state)); + } + + if in_str.trim() == "quit" { + return "[quit]".to_string(); + } else { + let r = crate::do_string( unsafe { &mut (*state).context }, &in_str); + + match r { + Ok(t) | Err(t) => { + out += t; + } + } + } + }, + + "\x7F" => { unsafe { (*state).promptbuffer.backspace(); } }, + "\x1B[3~" => { unsafe { (*state).promptbuffer.delete(); } }, + "\x1B[D" => { unsafe { (*state).promptbuffer.cursor_left(); } }, + "\x1B[C" => { unsafe { (*state).promptbuffer.cursor_right(); } }, + "\x1B[A" => { unsafe { (*state).promptbuffer.hist_up(); } }, + "\x1B[B" => { unsafe { (*state).promptbuffer.hist_down(); } }, + + //'\x04' | '\x03' + //=> { break 'outer; }, + + _ => { unsafe { (*state).promptbuffer.add_char(s.chars().next().unwrap()); } }, + }; + + let t = unsafe { (*state).promptbuffer.write_prompt(&mut (*state).context) }; + return (out + t).write(); } } }