mlua_extras/extras/
require.rs

1use mlua::{Error, FromLua, Table};
2
3/// Adds a similar syntax to tables as lua's `require` function.
4///
5/// # Example
6///
7/// ```
8/// use mlua_extras::{
9///     mlua::{Lua, Function},
10///     extras::Require,
11/// };
12///
13/// let lua = Lua::new();
14///
15/// let unpack = lua.require::<Function>("table.unpack")?;
16/// ```
17///
18/// Would be the same as
19///
20/// ```lua
21/// local unpack = require("table").unpack
22/// ```
23pub trait Require<'lua> {
24    /// Fetch a nested lua value from the table
25    fn require<R: FromLua<'lua>>(&'lua self, path: impl AsRef<str>) -> mlua::Result<R>;
26}
27
28impl<'lua> Require<'lua> for Table<'lua> {
29    fn require<R: FromLua<'lua>>(&'lua self, path: impl AsRef<str>) -> mlua::Result<R> {
30        let segments = path
31            .as_ref()
32            .split('.')
33            .filter_map(|v| (!v.trim().is_empty()).then_some(v.trim()))
34            .collect::<Vec<_>>();
35
36        let mut module = self.clone();
37        if !segments.is_empty() {
38            for seg in &segments[..segments.len() - 1] {
39                module = module.get::<_, Table>(*seg)?;
40            }
41        }
42
43        match segments.last() {
44            Some(seg) => module.get::<_, R>(*seg),
45            None => Err(Error::runtime(format!(
46                "module not found: {:?}",
47                path.as_ref()
48            ))),
49        }
50    }
51}