{"id":13437884,"url":"https://github.com/tomaka/hlua","last_synced_at":"2025-12-12T14:47:23.146Z","repository":{"id":57635208,"uuid":"20517144","full_name":"tomaka/hlua","owner":"tomaka","description":"Rust library to interface with Lua","archived":false,"fork":false,"pushed_at":"2024-07-27T14:20:29.000Z","size":2701,"stargazers_count":509,"open_issues_count":50,"forks_count":48,"subscribers_count":17,"default_branch":"master","last_synced_at":"2025-05-07T16:48:36.220Z","etag":null,"topics":["lua","rust"],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tomaka.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-06-05T08:13:54.000Z","updated_at":"2025-05-03T09:48:34.000Z","dependencies_parsed_at":"2024-06-18T17:56:08.706Z","dependency_job_id":"36efb3da-cc52-4cc1-8649-f5ad62b36a5f","html_url":"https://github.com/tomaka/hlua","commit_stats":{"total_commits":402,"total_committers":21,"mean_commits":"19.142857142857142","dds":0.1915422885572139,"last_synced_commit":"d587cedafea2ebbc003c9c5ff9c521c8836c3af6"},"previous_names":["tomaka/rust-hl-lua"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomaka%2Fhlua","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomaka%2Fhlua/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomaka%2Fhlua/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomaka%2Fhlua/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tomaka","download_url":"https://codeload.github.com/tomaka/hlua/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254346624,"owners_count":22055808,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["lua","rust"],"created_at":"2024-07-31T03:01:00.964Z","updated_at":"2025-12-12T14:47:18.111Z","avatar_url":"https://github.com/tomaka.png","language":"C","readme":"## hlua\n\nThis 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.\n\n[![Build Status](https://travis-ci.org/tomaka/hlua.svg?branch=master)](https://travis-ci.org/tomaka/hlua)\n\n### How to install it?\n\nAdd this to the `Cargo.toml` file of your project\n\n```toml\n[dependencies]\nhlua = \"0.3\"\n```\n\n### How to use it?\n\n```rust\nextern crate hlua;\nuse hlua::Lua;\n```\n\nThe `Lua` struct is the main element of this library. It represents a context in which you can execute Lua code.\n\n```rust\nlet mut lua = Lua::new();     // mutable is mandatory\n```\n\n**[You can check the documentation here](http://docs.rs/hlua)**.\n\n#### Reading and writing variables\n\n```rust\nlua.set(\"x\", 2);\nlua.execute::\u003c()\u003e(\"x = x + 1\").unwrap();\nlet x: i32 = lua.get(\"x\").unwrap();  // x is equal to 3\n```\n\nReading and writing global variables of the Lua context can be done with `set` and `get`.\nThe `get` function returns an `Option\u003cT\u003e` and does a copy of the value.\n\nThe base types that can be read and written are: `i8`, `i16`, `i32`, `u8`, `u16`, `u32`, `f32`, `f64`, `bool`, `String`. `\u0026str` can be written but not read.\n\nIf you wish so, you can also add other types by implementing the `Push` and `LuaRead` traits.\n\n#### Executing Lua\n\n```rust\nlet x: u32 = lua.execute(\"return 6 * 2;\").unwrap();    // equals 12\n```\n\nThe `execute` function takes a `\u0026str` and returns a `Result\u003cT, ExecutionError\u003e` where `T: LuaRead`.\n\nYou can also call `execute_from_reader` which takes a `std::io::Read` as parameter.\nFor example you can easily execute the content of a file like this:\n\n```rust\nlua.execute_from_reader::\u003c()\u003e(File::open(\u0026Path::new(\"script.lua\")).unwrap())\n```\n\n#### Writing functions\n\nIn order to write a function, you must wrap it around `hlua::functionX` where `X` is the number of parameters. This is for the moment a limitation of Rust's inferrence system.\n\n```rust\nfn add(a: i32, b: i32) -\u003e i32 {\n    a + b\n}\n\nlua.set(\"add\", hlua::function2(add));\nlua.execute::\u003c()\u003e(\"local c = add(2, 4)\");   // calls the `add` function above\nlet c: i32 = lua.get(\"c\").unwrap();   // returns 6\n```\n\nIn Lua, functions are exactly like regular variables.\n\nYou can write regular functions as well as closures:\n\n```rust\nlua.set(\"mul\", hlua::function2(|a: i32, b: i32| a * b));\n```\n\nNote that the lifetime of the Lua context must be equal to or shorter than the lifetime of closures. This is enforced at compile-time.\n\n```rust\nlet mut a = 5i;\n\n{\n    let mut lua = Lua::new();\n\n    lua.set(\"inc\", || a += 1);    // borrows 'a'\n    for i in (0 .. 15) {\n        lua.execute::\u003c()\u003e(\"inc()\").unwrap();\n    }\n} // unborrows `a`\n\nassert_eq!(a, 20)\n```\n\n##### Error handling\n\nIf your Rust function returns a `Result` object which contains an error, then a Lua error will be triggered.\n\n#### Manipulating Lua tables\n\nManipulating a Lua table can be done by reading a `LuaTable` object. This can be achieved easily by reading a `LuaTable` object.\n\n```rust\nlet mut table: hlua::LuaTable\u003c_\u003e = lua.get(\"a\").unwrap();\n```\n\nYou can then iterate through the table with the `.iter()` function. Note that the value returned by the iterator is an `Option\u003c(Key, Value)\u003e`, the `Option` being empty when either the key or the value is not convertible to the requested type. The `filter_map` function (provided by the standard `Iterator` trait) is very useful when dealing with this.\n\n```rust\nfor (key, value) in table.iter().filter_map(|e| e) {\n    ...\n}\n```\n\nYou can also retreive and modify individual indices:\n\n```rust\nlet x = table.get(\"a\").unwrap();\ntable.set(\"b\", \"hello\");\n```\n\n#### Calling Lua functions\n\nYou can call Lua functions by reading a `functions_read::LuaFunction`.\n\n```rust\nlua.execute::\u003c()\u003e(\"\n    function get_five() \n        return 5\n    end\");\n\nlet get_five: hlua::LuaFunction\u003c_\u003e = lua.get(\"get_five\").unwrap();\nlet value: i32 = get_five.call().unwrap();\nassert_eq!(value, 5);\n```\n\nThis object holds a mutable reference of `Lua`, so you can't read or modify anything in the Lua context while the `get_five` variable exists.\nIt is not possible to store the function for the moment, but it may be in the future.\n\n#### Reading and writing Rust containers\n\n*(note: not yet possible to read all containers, see below)*\n\nIt is possible to read and write whole Rust containers at once:\n\n```rust\nlua.set(\"a\", [ 12, 13, 14, 15 ]);\nlet hashmap: HashMap\u003ci32, f64\u003e = [1., 2., 3.].into_iter().enumerate().map(|(k, v)| (k as i32, *v as f64)).collect();\nlua.set(\"v\", hashmap);\n```\n\nIf the container has single elements, then the indices will be numerical. For example in the code above, the `12` will be at index `1`, the `13` at index `2`, etc.\n\nIf the container has tuples of two elements, then the first one will be considered as the key and the second one as the value.\n\nThis can be useful to create APIs:\n\n```rust\nfn foo() { }\nfn bar() { }\n\nlua.set(\"mylib\", [\n    (\"foo\", hlua::function0(foo)),\n    (\"bar\", hlua::function0(bar))\n]);\n\nlua.execute::\u003c()\u003e(\"mylib.foo()\");\n```\n\nIt is possible to read a `Vec\u003cAnyLuaValue\u003e`:\n\n```rust\n        let mut lua = Lua::new();\n\n        lua.execute::\u003c()\u003e(r#\"v = { 1, 2, 3 }\"#).unwrap();\n\n        let read: Vec\u003c_\u003e = lua.get(\"v\").unwrap();\n        assert_eq!(\n            read,\n            [1., 2., 3.].iter()\n                .map(|x| AnyLuaValue::LuaNumber(*x)).collect::\u003cVec\u003c_\u003e\u003e());\n```\n\nIn case table represents sparse array, has non-numeric keys, or\nindices not starting at 1, `.get()` will return `None`, as Rust's\n`Vec` doesn't support these features.\n\nIt is possible to read a `HashMap\u003cAnyHashableLuaValue, AnyLuaValue\u003e`:\n\n```rust\nlet mut lua = Lua::new();\n\nlua.execute::\u003c()\u003e(r#\"v = { [-1] = -1, [\"foo\"] = 2, [2.] = 42 }\"#).unwrap();\n\nlet read: HashMap\u003c_, _\u003e = lua.get(\"v\").unwrap();\nassert_eq!(read[\u0026AnyHashableLuaValue::LuaNumber(-1)], AnyLuaValue::LuaNumber(-1.));\nassert_eq!(read[\u0026AnyHashableLuaValue::LuaString(\"foo\".to_owned())], AnyLuaValue::LuaNumber(2.));\nassert_eq!(read[\u0026AnyHashableLuaValue::LuaNumber(2)], AnyLuaValue::LuaNumber(42.));\nassert_eq!(read.len(), 3);\n```\n\n#### User data\n\n**(note: the API here is very unstable for the moment)**\n\nWhen you expose functions to Lua, you may wish to read or write more elaborate objects. This is called a **user data**.\n\nTo do so, you should implement the `Push`, `CopyRead` and `ConsumeRead` for your types.\nThis is usually done by redirecting the call to `userdata::push_userdata`.\n\n```rust\nstruct Foo;\n\nimpl\u003cL\u003e hlua::Push\u003cL\u003e for Foo where L: hlua::AsMutLua\u003c'lua\u003e {\n    fn push_to_lua(self, lua: L) -\u003e hlua::PushGuard\u003cL\u003e {\n        lua::userdata::push_userdata(self, lua,\n            |mut metatable| {\n                // you can define all the member functions of Foo here\n                // see the official Lua documentation for metatables\n                metatable.set(\"__call\", hlua::function0(|| println!(\"hello from foo\")))\n            })\n    }\n}\n\nfn main() {\n    let mut lua = lua::Lua::new();\n    lua.set(\"foo\", Foo);\n    lua.execute::\u003c()\u003e(\"foo()\");       // prints \"hello from foo\"\n}\n```\n\n### Contributing\n\nContributions are welcome!\n","funding_links":[],"categories":["Development tools","开发工具 Development tools","开发工具"],"sub_categories":["FFI","FFI FFI","示例 FFI"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomaka%2Fhlua","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftomaka%2Fhlua","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomaka%2Fhlua/lists"}