mlua-json 1.0.1

A Rust-native implementation of LuaRocks openresty/lua-cjson or grafi/lunajson for mlua.
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(())
    }
}