use rlua::prelude::*;use std::{ mem, io::{Cursor, SeekFrom, prelude::*}};use serde_json;use rlua_serde;//TODO: Move to having a common interface so IO can share the same bindingpub struct LuaMemory(Cursor<Vec<u8>>);impl LuaUserData for LuaMemory { fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { methods.add_method_mut("read", |_, this: &mut LuaMemory, len: Option<usize>|{ let bytes = match len { Some(len) => { let mut bytes = vec![0u8; len]; this.0.read(&mut bytes).map_err(LuaError::external)?; bytes }, None => { let mut bytes = vec![]; this.0.read_to_end(&mut bytes).map_err(LuaError::external)?; bytes } }; Ok(bytes) }); methods.add_method_mut("read_to_string", |_, this: &mut LuaMemory, _: ()|{ let mut data = String::new(); this.0.read_to_string(&mut data).map_err(LuaError::external)?; Ok(data) }); methods.add_method_mut("write", |_, this: &mut LuaMemory, bytes: Vec<u8>|{ Ok(this.0.write(bytes.as_slice()).map_err(LuaError::external)?) }); methods.add_method_mut("write", |_, this: &mut LuaMemory, str: String|{ Ok(this.0.write(str.as_bytes()).map_err(LuaError::external)?) }); methods.add_method_mut("flush", |_, this: &mut LuaMemory, _: ()|{ Ok(this.0.flush().map_err(LuaError::external)?) }); methods.add_method_mut("clear", |_, this: &mut LuaMemory, _: ()|{ mem::replace(&mut this.0, Cursor::new(Vec::new())); Ok(()) }); methods.add_method_mut("seek", |_, this: &mut LuaMemory, (pos, size): (Option<String>, Option<usize>)| { let size = size.unwrap_or(0); let seekfrom = pos.and_then(|s_pos| { Some(match s_pos.as_ref() { "start" => SeekFrom::Start(size as u64), "end" => SeekFrom::End(size as i64), "current" | _ => SeekFrom::Current(size as i64), }) }).unwrap_or(SeekFrom::Current(size as i64)); Ok(this.0.seek(seekfrom).map_err(LuaError::external)?) }); methods.add_method_mut("dump", |_, this: &mut LuaMemory, _: ()|{ Ok(this.0.clone().into_inner()) }); }}pub fn init(lua: &Lua) -> crate::Result<()> { let module = lua.create_table()?; module.set("new", lua.create_function( |_, _: ()| { Ok(LuaMemory(Cursor::new(Vec::new()))) })? )?; lua.globals().set("memory", module)?; Ok(())}