Skip to main content

zoi_lua/api/
parse.rs

1use mlua::{self, Lua, LuaSerdeExt, Table};
2
3/// Exposes data parsing utilities to the Lua environment.
4///
5/// These helpers allow package scripts to easily consume structured data
6/// commonly found in upstream projects:
7/// - `json`/`yaml`/`toml`: Parsers for structured configuration files.
8/// - `checksumFile`: A specialized parser for standard checksum files (e.g.
9///   `sha256sums`).
10///
11/// These utilities return native Lua tables, allowing for idiomatic
12/// manipulation of complex data within the package script.
13/// Adds data parsing utilities (JSON, YAML, TOML, checksum files) to the
14/// `UTILS.PARSE` table.
15///
16/// # Errors
17///
18/// Returns an error if the `UTILS` table cannot be found or if setting the
19/// `PARSE` table fails.
20pub fn add_parse_util(lua: &Lua) -> Result<(), mlua::Error> {
21    let parse_table = lua.create_table()?;
22
23    let json_fn = lua.create_function(|lua, json_str: String| {
24        let value: serde_json::Value = serde_json::from_str(&json_str)
25            .map_err(|e| mlua::Error::RuntimeError(e.to_string()))?;
26        lua.to_value(&value)
27    })?;
28    parse_table.set("json", json_fn)?;
29
30    let yaml_fn = lua.create_function(|lua, yaml_str: String| {
31        let value: serde_yaml::Value = serde_yaml::from_str(&yaml_str)
32            .map_err(|e| mlua::Error::RuntimeError(e.to_string()))?;
33        lua.to_value(&value)
34    })?;
35    parse_table.set("yaml", yaml_fn)?;
36
37    let toml_fn = lua.create_function(|lua, toml_str: String| {
38        let value: toml::Value = toml::from_str(&toml_str)
39            .map_err(|e| mlua::Error::RuntimeError(e.to_string()))?;
40        lua.to_value(&value)
41    })?;
42    parse_table.set("toml", toml_fn)?;
43
44    let checksum_fn =
45        lua.create_function(|_, (content, file_name): (String, String)| {
46            for line in content.lines() {
47                let parts: Vec<&str> = line.split_whitespace().collect();
48                if parts.len() == 2 && parts.get(1) == Some(&file_name.as_str())
49                {
50                    return Ok(parts.first().map(ToString::to_string));
51                }
52            }
53            Ok(None)
54        })?;
55    parse_table.set("checksumFile", checksum_fn)?;
56
57    let utils_table: Table = lua.globals().get("UTILS")?;
58    utils_table.set("PARSE", parse_table)?;
59
60    Ok(())
61}