fmt comment
export include_fnl_config::Mount from include_fnl
refactor Mount
Embed Fennel modules in Rust.
Assume we have the following directory structure, where .
is a simple
Rust library crate containing subdirectory kiwi
. Inside kiwi
are
Fennel modules to embed:
$ tree
.
├── kiwi
│ ├── dine
│ │ ├── init.fnl
│ │ └── proximates.fnl
│ ├── food
│ │ ├── init.fnl
│ │ └── proximates.fnl
│ ├── cite.fnl
│ ├── date-time.fnl
│ ├── date.fnl
│ ├── time.fnl
│ └── utils.fnl
├── src
│ └── lib.rs
└── Cargo.toml
4 directories, 11 files
Create include.fnl
alongside Cargo.toml
:
(local include-fnl (require :include-fnl))
{;; Name of Fennel module searcher.
:kiwi {
;; Table of Fennel module paths indexed by module name.
:provides {:fnl {:kiwi/cite :kiwi/cite.fnl
:kiwi/date :kiwi/date.fnl
:kiwi/date-time :kiwi/date-time.fnl
:kiwi/dine :kiwi/dine/init.fnl
:kiwi/dine/proximates :kiwi/dine/proximates.fnl
:kiwi/food :kiwi/food/init.fnl
:kiwi/food/proximates :kiwi/food/proximates.fnl
:kiwi/time :kiwi/time.fnl
:kiwi/utils :kiwi/utils.fnl}
;; Embed Fennel release from `fennel-src` crate. Enables
;; `(require :fennel)`.
:lua {:fennel include-fnl.fennel-path}}}}
main.rs
:
use rlua::Lua;
// For enabling the `add_searcher` method on `rlua::Context`.
use rlua_searcher::AddSearcher;
// For enabling `include_fnl!`.
use include_fnl::include_fnl;
fn main() {
let lua = Lua::new();
// Embed Fennel modules specified in the `provides` table of the searcher named `kiwi`
// in `include.fnl`. Fennel sources are AOT-compiled to Lua during Rust comptime.
// Our source code can access Fennel via `require("fennel")`, because we configured the
// `kiwi` module searcher to embed the Fennel library.
let mut kiwi = include_fnl!("kiwi");
let kiwi_fnl = kiwi.fnl.take().unwrap();
let kiwi_lua = kiwi.lua.take().unwrap();
let uuid = lua.context::<_, String>(|lua_ctx| {
// Enable Lua's `require` to find embedded Fennel modules (AOT-compiled to Lua).
//
// N.B. Fennel is not yet accessible via `require("fennel")`, because `kiwi_fnl`
// contains only Fennel source code. If you need to access Fennel, load `kiwi_lua`.
lua_ctx.add_searcher(kiwi_fnl).unwrap();
lua_ctx
.load(r#"local utils = require("kiwi/utils"); return utils.uuid()"#)
.eval()
.unwrap()
});
// e.g. "d717c6d8-ebed-47ca-8c21-2b6624846ddc"
eprintln!("{}", uuid);
let version = lua.context::<_, String>(|lua_ctx| {
// Enable Lua's `require` to find Lua modules (including Fennel itself) - in this
// case, only Fennel itself. We configure Lua modules separately from Fennel
// modules because Fennel modules require a compilation step.
lua_ctx.add_searcher(kiwi_lua).unwrap();
lua_ctx
.load(r#"local fennel = require("fennel"); return fennel.version"#)
.eval()
.unwrap()
});
assert_eq!(&version, "1.0.0");
}
main.rs
:
use rlua::Lua;
// For enabling the `add_path_searcher_fnl` method on `rlua::Context`.
use fennel_searcher::AddSearcherFnl;
// For enabling the `add_path_searcher` method on `rlua::Context`.
use rlua_searcher::AddSearcher;
// For enabling `load_fnl!`.
use include_fnl::load_fnl;
fn main() {
let lua = Lua::new();
// Configure Fennel modules specified in the `provides` table of the searcher named
// `kiwi` in `include.fnl` to be compiled to Lua at runtime (on demand). With Fennel
// accessible via module name `fennel`.
let mut kiwi = load_fnl!("kiwi");
let kiwi_fnl = kiwi.fnl.take().unwrap();
let kiwi_lua = kiwi.lua.take().unwrap();
let uuid = lua.context::<_, String>(|lua_ctx| {
// Enable Lua's `require` to find Fennel modules.
lua_ctx.add_path_searcher_fnl(kiwi_fnl).unwrap();
lua_ctx
.load(r#"local utils = require("kiwi/utils"); return utils.uuid()"#)
.eval()
.unwrap()
});
// e.g. "d717c6d8-ebed-47ca-8c21-2b6624846ddc"
eprintln!("{}", uuid);
let version = lua.context::<_, String>(|lua_ctx| {
// Enable Lua's `require` to find Lua modules (including Fennel itself) - in this
// case, only Fennel itself.
lua_ctx.add_path_searcher(kiwi_lua).unwrap();
lua_ctx
.load(r#"local fennel = require("fennel"); return fennel.version"#)
.eval()
.unwrap()
});
assert_eq!(&version, "1.0.0");
}
Licensed under either of
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.