[][src]Crate rudeboy

rudeboy - Rlua User Data Extension library

Provides attribute macros which allow for easily generating metamethod implementations, exporting methods, and exporting rust structs and enums to lua with the use of the rlua crate.

Generating metamethods

To generate metamethods for a struct or enum, use the metamethods attribute on the type's definition, along with a list of parameters indicating the metamethods to generate implementations for. With the exception of the Index metamethod, which can only be generated for structs with named fields and which parses the struct definition, every generated metamethod expects and uses the corresponding rust trait to provide implementation details. See the metamethods attribute documentation for the full list of supported metamethods and the rust traits each one uses.

Examples

use rudeboy::{metamethods, user_data};

#[metamethods(Add, Eq, Index)]
#[user_data(MetaMethods)]
#[derive(PartialEq, Copy, Clone)]
struct Test {
    x: i32,
}

impl std::ops::Add for Test {
    type Output = Self;
    fn add(self, other: Self) -> Self {
        Test { x: self.x + other.x }
    }
}

let lua = rlua::Lua::new();
lua.context(|ctx| {
    let globals = ctx.globals();
    globals.set("one", Test { x: 1 })?;
    globals.set("two", Test { x: 2 })?;
    ctx.load("sum = one + one").exec()?;
    assert!(ctx.load("sum == two").eval::<bool>()?);
    assert_eq!(ctx.load("sum.x").eval::<i32>()?, 2);

    Ok(())
})?;

Exporting methods

To export methods for a struct or enum, use the methods attribute on the impl block for the corresponding type, containing the methods that you wish to export to lua. Currently, there is no way to ignore a method other than placing it in a separate impl block without the methods attribute.

Examples

use rudeboy::{methods, user_data};

#[user_data(Methods)]
#[derive(PartialEq, Debug, Clone)]
enum Sign {
    Minus,
    Plus,
}

#[methods]
impl Sign {
    // This method will be exposed to lua...
    pub fn flip(&self) -> Self {
        match self {
            Sign::Minus => Sign::Plus,
            Sign::Plus => Sign::Minus,
        }
    }
}

 
impl Sign {
    // ... but this method won't
    pub fn apply(&self, x: i32) -> i32 {
        match self {
            Sign::Minus => -x,
            Sign::Plus => x,
        }
    }
}

let lua = rlua::Lua::new();
lua.context(|ctx| {
    let globals = ctx.globals();
    globals.set("plus", Sign::Plus)?;
    globals.set("minus", Sign::Minus)?;

    assert_eq!(ctx.load("plus:flip()").eval::<Sign>()?, Sign::Minus);
    assert_eq!(ctx.load("minus:flip()").eval::<Sign>()?, Sign::Plus);
    assert_eq!(ctx.load("minus:flip():flip()").eval::<Sign>()?, Sign::Minus);

    Ok(())
})?;

Generating rlua::UserData implementation

To export a struct or enum for use with rlua, use the user_data attribute on the type definition or an associated impl block. When given no parameters, an empty UserData implementation is generated that provides no metamethods or methods for use in lua. If given the MetaMethods parameter, the metamethods generated by metamethods will be exported, and if given the Methods parameter, the methods generated by methods will be exported. Note that this attribute will prevent the user from adding any additional methods to the exported type beyond what can be generated with the methods and metamethods attributes. If you wish to export additional methods, write your own implementation of rlua::UserData and call the appropriate methods from the RudeboyMethods and RudeboyMetaMethods traits.

Examples

use rudeboy::{metamethods, methods, user_data};

// Tagging a type with user_data with no parameters means it can be passed
// in and out of lua, but no metamethods or methods will be available
#[user_data]
#[derive(Clone)]
enum Amount {
    Single,
    Double,
}

#[user_data(Methods)]
#[derive(Clone, PartialEq)]
struct Test {
    x: f64,
}

#[methods]
impl Test {
    pub fn get(&self, amount: Amount) -> f64 {
        match amount {
            Amount::Single => self.x,
            Amount::Double => self.x * 2.0,
        }
    }
}

let lua = rlua::Lua::new();
lua.context(|ctx| {
    let globals = ctx.globals();
    globals.set("single", Amount::Single)?;
    globals.set("double", Amount::Double)?;
    globals.set("test", Test { x: 5.0 })?;

    assert_eq!(ctx.load("test:get(single)").eval::<f64>()?, 5.0);
    assert_eq!(ctx.load("test:get(double)").eval::<f64>()?, 10.0);

    Ok(())
})?;

Traits

RudeboyMetaMethods

Provides methods for registering each supported metamethod. The generate_metamethods method will call all of them. Generated by the metamethods attribute macro.

RudeboyMethods

Used to expose, to rlua, rust methods for a UserData struct

Attribute Macros

metamethods

Placed on a struct or enum definition; generates an impl of RudeboyMetamethods to add the specified metamethods to the exported user data.

methods

Placed on an inherent impl block; generates an impl of RudeboyMethods to add the contained methods to the exported user data. Takes no parameters.

user_data

Generates an implementation of rlua::UserData for the tagged type definition or the type that matches a tagged impl block.