| Crates.io | serde_luaq |
| lib.rs | serde_luaq |
| version | 0.1.0 |
| created_at | 2025-09-09 05:49:45.65604+00 |
| updated_at | 2025-09-09 05:49:45.65604+00 |
| description | A Lua %q serialization file format |
| homepage | |
| repository | https://github.com/micolous/serde_luaq |
| max_upload_size | |
| id | 1830307 |
| size | 211,108 |
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 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'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 Serde traits that let you deserialise it:
#[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).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 that is equivalent to the subset of JavaScript that a JSON parser would implement:
niltrue, false)123)
< i64::MIN or > i64::MAX0xFF)
i643.14, 0.314e1)3e14)0x.ABCDEFp+24)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:
+, -, *, /...)<<, >>, &, |, ~...)do ... end, local)if, break, for, goto, repeat, until, while...)#)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)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.
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.