1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
//! Using the Lua programming language with the [`sandkiste`] sandboxing API
//!
//! # Features
//!
//! This crate allows executing [Lua](https://www.lua.org/) code in a sandbox
//! where memory usage and the number of executed Lua instructions can be
//! limited.
//!
//! It uses the [`sandkiste`] API, which is an interface that can also be used
//! for sandboxing other scripting languages than Lua.
//!
//! It is possible to call Lua functions from Rust or to call Rust closures
//! from Lua. However, execution time in Rust (or waiting for I/O) is not
//! counting towards resource limits.
//!
//! # Different Lua versions
//!
//! Upon building, either Lua version 5.3 or 5.4 must be selected by specifying
//! one of the features `Lua5_3` or `Lua5_4`. Currently, it is not possible to
//! build this crate with support for both Lua versions at the same time.
//!
//! To allow lifting this restriction in future, items are contained in a
//! module reflecting the Lua version being used (module `v5_3` or `v5_4`).
//!
//! # Example use
//!
//! ```
//! use sandkiste::prelude::*;
//! #[cfg(feature = "Lua5_3")]
//! use sandkiste_lua::v5_3::{LuaMachine, LuaDatum};
//! #[cfg(feature = "Lua5_4")]
//! use sandkiste_lua::v5_4::{LuaMachine, LuaDatum};
//! use std::cell::RefCell;
//!
//! let output_cell = RefCell::new(String::new());
//!
//! let machine = LuaMachine::new();
//!
//! machine.load_stdlib().expect("could not load Lua standard lib");
//! machine
//! .compile(
//! Some("init".to_string()),
//! "-- require 'some_library'",
//! )
//! .expect("could not compile initialization code")
//! .call([])
//! .expect("could not run initialization code");
//!
//! // remove certain functions from Lua's standard library:
//! machine.seal().expect("could not seal sandbox");
//!
//! let my_print = machine
//! .callback_1arg(|s| {
//! let s = s.try_as_str()?;
//! let mut output = output_cell.borrow_mut();
//! output.push_str(s);
//! Ok([])
//! })
//! .expect("could not create closure for myprint");
//! machine
//! .compile(
//! Some("set_myprint".to_string()),
//! "myprint = ...",
//! )
//! .expect("could not compile code to set myprint")
//! .call([my_print])
//! .expect("could not run code to set myprint");
//!
//! let main = machine
//! .compile(
//! Some("main".to_string()),
//! "\
//! local args = {...}\n\
//! myprint('Hello ')\n\
//! myprint(args[1])\n\
//! myprint('!')\n\
//! "
//! )
//! .expect("could not compile main Lua function");
//!
//! let name: LuaDatum = "Rust".into();
//! main.call([name]).expect("runtime error in main Lua function");
//!
//! // dropping these lets us move out of `output_cell`, which is still
//! // borrowed by the closure that has been moved to the machine:
//! drop(main);
//! drop(machine);
//!
//! let output = output_cell.into_inner();
//! assert_eq!(output, "Hello Rust!");
//! ```
#![warn(missing_docs)]
pub mod cmach;
#[cfg(feature = "Lua5_3")]
pub mod v5_3 {
//! Support for Lua 5.3
//!
//! This module provides data structures implementing the
//! [`sandkiste`] API to provide support for version 5.3 of the
//! [Lua programming language](https://www.lua.org/).
//! For an overview on how to use these data structures, refer
//! to the [top-level module documentation](super).
include!("common.rs");
}
#[cfg(feature = "Lua5_4")]
pub mod v5_4 {
//! Support for Lua 5.4
//!
//! This module provides data structures implementing the
//! [`sandkiste`] API to provide support for version 5.4 of the
//! [Lua programming language](https://www.lua.org/).
//! For an overview on how to use these data structures, refer
//! to the [top-level module documentation](super).
include!("common.rs");
}
#[cfg(any())] // never expose, only for rustfmt
pub mod common;
#[cfg(test)]
mod tests;