use mlua::{MultiValue, UserData, UserDataMethods};
pub struct Pixel {
pub delegate: image::Rgba<u8>,
}
impl UserData for Pixel {
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
methods.add_meta_method("__index", |_lua, this, index: usize| {
let value: u8 = this.delegate[index - 1];
Ok(value)
});
methods.add_method("eq", |_lua, this, args: MultiValue| {
let other: Pixel = args[0].as_userdata().unwrap().take()?;
let equal = this.delegate.eq(&other.delegate);
Ok(equal)
});
methods.add_meta_method("__tostring", |_lua, this, ()| Ok(format!("{:?}", this.delegate)));
}
}
#[cfg(test)]
mod tests {
use mlua::Lua;
use std::error::Error;
#[test]
fn eq() -> Result<(), Box<dyn Error>> {
let lua = Lua::new();
crate::preload(&lua)?;
let script = r#"
local image = require('image')
local img = image.open('testdata/fractal.png')
local pixel_10_10 = img:get_pixel(10, 10)
assert(pixel_10_10:eq(img:get_pixel(10, 10)))
local pixel_20_20 = img:get_pixel(20, 20)
assert(pixel_10_10:eq(pixel_20_20) == false)
"#;
lua.load(script).exec()?;
Ok(())
}
#[test]
fn index() -> Result<(), Box<dyn Error>> {
let lua = Lua::new();
crate::preload(&lua)?;
let script = r#"
local image = require('image')
local img = image.open('testdata/fractal.png')
local pixel = img:get_pixel(10, 10)
return pixel[1], pixel[2], pixel[3], pixel[4]
"#;
let (p1, p2, p3, p4): (u8, u8, u8, u8) = lua.load(script).eval()?;
assert_eq!(p1, 2);
assert_eq!(p2, 0);
assert_eq!(p3, 2);
assert_eq!(p4, 255);
Ok(())
}
}