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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
//! Batteries-included standard library modules for mlua.
//!
//! Each module exposes a single `module(lua) -> LuaResult<LuaTable>` entry point.
//! Register individually or use [`register_all`] for convenience.
//!
//! # Platform support
//!
//! This crate targets **Unix server platforms** (Linux, macOS).
//! Windows is not a supported target.
//!
//! # Encoding — UTF-8 only (by design)
//!
//! All path arguments are received as Rust [`String`] (UTF-8).
//! Non-UTF-8 Lua strings are rejected at the `FromLua` boundary.
//! Returned paths use [`to_string_lossy`](std::path::Path::to_string_lossy),
//! replacing any non-UTF-8 bytes with U+FFFD.
//!
//! ## Why not raw bytes / `OsStr`?
//!
//! mlua's `FromLua` for `String` performs UTF-8 validation — non-UTF-8
//! values produce `FromLuaConversionError` before reaching handler code.
//! Bypassing this would require accepting `mlua::String` + `as_bytes()`
//! in every function, converting through `OsStr::from_bytes()`, and
//! returning `OsStr::as_bytes()` back to Lua. This adds complexity
//! across all path-accepting functions for a scenario (non-UTF-8
//! filenames) that is rare on modern systems.
//!
//! References:
//! - mlua `String::to_str()`: <https://docs.rs/mlua/latest/mlua/struct.String.html>
//! - mlua string internals: <https://deepwiki.com/mlua-rs/mlua/2.3.4-strings>
//!
//! # Quick start
//!
//! ```rust,no_run
//! use mlua::prelude::*;
//!
//! let lua = Lua::new();
//! mlua_batteries::register_all(&lua, "std").unwrap();
//! // Lua: std.json.encode({a = 1})
//! // Lua: std.env.get("HOME")
//! ```
//!
//! # Custom configuration
//!
//! ```rust,ignore
//! // Requires the `sandbox` feature.
//! use mlua::prelude::*;
//! use mlua_batteries::config::Config;
//! use mlua_batteries::policy::Sandboxed;
//!
//! let lua = Lua::new();
//! let config = Config::builder()
//! .path_policy(Sandboxed::new(["/app/data"]).unwrap().read_only())
//! .max_walk_depth(50)
//! .build()
//! .expect("invalid config");
//! mlua_batteries::register_all_with(&lua, "std", config).unwrap();
//! ```
pub
use Config;
use *;
/// Module factory function type.
pub type ModuleFactory = fn ;
/// Register all enabled modules with default configuration.
///
/// Equivalent to `register_all_with(lua, namespace, Config::default())`.
///
/// # Warning
///
/// The default configuration uses [`policy::Unrestricted`], which allows
/// Lua scripts to access **any** file on the filesystem. For untrusted
/// scripts, use [`register_all_with`] with a [`policy::Sandboxed`] policy.
/// Register all enabled modules with custom configuration.
///
/// The [`Config`] is stored in `lua.app_data` and consulted by each
/// module for policy checks and limit values.
///
/// # Calling multiple times
///
/// Calling this function again on the same [`Lua`] instance **replaces**
/// the previous [`Config`] (and the shared HTTP agent, if the `http`
/// feature is enabled). Functions registered by earlier calls remain
/// in the namespace table but will use the **new** Config for all
/// subsequent invocations. This is intentional — it allows
/// reconfiguration — but callers should be aware that there is no
/// "merge" behaviour.
/// Returns a list of `(name, factory)` pairs for all enabled modules.
///
/// Each entry is a `(&'static str, fn(&Lua) -> LuaResult<LuaTable>)`.
/// The list only includes modules whose cargo features are active.
///
/// # When to use
///
/// Use this when you need per-module registration instead of the
/// all-in-one [`register_all`]. Common case: integration with
/// `mlua-pkg`'s `NativeResolver`:
///
/// ```rust,ignore
/// // `ignore`: NativeResolver is from the `mlua-pkg` crate, which is
/// // not a dependency of this crate. Cannot be compiled in-tree.
/// let mut resolver = NativeResolver::new();
/// for (name, factory) in mlua_batteries::module_entries() {
/// resolver = resolver.add(name, |lua| factory(lua).map(mlua::Value::Table));
/// }
/// ```