retex-lua 1.0.0

Embedded Lua and the LuaTeX Lua API for retex
Documentation
//! The `sio` and `fio` libraries (binary readers on strings and files).

use mlua::{Lua, Table};

const SIO_LUA: &str = include_str!("sio.lua");

/// Installs the globals `sio` and `fio`.
pub fn install(lua: &Lua) -> mlua::Result<()> {
    let (sio, fio): (Table, Table) = lua.load(SIO_LUA).set_name("=sio").call(())?;
    lua.globals().set("sio", sio)?;
    lua.globals().set("fio", fio)?;
    Ok(())
}

#[cfg(test)]
mod tests {
    use mlua::Lua;

    fn eval(code: &str) -> String {
        let lua = Lua::new();
        super::install(&lua).unwrap();
        lua.load(code).eval::<String>().unwrap()
    }

    // Expected values observed with texlua (LuaTeX 1.22).
    #[test]
    fn string_readers() {
        let r = eval(
            r##"local s="\1\2\3\4\255\254\253\252abc\ndef"
            return table.concat({sio.readcardinal1(s,1), sio.readcardinal2(s,1),
              sio.readcardinal3(s,1), sio.readcardinal4(s,1), sio.readinteger1(s,5),
              sio.readinteger2(s,5), sio.readinteger3(s,5), sio.readinteger4(s,5),
              sio.readcardinal2le(s,1), sio.readinteger2le(s,5), sio.readcardinal4le(s,1),
              sio.readcardinal3le(s,1), sio.readinteger3le(s,5), sio.readinteger4le(s,5)}, ",")"##,
        );
        assert_eq!(
            r,
            "1,258,66051,16909060,-1,-2,-259,-66052,513,-257,67305985,197121,-131329,-50462977"
        );
    }

    #[test]
    fn fixed_and_tables() {
        let r = eval(
            r##"local s="\1\2\3\4\255\254\253\252abc\ndef"
            return table.concat({sio.readfixed2(s,1), sio.readfixed4(s,1), sio.read2dot14(s,1),
              sio.readfixed2(s,5), sio.readfixed4(s,5), sio.read2dot14(s,5),
              table.concat(sio.readbytetable(s,1,4),"/"), table.concat(sio.readcardinaltable(s,1,2,2),"/"),
              table.concat(sio.readintegertable(s,5,2,1),"/"), #sio.readbytetable(s,14,4),
              table.concat(sio.readcardinaltable(s,13,2,2),"/"), select("#", sio.readbytes(s,14,4)),
              tostring(sio.readcardinal1(s,100)), tostring(sio.readcardinal1(s,0))}, ",")"##,
        );
        assert_eq!(
            r,
            "1.0078125,258.01177978516,0.0157470703125,255.9921875,-1.0078735351562,\
             -0.0001220703125,1/2/3/4,258/772,-1/-2,2,25701,2,nil,nil"
        );
    }

    #[test]
    fn argument_errors() {
        let r = eval(
            r##"local _, a = pcall(sio.readcardinal1, "x")
            local _, b = pcall(sio.readcardinal1)
            return a .. "|" .. b"##,
        );
        assert_eq!(
            r,
            "bad argument #2 to 'sio.readcardinal1' (number expected, got no value)|\
             bad argument #1 to 'sio.readcardinal1' (string expected, got no value)"
        );
    }
}