Update examples to include chunk! macro

This commit is contained in:
Alex Orlenko 2021-06-19 14:41:48 +01:00
parent 242bdafa75
commit a208156ed2
5 changed files with 50 additions and 47 deletions

View file

@ -76,11 +76,11 @@ required-features = ["async"]
[[example]]
name = "async_http_client"
required-features = ["async"]
required-features = ["async", "macros"]
[[example]]
name = "async_http_reqwest"
required-features = ["async", "serialize"]
required-features = ["async", "serialize", "macros"]
[[example]]
name = "async_http_server"
@ -88,7 +88,11 @@ required-features = ["async", "send"]
[[example]]
name = "async_tcp_server"
required-features = ["async"]
required-features = ["async", "macros"]
[[example]]
name = "guided_tour"
required-features = ["macros"]
[[example]]
name = "serialize"

View file

@ -5,7 +5,7 @@ use hyper::body::{Body as HyperBody, HttpBody as _};
use hyper::Client as HyperClient;
use tokio::sync::Mutex;
use mlua::{ExternalResult, Lua, Result, UserData, UserDataMethods};
use mlua::{chunk, ExternalResult, Lua, Result, UserData, UserDataMethods};
#[derive(Clone)]
struct BodyReader(Arc<Mutex<HyperBody>>);
@ -55,13 +55,9 @@ async fn main() -> Result<()> {
Ok(lua_resp)
})?;
let globals = lua.globals();
globals.set("fetch_url", fetch_url)?;
let f = lua
.load(
r#"
local res = fetch_url(...)
.load(chunk! {
local res = $fetch_url(...)
print(res.status)
for key, vals in pairs(res.headers) do
for _, val in ipairs(vals) do
@ -74,8 +70,7 @@ async fn main() -> Result<()> {
print(body)
end
until not body
"#,
)
})
.into_function()?;
f.call_async("http://httpbin.org/ip").await

View file

@ -1,10 +1,10 @@
use mlua::{ExternalResult, Lua, LuaSerdeExt, Result};
use mlua::{chunk, ExternalResult, Lua, LuaSerdeExt, Result};
#[tokio::main]
async fn main() -> Result<()> {
let lua = Lua::new();
let globals = lua.globals();
globals.set("null", lua.null())?;
let null = lua.null();
let fetch_json = lua.create_async_function(|lua, uri: String| async move {
let resp = reqwest::get(&uri)
@ -14,24 +14,21 @@ async fn main() -> Result<()> {
let json = resp.json::<serde_json::Value>().await.to_lua_err()?;
lua.to_value(&json)
})?;
globals.set("fetch_json", fetch_json)?;
let f = lua
.load(
r#"
.load(chunk! {
function print_r(t, indent)
local indent = indent or ''
local indent = indent or ""
for k, v in pairs(t) do
io.write(indent, tostring(k))
if type(v) == "table" then io.write(':\n') print_r(v, indent..' ')
else io.write(': ', v == null and "null" or tostring(v), '\n') end
if type(v) == "table" then io.write(":\n") print_r(v, indent.." ")
else io.write(": ", v == $null and "null" or tostring(v), "\n") end
end
end
local res = fetch_json(...)
local res = $fetch_json(...)
print_r(res)
"#,
)
})
.into_function()?;
f.call_async("https://httpbin.org/anything?arg0=val0").await

View file

@ -5,7 +5,7 @@ use tokio::net::{TcpListener, TcpStream};
use tokio::sync::Mutex;
use tokio::task;
use mlua::{Function, Lua, Result, String as LuaString, UserData, UserDataMethods};
use mlua::{chunk, Function, Lua, Result, String as LuaString, UserData, UserDataMethods};
struct LuaTcp;
@ -64,15 +64,12 @@ async fn run_server(lua: &'static Lua) -> Result<()> {
Ok(())
})?;
let globals = lua.globals();
globals.set("tcp", LuaTcp)?;
globals.set("spawn", spawn)?;
let tcp = LuaTcp;
let server = lua
.load(
r#"
.load(chunk! {
local addr = ...
local listener = tcp.bind(addr)
local listener = $tcp.bind(addr)
print("listening on "..addr)
local accept_new = true
@ -85,7 +82,7 @@ async fn run_server(lua: &'static Lua) -> Result<()> {
return
end
spawn(function()
$spawn(function()
while true do
local data = stream:read(100)
data = data:match("^%s*(.-)%s*$") -- trim
@ -104,8 +101,7 @@ async fn run_server(lua: &'static Lua) -> Result<()> {
end
end)
end
"#,
)
})
.into_function()?;
task::LocalSet::new()

View file

@ -1,15 +1,15 @@
use std::f32;
use std::iter::FromIterator;
use mlua::{Function, Lua, MetaMethod, Result, UserData, UserDataMethods, Variadic};
use mlua::{chunk, Function, Lua, MetaMethod, Result, UserData, UserDataMethods, Variadic};
fn main() -> Result<()> {
// You can create a new Lua state with `Lua::new()`. This loads the default Lua std library
// You can create a new Lua state with `Lua::new()`. This loads the default Lua std library
// *without* the debug library.
let lua = Lua::new();
// You can get and set global variables. Notice that the globals table here is a permanent
// reference to _G, and it is mutated behind the scenes as Lua code is loaded. This API is
// You can get and set global variables. Notice that the globals table here is a permanent
// reference to _G, and it is mutated behind the scenes as Lua code is loaded. This API is
// based heavily around sharing and internal mutation (just like Lua itself).
let globals = lua.globals();
@ -20,8 +20,8 @@ fn main() -> Result<()> {
assert_eq!(globals.get::<_, String>("string_var")?, "hello");
assert_eq!(globals.get::<_, i64>("int_var")?, 42);
// You can load and evaluate Lua code. The returned type of `Lua::load` is a builder
// that allows you to change settings before running Lua code. Here, we are using it to set
// You can load and evaluate Lua code. The returned type of `Lua::load` is a builder
// that allows you to change settings before running Lua code. Here, we are using it to set
// the name of the laoded chunk to "example code", which will be used when Lua error
// messages are printed.
@ -38,6 +38,17 @@ fn main() -> Result<()> {
assert_eq!(lua.load("false == false").eval::<bool>()?, true);
assert_eq!(lua.load("return 1 + 2").eval::<i32>()?, 3);
// Use can use special `chunk!` macro to use Rust tokenizer and automatically capture variables
let a = 1;
let b = 2;
let name = "world";
lua.load(chunk! {
print($a + $b)
print("hello, " .. $name)
})
.exec()?;
// You can create and manage Lua tables
let array_table = lua.create_table()?;
@ -76,7 +87,7 @@ fn main() -> Result<()> {
let print: Function = globals.get("print")?;
print.call::<_, ()>("hello from rust")?;
// This API generally handles variadics using tuples. This is one way to call a function with
// This API generally handles variadics using tuples. This is one way to call a function with
// multiple parameters:
print.call::<_, ()>(("hello", "again", "from", "rust"))?;
@ -87,15 +98,15 @@ fn main() -> Result<()> {
["hello", "yet", "again", "from", "rust"].iter().cloned(),
))?;
// You can bind rust functions to Lua as well. Callbacks receive the Lua state inself as their
// first parameter, and the arguments given to the function as the second parameter. The type
// You can bind rust functions to Lua as well. Callbacks receive the Lua state inself as their
// first parameter, and the arguments given to the function as the second parameter. The type
// of the arguments can be anything that is convertible from the parameters given by Lua, in
// this case, the function expects two string sequences.
let check_equal = lua.create_function(|_, (list1, list2): (Vec<String>, Vec<String>)| {
// This function just checks whether two string lists are equal, and in an inefficient way.
// Lua callbacks return `mlua::Result`, an Ok value is a normal return, and an Err return
// turns into a Lua 'error'. Again, any type that is convertible to Lua may be returned.
// turns into a Lua 'error'. Again, any type that is convertible to Lua may be returned.
Ok(list1 == list2)
})?;
globals.set("check_equal", check_equal)?;
@ -174,7 +185,7 @@ fn main() -> Result<()> {
lua.scope(|scope| {
// We create a 'sketchy' Lua callback that holds a mutable reference to the variable
// `rust_val`. Outside of a `Lua::scope` call, this would not be allowed
// `rust_val`. Outside of a `Lua::scope` call, this would not be allowed
// because it could be unsafe.
lua.globals().set(
@ -191,9 +202,9 @@ fn main() -> Result<()> {
assert_eq!(rust_val, 42);
}
// We were able to run our 'sketchy' function inside the scope just fine. However, if we
// We were able to run our 'sketchy' function inside the scope just fine. However, if we
// try to run our 'sketchy' function outside of the scope, the function we created will have
// been invalidated and we will generate an error. If our function wasn't invalidated, we
// been invalidated and we will generate an error. If our function wasn't invalidated, we
// might be able to improperly access the freed `rust_val` which would be unsafe.
assert!(lua.load("sketchy()").exec().is_err());