69 lines
2.3 KiB
Rust
69 lines
2.3 KiB
Rust
use anyhow::Error;
|
|
use piccolo::{Callback, Closure, Context, Executor, IntoValue, Lua, StashedExecutor, Table};
|
|
|
|
use crate::{echo_to_term_frame, GlobalCell, TermFrame};
|
|
use std::str;
|
|
|
|
pub struct LuaState {
|
|
pub interp: Lua,
|
|
pub exec: StashedExecutor,
|
|
}
|
|
|
|
impl LuaState {
|
|
pub fn setup() -> Result<LuaState, String> {
|
|
let mut interp = Lua::core();
|
|
let exec: StashedExecutor =
|
|
interp.enter(|ctx| Ok::<StashedExecutor, String>(ctx.stash(Executor::new(ctx))))?;
|
|
|
|
Ok(LuaState { interp, exec })
|
|
}
|
|
|
|
pub fn execute(&mut self, command: &str) -> Result<String, String> {
|
|
self.interp
|
|
.try_enter(|ctx| {
|
|
let closure = Closure::load(ctx, None, format!("return ({})", command).as_bytes())
|
|
.or_else(|_| Closure::load(ctx, None, command.as_bytes()))?;
|
|
ctx.fetch(&self.exec).restart(ctx, closure.into(), ());
|
|
Ok(())
|
|
})
|
|
.map_err(|err| format!("{}", err))?;
|
|
Ok("Blah".to_owned())
|
|
}
|
|
}
|
|
|
|
pub fn install_lua_globals(global: &GlobalCell) -> Result<(), String> {
|
|
global
|
|
.lua_engine
|
|
.borrow_mut()
|
|
.interp
|
|
.try_enter(|ctx| {
|
|
let cmd_table = Table::new(&ctx);
|
|
cmd_table
|
|
.set(
|
|
ctx,
|
|
ctx.intern_static(b"echo_frame"),
|
|
echo_frame(ctx, global.clone()),
|
|
)
|
|
.map_err(|_| Error::msg("Can't add command"))?;
|
|
ctx.set_global(ctx.intern_static(b"commands").into_value(ctx), cmd_table)
|
|
.map(|_| ())
|
|
.map_err(|_| Error::msg("Can't set commands key"))?;
|
|
Ok(())
|
|
})
|
|
.map_err(|e| e.to_string())?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn echo_frame(ctx: Context, global: GlobalCell) -> Callback {
|
|
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
|
|
let frame_no: u64 = stack.consume(ctx)?;
|
|
let message: piccolo::String = stack.consume(ctx)?;
|
|
let message_str = str::from_utf8(message.as_bytes())
|
|
.map_err(|_| "Expected message to echo to be UTF-8.".into_value(ctx))?;
|
|
echo_to_term_frame(&global, &TermFrame(frame_no), message_str)
|
|
.map_err(|m| m.into_value(ctx))?;
|
|
Ok(piccolo::CallbackReturn::Return)
|
|
})
|
|
}
|