use mlua::{Error, ExternalError, Lua, LuaSerdeExt, Value}; pub fn decode(lua: &Lua, value: Option) -> Result { match value { None => Ok(mlua::Nil), Some(value) => { let value: serde_json::Value = serde_json::from_str(&value).map_err(|e| e.into_lua_err())?; Ok(lua.to_value(&value).map_err(|e| e.into_lua_err())?) } } } #[cfg(test)] mod tests { use mlua::{Lua, Table}; use std::error::Error; #[test] fn can_decode_a_boolean() -> Result<(), Box> { let lua = Lua::new(); crate::preload(&lua)?; let result: bool = lua .load( r#" local json = require('json') return json.decode('true') "#, ) .eval()?; assert_eq!(result, true); Ok(()) } #[test] fn can_decode_a_nil() -> Result<(), Box> { let lua = Lua::new(); crate::preload(&lua)?; let result: mlua::Value = lua .load( r#" local json = require('json') return json.decode(nil) "#, ) .eval()?; assert!(result.is_nil()); Ok(()) } #[test] fn can_decode_a_number() -> Result<(), Box> { let lua = Lua::new(); crate::preload(&lua)?; let result: u32 = lua .load( r#" local json = require('json') return json.decode('123') "#, ) .eval()?; assert_eq!(result, 123); Ok(()) } #[test] fn can_decode_a_string() -> Result<(), Box> { let lua = Lua::new(); crate::preload(&lua)?; let result: String = lua .load( r#" local json = require('json') return json.decode('"abc"') "#, ) .eval()?; assert_eq!(result, "abc"); Ok(()) } #[test] fn can_decode_a_table() -> Result<(), Box> { let lua = Lua::new(); crate::preload(&lua)?; let result: Table = lua .load( r#" local json = require('json') return json.decode('{"abc":"123","def":456,"ghi":true,"jkl":[7,8,9]}') "#, ) .eval()?; assert_eq!(result.get::("abc")?, "123"); assert_eq!(result.get::("def")?, 456); assert!(result.get::("ghi")?); Ok(()) } }