use mlua::{Error, ExternalError, Lua, LuaSerdeExt, Value};
pub fn decode(lua: &Lua, value: Option<String>) -> Result<Value, Error> {
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<dyn Error>> {
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<dyn Error>> {
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<dyn Error>> {
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<dyn Error>> {
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<dyn Error>> {
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::<String>("abc")?, "123");
assert_eq!(result.get::<u32>("def")?, 456);
assert!(result.get::<bool>("ghi")?);
Ok(())
}
}