| Crates.io | serde_luaq |
| lib.rs | serde_luaq |
| version | 0.2.1 |
| created_at | 2025-09-09 05:49:45.65604+00 |
| updated_at | 2025-12-30 08:16:10.19178+00 |
| description | A Lua %q serialization file format |
| homepage | |
| repository | https://github.com/micolous/serde_luaq |
| max_upload_size | |
| id | 1830307 |
| size | 327,957 |
serde_luaq [!NOTE] This library is still a work in progress, and there are no API stability guarantees.
serde_luaq is a library for deserialising (and eventually, serialising) simple, JSON-equivalent
data structures from Lua 5.4 source code, without requiring Lua itself (unlike mlua).
The goal is to be able to read state from software (mostly games) which is serialised using
Lua %q formatting (and similar techniques) without requiring arbitrary code execution.
This library consists of four parts:
A LuaValue enum, which describes Lua 5.4's basic data types (nil, boolean,
string, number, table).
A peg-based parser for parsing a &[u8] (containing Lua) into a LuaValue.
A Serde-based Deserialize implementation for converting a LuaValue into your own
data types.
Optional lossy converter to and from serde_json's Value type.
For example, you could have a Lua script like this:
a = 1
b = {1, 2, 3}
c = {
["foo"] = "bar",
}
And define some a schema using Serde traits:
#[derive(Deserialize, PartialEq, Debug)]
struct ComplexType {
foo: String,
}
#[derive(Deserialize, PartialEq, Debug)]
struct Test {
a: u32,
b: Vec<u32>,
c: ComplexType,
}
Then deserialise it with:
use serde_luaq::{from_slice, LuaFormat};
let parsed: Test = serde_luaq::from_slice(
input,
LuaFormat::Script,
/* maximum table depth */ 16,
).unwrap();
assert_eq!(parsed, Test {
a: true,
b: vec![1, 2, 3],
c: ComplexType { foo: "bar".to_string() },
});
{["hello"] = "world"})return {["hello"] = "world"})hello = "world")serde_json interoperability
LuaValue -> serde_json::Valueserde_json::Value -> LuaValueThis library aims to implement a subset of Lua 5.4 that is equivalent to the subset of JavaScript that a JSON parser would implement:
niltrue, false)i64 only)
123)
< i64::MIN or > i64::MAX (Lua 5.4)0xFF)
i64f64 only)
3.14, 0.314e1)3e14)0x.ABCDEFp+24) (not supported on WASM before v0.2.1)1e9999, -1e9999)(0/0))')")[[string]], [==[string]==]) (up to 5 = deep)[u8])abfnrtv\"')\\\n, \\\r, \\\r\n, \\\n\r)\z whitespace span escapes (str\z ing == string)\1, \01, \001)\x01)\u{1F4A9})
\u{D800}, \u{7FFFFFFF}){["foo"] = "bar"}, {[1234]="bar"}){foo = "bar"})
{"bar"})This library is not designed to replace Lua, nor execute arbitrary Lua code, so these Lua features are intentionally unsupported:
+, -, *, /...)<<, >>, &, |, ~...)if, break, do, end, for, goto, repeat, until, while...)#)3,14159)and, or, not)\r\n => \n on UNIX, \n => \r\n on Windows)(0/0) (NaN)a = 10; b = a)==, ~=, <, >...)"hello" .. " world")a = {}; a.b = 'foo')a, b = 1, 2)local <const> a = 10)If you want to use these language features or otherwise need to run arbitrary Lua code, look at
something like mlua, which links to liblua, and also provides serde bindings.
Programming in Lua has a function that dumps a Lua table into a file as a script.
SaveData: Love2D library, emits a return statement which is loaded by evaluating the string.
Balatro (engine/string_packer.lua) is a modified version of SaveData that also compresses
with deflate for save games and settings (.jkr files).
World of Warcraft: addon state, written to WTF/{Account,SavedVariables}/**/*.lua as scripts that
set variables.
This project is dual-licensed under the terms of the Apache-2.0 and MIT licenses.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this project by you, as defined in the Apache-2.0 license, shall be dual licensed under the terms of the Apache-2.0 and MIT licenses, without any additional terms or conditions.
serde_luaq does not include any copy of Lua itself. To ensure maximal compatibility with Lua's
syntax, some of its test cases are derived from Lua's test suite.