rsjson-lua 0.4.1

a json lua module using the serde-json rust crate
Documentation
// SPDX-License-Identifier: MIT

use serde::Serialize;
use serde_json::ser::{PrettyFormatter, Serializer};

use crate::config::EncodeConfig;

/// Serialize an `mlua::Value` to a JSON string.
pub(crate) fn encode(
    lua: &mlua::Lua,
    value: &mlua::Value,
    config: Option<EncodeConfig>,
) -> mlua::Result<mlua::String> {
    let mut writer: Vec<u8> = Vec::new();

    match config {
        Some(config) => {
            let obj = value
                .to_serializable()
                .sort_keys(config.sort_keys)
                .encode_empty_tables_as_array(config.empty_table_as_array)
                .detect_mixed_tables(config.detect_mixed_tables)
                .deny_unsupported_types(config.error_unsupported)
                .deny_recursive_tables(config.error_cycles);

            match config.indent {
                Some(n) => {
                    let prefix = config.prefix.repeat(n);
                    let formatter = PrettyFormatter::with_indent(prefix.as_bytes());
                    let mut ser = Serializer::with_formatter(&mut writer, formatter);
                    obj.serialize(&mut ser).map_err(mlua::Error::external)?;
                },
                _ => {
                    let mut ser = Serializer::new(&mut writer);
                    obj.serialize(&mut ser).map_err(mlua::Error::external)?;
                },
            }
        },
        None => {
            let mut ser = Serializer::new(&mut writer);
            value
                .to_serializable()
                .serialize(&mut ser)
                .map_err(mlua::Error::external)?;
        },
    };

    lua.create_string(writer)
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn it_str_to_json() {
        let lua = mlua::Lua::new();

        let te = lua.create_string("one two three").unwrap();
        let res = encode(&lua, &mlua::Value::String(te), None).unwrap();

        assert_eq!(res, r#""one two three""#);
    }

    #[test]
    fn it_int_to_json() {
        let lua = mlua::Lua::new();

        let res = encode(&lua, &mlua::Value::Integer(99), None).unwrap();

        assert_eq!(res, "99");
    }

    #[test]
    fn it_float_to_json() {
        let lua = mlua::Lua::new();

        let res = encode(&lua, &mlua::Value::Number(9.9), None).unwrap();

        assert_eq!(res, "9.9");
    }

    #[test]
    fn it_bool_to_json() {
        let lua = mlua::Lua::new();

        let res = encode(&lua, &mlua::Value::Boolean(true), None).unwrap();

        assert_eq!(res, "true");

        let res = encode(&lua, &mlua::Value::Boolean(false), None).unwrap();

        assert_eq!(res, "false");
    }

    #[test]
    fn it_nil_to_json() {
        let lua = mlua::Lua::new();

        let res = encode(&lua, &mlua::Value::Nil, None).unwrap();

        assert_eq!(res, "null");
    }

    #[test]
    fn it_array_to_json() {
        let lua = mlua::Lua::new();

        let te = lua.create_sequence_from(vec![1, 2, 3]).unwrap();
        let res = encode(&lua, &mlua::Value::Table(te), None).unwrap();

        assert_eq!(res, "[1,2,3]");
    }

    #[test]
    fn it_table_to_json() {
        let lua = mlua::Lua::new();

        let mut config = EncodeConfig::new();
        config.sort_keys = true;

        let te = lua.create_table().unwrap();
        te.set("a", 1).unwrap();
        te.set("b", 2).unwrap();
        te.set("c", 3).unwrap();

        let res = encode(&lua, &mlua::Value::Table(te), Some(config)).unwrap();

        assert_eq!(res, r#"{"a":1,"b":2,"c":3}"#);
    }
}