mod transfer;
#[cfg(test)]
pub mod integration_tests;
use mlua::prelude::LuaError;
use mlua::{Error, IntoLua, Lua, MultiValue, Number, Table, UserData, UserDataFields, UserDataMethods, Value};
#[repr(u16)]
#[derive(Copy, Clone)]
enum Const {
Ten = 0x0010,
Rd = 0x0001,
Stop = 0x8000,
Nostart = 0x4000,
RevDirAddr = 0x2000,
IgnoreNak = 0x1000,
NoRdAck = 0x0800,
RecvLen = 0x0400,
}
impl IntoLua for Const {
fn into_lua(self, _lua: &Lua) -> Result<Value, LuaError> {
Ok(Value::Number(Number::from(self as u16)))
}
}
#[derive(Clone)]
struct I2c {
#[allow(dead_code)]
device: String,
}
impl UserData for I2c {
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
methods.add_method("close", |_, _i2c, ()| Ok(()));
methods.add_method("transfer", transfer::handle);
}
fn add_fields<F: UserDataFields<Self>>(_fields: &mut F) {
}
}
pub fn preload(lua: &Lua) -> Result<(), Error> {
let module = lua.create_table()?;
module.raw_set("I2C_M_TEN", Const::Ten)?;
module.raw_set("I2C_M_RD", Const::Rd)?;
module.raw_set("I2C_M_STOP", Const::Stop)?;
module.raw_set("I2C_M_NOSTART", Const::Nostart)?;
module.raw_set("I2C_M_REV_DIR_ADDR", Const::RevDirAddr)?;
module.raw_set("I2C_M_IGNORE_NAK", Const::IgnoreNak)?;
module.raw_set("I2C_M_NO_RD_ACK", Const::NoRdAck)?;
module.raw_set("I2C_M_RECV_LEN", Const::RecvLen)?;
let metatable = lua.create_table()?;
metatable.set(
"__call",
lua.create_function(|_, args: MultiValue| {
let device = args[1].to_string()?;
Ok(I2c { device })
})?,
)?;
module.set_metatable(Some(metatable))?;
let globals = lua.globals();
let package: Table = globals.get("package")?;
let loaded: Table = package.get("loaded")?;
loaded.set("periphery.I2C", module)?;
Ok(())
}
#[cfg(test)]
mod tests {
use mlua::Lua;
use std::error::Error;
#[test]
fn preload() -> Result<(), Box<dyn Error>> {
let lua = Lua::new();
super::preload(&lua)?;
lua.load("local I2C = require('periphery.I2C')").exec()?;
Ok(())
}
}