Skip to content

allow erroring in navigateresult directly #582

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions mlua-sys/src/luau/luarequire.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub struct luarequire_Configuration {
unsafe extern "C" fn(L: *mut lua_State, ctx: *mut c_void, requirer_chunkname: *const c_char) -> bool,

// Resets the internal state to point at the requirer module.
pub reset: unsafe extern "C" fn(
pub reset: unsafe extern "C-unwind" fn(
L: *mut lua_State,
ctx: *mut c_void,
requirer_chunkname: *const c_char,
Expand All @@ -39,15 +39,15 @@ pub struct luarequire_Configuration {
// Resets the internal state to point at an aliased module, given its exact path from a configuration
// file. This function is only called when an alias's path cannot be resolved relative to its
// configuration file.
pub jump_to_alias: unsafe extern "C" fn(
pub jump_to_alias: unsafe extern "C-unwind" fn(
L: *mut lua_State,
ctx: *mut c_void,
path: *const c_char,
) -> luarequire_NavigateResult,

// Navigates through the context by making mutations to the internal state.
pub to_parent: unsafe extern "C" fn(L: *mut lua_State, ctx: *mut c_void) -> luarequire_NavigateResult,
pub to_child: unsafe extern "C" fn(
pub to_parent: unsafe extern "C-unwind" fn(L: *mut lua_State, ctx: *mut c_void) -> luarequire_NavigateResult,
pub to_child: unsafe extern "C-unwind" fn(
L: *mut lua_State,
ctx: *mut c_void,
name: *const c_char,
Expand Down
59 changes: 45 additions & 14 deletions src/luau/require.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,19 @@ use std::os::raw::{c_char, c_int, c_void};
use std::path::{Component, Path, PathBuf};
use std::result::Result as StdResult;
use std::{env, fmt, fs, mem, ptr};

use crate::error::Result;
use crate::error::{Result, Error};
use crate::function::Function;
use crate::state::{callback_error_ext, Lua};
use crate::table::Table;
use crate::types::MaybeSend;
use crate::traits::IntoLua;
use crate::state::RawLua;

/// An error that can occur during navigation in the Luau `require` system.
pub enum NavigateError {
Ambiguous,
NotFound,
Error(Error)
}

#[cfg(feature = "luau")]
Expand All @@ -31,6 +33,7 @@ impl IntoNavigateResult for StdResult<(), NavigateError> {
Ok(()) => ffi::luarequire_NavigateResult::Success,
Err(NavigateError::Ambiguous) => ffi::luarequire_NavigateResult::Ambiguous,
Err(NavigateError::NotFound) => ffi::luarequire_NavigateResult::NotFound,
Err(NavigateError::Error(_)) => unreachable!()
}
}
}
Expand Down Expand Up @@ -320,42 +323,70 @@ pub(super) unsafe extern "C" fn init_config(config: *mut ffi::luarequire_Configu
this.is_require_allowed(&chunk_name)
}

unsafe extern "C" fn reset(
_state: *mut ffi::lua_State,
unsafe extern "C-unwind" fn reset(
state: *mut ffi::lua_State,
ctx: *mut c_void,
requirer_chunkname: *const c_char,
) -> ffi::luarequire_NavigateResult {
let this = &*(ctx as *const Box<dyn Require>);
let chunk_name = CStr::from_ptr(requirer_chunkname).to_string_lossy();
this.reset(&chunk_name).into_nav_result()
match this.reset(&chunk_name) {
Err(NavigateError::Error(err)) => {
let raw_lua = RawLua::init_from_ptr(state, false);
err.push_into_stack(&raw_lua.lock()).expect("mlua internal: failed to push error to stack");
ffi::lua_error(state);
},
error => error.into_nav_result()
}
}

unsafe extern "C" fn jump_to_alias(
_state: *mut ffi::lua_State,
unsafe extern "C-unwind" fn jump_to_alias(
state: *mut ffi::lua_State,
ctx: *mut c_void,
path: *const c_char,
) -> ffi::luarequire_NavigateResult {
let this = &*(ctx as *const Box<dyn Require>);
let path = CStr::from_ptr(path).to_string_lossy();
this.jump_to_alias(&path).into_nav_result()
match this.jump_to_alias(&path) {
Err(NavigateError::Error(err)) => {
let raw_lua = RawLua::init_from_ptr(state, false);
err.push_into_stack(&raw_lua.lock()).expect("mlua internal: failed to push error to stack");
ffi::lua_error(state);
},
error => error.into_nav_result()
}
}

unsafe extern "C" fn to_parent(
_state: *mut ffi::lua_State,
unsafe extern "C-unwind" fn to_parent(
state: *mut ffi::lua_State,
ctx: *mut c_void,
) -> ffi::luarequire_NavigateResult {
let this = &*(ctx as *const Box<dyn Require>);
this.to_parent().into_nav_result()
match this.to_parent() {
Err(NavigateError::Error(err)) => {
let raw_lua = RawLua::init_from_ptr(state, false);
err.push_into_stack(&raw_lua.lock()).expect("mlua internal: failed to push error to stack");
ffi::lua_error(state);
},
error => error.into_nav_result()
}
}

unsafe extern "C" fn to_child(
_state: *mut ffi::lua_State,
unsafe extern "C-unwind" fn to_child(
state: *mut ffi::lua_State,
ctx: *mut c_void,
name: *const c_char,
) -> ffi::luarequire_NavigateResult {
let this = &*(ctx as *const Box<dyn Require>);
let name = CStr::from_ptr(name).to_string_lossy();
this.to_child(&name).into_nav_result()
match this.to_child(&name) {
Err(NavigateError::Error(err)) => {
let raw_lua = RawLua::init_from_ptr(state, false);
err.push_into_stack(&raw_lua.lock()).expect("mlua internal: failed to push error to stack");
ffi::lua_error(state);
},
error => error.into_nav_result()
}
}

unsafe extern "C" fn is_module_present(_state: *mut ffi::lua_State, ctx: *mut c_void) -> bool {
Expand Down
2 changes: 1 addition & 1 deletion src/state/raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ impl RawLua {
rawlua
}

pub(super) unsafe fn init_from_ptr(state: *mut ffi::lua_State, owned: bool) -> XRc<ReentrantMutex<Self>> {
pub(crate) unsafe fn init_from_ptr(state: *mut ffi::lua_State, owned: bool) -> XRc<ReentrantMutex<Self>> {
assert!(!state.is_null(), "Lua state is NULL");
if let Some(lua) = Self::try_from_ptr(state) {
return lua;
Expand Down
Loading