Skip to main content

luaur_repl_cli/functions/
require_config_init.rs

1use core::ffi::{c_char, c_int, c_void};
2
3use luaur_require::enums::luarequire_config_status::luarequire_ConfigStatus as ReqConfigStatus;
4use luaur_require::enums::luarequire_navigate_result::luarequire_NavigateResult as ReqNavigateResult;
5use luaur_require::enums::luarequire_write_result::luarequire_WriteResult as ReqWriteResult;
6use luaur_require::records::luarequire_configuration::luarequire_Configuration;
7
8use luaur_vm::type_aliases::lua_state::lua_State;
9
10use crate::functions::convert_repl_requirer::luarequire_NavigateResult as CliNavigateResult;
11use crate::functions::convert_repl_requirer_alt_b::luarequire_ConfigStatus as CliConfigStatus;
12use crate::functions::get_cache_key::get_cache_key;
13use crate::functions::get_chunkname::get_chunkname;
14use crate::functions::get_config::get_config;
15use crate::functions::get_config_status::get_config_status;
16use crate::functions::get_loadname::get_loadname;
17use crate::functions::is_module_present::is_module_present;
18use crate::functions::is_require_allowed::is_require_allowed;
19use crate::functions::jump_to_alias::jump_to_alias;
20use crate::functions::load::load;
21use crate::functions::reset::reset;
22use crate::functions::to_child::to_child;
23use crate::functions::to_parent::to_parent;
24use crate::functions::write::luarequire_WriteResult as CliWriteResult;
25
26// The CLI requirer functions report results with crate-local enums (the faithful
27// translations of the enums declared alongside Repl.cpp/ReplRequirer.cpp); these
28// helpers map them onto the `luaur_require` C-ABI enums expected by the
29// luarequire_Configuration struct that luaopen_require consumes.
30fn to_req_navigate(r: CliNavigateResult) -> ReqNavigateResult {
31    match r {
32        CliNavigateResult::NAVIGATE_SUCCESS => ReqNavigateResult::NAVIGATE_SUCCESS,
33        CliNavigateResult::NAVIGATE_AMBIGUOUS => ReqNavigateResult::NAVIGATE_AMBIGUOUS,
34        CliNavigateResult::NAVIGATE_NOT_FOUND => ReqNavigateResult::NAVIGATE_NOT_FOUND,
35    }
36}
37
38fn to_req_config_status(r: CliConfigStatus) -> ReqConfigStatus {
39    match r {
40        CliConfigStatus::CONFIG_AMBIGUOUS => ReqConfigStatus::CONFIG_AMBIGUOUS,
41        CliConfigStatus::CONFIG_PRESENT_JSON => ReqConfigStatus::CONFIG_PRESENT_JSON,
42        CliConfigStatus::CONFIG_PRESENT_LUAU => ReqConfigStatus::CONFIG_PRESENT_LUAU,
43        CliConfigStatus::CONFIG_ABSENT => ReqConfigStatus::CONFIG_ABSENT,
44    }
45}
46
47fn to_req_write(r: CliWriteResult) -> ReqWriteResult {
48    match r {
49        CliWriteResult::WRITE_SUCCESS => ReqWriteResult::WRITE_SUCCESS,
50        CliWriteResult::WRITE_BUFFER_TOO_SMALL => ReqWriteResult::WRITE_BUFFER_TOO_SMALL,
51        CliWriteResult::WRITE_FAILURE => ReqWriteResult::WRITE_FAILURE,
52    }
53}
54
55unsafe extern "C" fn cb_is_require_allowed(
56    l: *mut c_void,
57    ctx: *mut c_void,
58    requirer_chunkname: *const c_char,
59) -> bool {
60    is_require_allowed(l as *mut lua_State, ctx, requirer_chunkname)
61}
62
63unsafe extern "C" fn cb_reset(
64    l: *mut c_void,
65    ctx: *mut c_void,
66    requirer_chunkname: *const c_char,
67) -> ReqNavigateResult {
68    to_req_navigate(reset(l as *mut lua_State, ctx, requirer_chunkname))
69}
70
71unsafe extern "C" fn cb_jump_to_alias(
72    l: *mut c_void,
73    ctx: *mut c_void,
74    path: *const c_char,
75) -> ReqNavigateResult {
76    to_req_navigate(jump_to_alias(l as *mut lua_State, ctx, path))
77}
78
79unsafe extern "C" fn cb_to_parent(l: *mut c_void, ctx: *mut c_void) -> ReqNavigateResult {
80    to_req_navigate(to_parent(l as *mut lua_State, ctx))
81}
82
83unsafe extern "C" fn cb_to_child(
84    l: *mut c_void,
85    ctx: *mut c_void,
86    name: *const c_char,
87) -> ReqNavigateResult {
88    to_req_navigate(to_child(l as *mut lua_State, ctx, name))
89}
90
91unsafe extern "C" fn cb_is_module_present(l: *mut c_void, ctx: *mut c_void) -> bool {
92    is_module_present(l as *mut lua_State, ctx)
93}
94
95unsafe extern "C" fn cb_get_config_status(l: *mut c_void, ctx: *mut c_void) -> ReqConfigStatus {
96    to_req_config_status(get_config_status(l as *mut lua_State, ctx))
97}
98
99unsafe extern "C" fn cb_get_chunkname(
100    l: *mut c_void,
101    ctx: *mut c_void,
102    buffer: *mut c_char,
103    buffer_size: usize,
104    size_out: *mut usize,
105) -> ReqWriteResult {
106    to_req_write(get_chunkname(
107        l as *mut lua_State,
108        ctx,
109        buffer,
110        buffer_size,
111        size_out,
112    ))
113}
114
115unsafe extern "C" fn cb_get_loadname(
116    l: *mut c_void,
117    ctx: *mut c_void,
118    buffer: *mut c_char,
119    buffer_size: usize,
120    size_out: *mut usize,
121) -> ReqWriteResult {
122    to_req_write(get_loadname(
123        l as *mut lua_State,
124        ctx,
125        buffer,
126        buffer_size,
127        size_out,
128    ))
129}
130
131unsafe extern "C" fn cb_get_cache_key(
132    l: *mut c_void,
133    ctx: *mut c_void,
134    buffer: *mut c_char,
135    buffer_size: usize,
136    size_out: *mut usize,
137) -> ReqWriteResult {
138    to_req_write(get_cache_key(
139        l as *mut lua_State,
140        ctx,
141        buffer,
142        buffer_size,
143        size_out,
144    ))
145}
146
147unsafe extern "C" fn cb_get_config(
148    l: *mut c_void,
149    ctx: *mut c_void,
150    buffer: *mut c_char,
151    buffer_size: usize,
152    size_out: *mut usize,
153) -> ReqWriteResult {
154    to_req_write(get_config(
155        l as *mut lua_State,
156        ctx,
157        buffer,
158        buffer_size,
159        size_out,
160    ))
161}
162
163unsafe extern "C-unwind" fn cb_load(
164    l: *mut c_void,
165    ctx: *mut c_void,
166    path: *const c_char,
167    chunkname: *const c_char,
168    loadname: *const c_char,
169) -> c_int {
170    load(l as *mut lua_State, ctx, path, chunkname, loadname)
171}
172
173// Faithful port of `requireConfigInit`: install the CLI requirer's navigation
174// and I/O callbacks into the luarequire configuration.
175pub unsafe extern "C" fn require_config_init(config: *mut luarequire_Configuration) {
176    if config.is_null() {
177        return;
178    }
179
180    let config = &mut *config;
181    config.is_require_allowed = Some(cb_is_require_allowed);
182    config.reset = Some(cb_reset);
183    config.jump_to_alias = Some(cb_jump_to_alias);
184    config.to_parent = Some(cb_to_parent);
185    config.to_child = Some(cb_to_child);
186    config.is_module_present = Some(cb_is_module_present);
187    config.get_config_status = Some(cb_get_config_status);
188    config.get_chunkname = Some(cb_get_chunkname);
189    config.get_loadname = Some(cb_get_loadname);
190    config.get_cache_key = Some(cb_get_cache_key);
191    config.get_config = Some(cb_get_config);
192    config.load = Some(cb_load);
193}