Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

Rust library to interface with Lua

License

NotificationsYou must be signed in to change notification settings

tomaka/hlua

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

This library is a high-level binding for Lua 5.2. You don't have access to the Lua stack, all you can do is read/write variables (including callbacks) and execute Lua code.

Build Status

How to install it?

Add this to theCargo.toml file of your project

[dependencies]hlua ="0.3"

How to use it?

externcrate hlua;use hlua::Lua;

TheLua struct is the main element of this library. It represents a context in which you can execute Lua code.

letmut lua =Lua::new();// mutable is mandatory

You can check the documentation here.

Reading and writing variables

lua.set("x",2);lua.execute::<()>("x = x + 1").unwrap();let x:i32 = lua.get("x").unwrap();// x is equal to 3

Reading and writing global variables of the Lua context can be done withset andget.Theget function returns anOption<T> and does a copy of the value.

The base types that can be read and written are:i8,i16,i32,u8,u16,u32,f32,f64,bool,String.&str can be written but not read.

If you wish so, you can also add other types by implementing thePush andLuaRead traits.

Executing Lua

let x:u32 = lua.execute("return 6 * 2;").unwrap();// equals 12

Theexecute function takes a&str and returns aResult<T, ExecutionError> whereT: LuaRead.

You can also callexecute_from_reader which takes astd::io::Read as parameter.For example you can easily execute the content of a file like this:

lua.execute_from_reader::<()>(File::open(&Path::new("script.lua")).unwrap())

Writing functions

In order to write a function, you must wrap it aroundhlua::functionX whereX is the number of parameters. This is for the moment a limitation of Rust's inferrence system.

fnadd(a:i32,b:i32) ->i32{    a + b}lua.set("add", hlua::function2(add));lua.execute::<()>("local c = add(2, 4)");// calls the `add` function abovelet c:i32 = lua.get("c").unwrap();// returns 6

In Lua, functions are exactly like regular variables.

You can write regular functions as well as closures:

lua.set("mul", hlua::function2(|a:i32,b:i32| a* b));

Note that the lifetime of the Lua context must be equal to or shorter than the lifetime of closures. This is enforced at compile-time.

letmut a =5i;{letmut lua =Lua::new();    lua.set("inc", || a +=1);// borrows 'a'for iin(0 ..15){        lua.execute::<()>("inc()").unwrap();}}// unborrows `a`assert_eq!(a,20)
Error handling

If your Rust function returns aResult object which contains an error, then a Lua error will be triggered.

Manipulating Lua tables

Manipulating a Lua table can be done by reading aLuaTable object. This can be achieved easily by reading aLuaTable object.

letmut table: hlua::LuaTable<_> = lua.get("a").unwrap();

You can then iterate through the table with the.iter() function. Note that the value returned by the iterator is anOption<(Key, Value)>, theOption being empty when either the key or the value is not convertible to the requested type. Thefilter_map function (provided by the standardIterator trait) is very useful when dealing with this.

for(key, value)in table.iter().filter_map(|e| e){    ...}

You can also retreive and modify individual indices:

let x = table.get("a").unwrap();table.set("b","hello");

Calling Lua functions

You can call Lua functions by reading afunctions_read::LuaFunction.

lua.execute::<()>("    function get_five()        return 5    end");let get_five: hlua::LuaFunction<_> = lua.get("get_five").unwrap();let value:i32 = get_five.call().unwrap();assert_eq!(value,5);

This object holds a mutable reference ofLua, so you can't read or modify anything in the Lua context while theget_five variable exists.It is not possible to store the function for the moment, but it may be in the future.

Reading and writing Rust containers

(note: not yet possible to read all containers, see below)

It is possible to read and write whole Rust containers at once:

lua.set("a",[12,13,14,15]);let hashmap:HashMap<i32,f64> =[1.,2.,3.].into_iter().enumerate().map(|(k, v)|(kasi32,*vasf64)).collect();lua.set("v", hashmap);

If the container has single elements, then the indices will be numerical. For example in the code above, the12 will be at index1, the13 at index2, etc.

If the container has tuples of two elements, then the first one will be considered as the key and the second one as the value.

This can be useful to create APIs:

fnfoo(){}fnbar(){}lua.set("mylib",[("foo", hlua::function0(foo)),("bar", hlua::function0(bar))]);lua.execute::<()>("mylib.foo()");

It is possible to read aVec<AnyLuaValue>:

letmut lua =Lua::new();        lua.execute::<()>(r#"v = { 1, 2, 3 }"#).unwrap();let read:Vec<_> = lua.get("v").unwrap();assert_eq!(            read,[1.,2.,3.].iter().map(|x|AnyLuaValue::LuaNumber(*x)).collect::<Vec<_>>());

In case table represents sparse array, has non-numeric keys, orindices not starting at 1,.get() will returnNone, as Rust'sVec doesn't support these features.

It is possible to read aHashMap<AnyHashableLuaValue, AnyLuaValue>:

letmut lua =Lua::new();lua.execute::<()>(r#"v = { [-1] = -1, ["foo"] = 2, [2.] = 42 }"#).unwrap();let read:HashMap<_,_> = lua.get("v").unwrap();assert_eq!(read[&AnyHashableLuaValue::LuaNumber(-1)],AnyLuaValue::LuaNumber(-1.));assert_eq!(read[&AnyHashableLuaValue::LuaString("foo".to_owned())],AnyLuaValue::LuaNumber(2.));assert_eq!(read[&AnyHashableLuaValue::LuaNumber(2)],AnyLuaValue::LuaNumber(42.));assert_eq!(read.len(),3);

User data

(note: the API here is very unstable for the moment)

When you expose functions to Lua, you may wish to read or write more elaborate objects. This is called auser data.

To do so, you should implement thePush,CopyRead andConsumeRead for your types.This is usually done by redirecting the call touserdata::push_userdata.

structFoo;impl<L> hlua::Push<L>forFoowhereL: hlua::AsMutLua<'lua>{fnpush_to_lua(self,lua:L) -> hlua::PushGuard<L>{        lua::userdata::push_userdata(self, lua,            |mut metatable|{// you can define all the member functions of Foo here// see the official Lua documentation for metatables                metatable.set("__call", hlua::function0(||println!("hello from foo")))})}}fnmain(){letmut lua = lua::Lua::new();    lua.set("foo",Foo);    lua.execute::<()>("foo()");// prints "hello from foo"}

Contributing

Contributions are welcome!

About

Rust library to interface with Lua

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

[8]ページ先頭

©2009-2025 Movatter.jp