mlua-image 0.1.3

Lua bindings and embedding of the Rust based 'image' imaging library.
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(())
    }
}