rs_web/lua/
mod.rs

1//! Lua API functions for rs-web
2//!
3//! This module provides all Lua functions available in config.lua,
4//! organized by category for maintainability.
5//!
6//! Usage in Lua:
7//! ```lua
8//! local rs = require("rs-web")
9//! local content = rs.read_file("path/to/file.md")
10//! local html = rs.render_markdown(content)
11//! ```
12
13mod assets;
14mod async_io;
15mod collections;
16mod content;
17mod coro;
18mod crypt;
19mod env;
20mod file_ops;
21mod git;
22mod helpers;
23mod images;
24mod markdown_context;
25mod parallel;
26mod search;
27mod text;
28mod types;
29
30pub use helpers::{is_path_within_root, parse_frontmatter_content, resolve_path};
31pub use types::{LuaClass, LuaField, LuaFunction, LuaParam, generate_emmylua, generate_markdown};
32
33use crate::tracker::SharedTracker;
34use mlua::{Lua, Result, Table};
35use std::path::Path;
36
37/// Register all Lua functions as a require-able module
38///
39/// This function registers the rs-web module so it can be used with:
40/// ```lua
41/// local rs = require("rs-web")
42/// ```
43///
44/// The module provides:
45/// - File operations: rs.read_file, rs.write_file, rs.load_json, etc.
46/// - Search: rs.glob, rs.scan
47/// - Collections: rs.filter, rs.sort, rs.map
48/// - Text: rs.slugify, rs.word_count, rs.reading_time
49/// - Environment: rs.env, rs.print, rs.is_gitignored
50/// - Git: rs.git_info
51/// - Content: rs.render_markdown, rs.rss_date, rs.html_to_text, etc.
52/// - Images: rs.image_dimensions, rs.image_resize, rs.image_convert, rs.image_optimize
53/// - Assets: rs.build_css
54/// - Coroutines: rs.coro.task, rs.coro.await, rs.coro.yield, etc.
55/// - Parallel (rayon): rs.parallel.load_json, rs.parallel.read_files, etc.
56/// - Async I/O (tokio): rs.async.fetch, rs.async.read_file, rs.async.write_file, etc.
57/// - Encryption: rs.crypt.encrypt, rs.crypt.decrypt, rs.crypt.encrypt_html
58pub fn register(
59    lua: &Lua,
60    project_root: &Path,
61    sandbox: bool,
62    tracker: SharedTracker,
63    global_password: Option<String>,
64) -> Result<()> {
65    let root = project_root.to_path_buf();
66
67    // Create the main module table
68    let rs_module = lua.create_table()?;
69
70    // Store metadata
71    rs_module.set("_VERSION", env!("CARGO_PKG_VERSION"))?;
72    rs_module.set("_SANDBOX", sandbox)?;
73    rs_module.set("_PROJECT_ROOT", project_root.to_string_lossy().to_string())?;
74
75    // Register all function categories on the module
76    file_ops::register(lua, &rs_module, &root, sandbox, tracker.clone())?;
77    search::register(lua, &rs_module, &root, sandbox)?;
78    collections::register(lua, &rs_module)?;
79    text::register(lua, &rs_module)?;
80    env::register(lua, &rs_module, &root)?;
81    git::register(lua, &rs_module, &root, sandbox)?;
82    content::register(lua, &rs_module, tracker.clone())?;
83    images::register(lua, &rs_module, &root, tracker.clone())?;
84    assets::register(lua, &rs_module, &root, tracker.clone())?;
85
86    // Register coro and parallel as submodules
87    let coro_module = coro::create_module(lua)?;
88    rs_module.set("coro", coro_module)?;
89
90    let parallel_module = parallel::create_module(lua, &root, sandbox, tracker.clone())?;
91    rs_module.set("parallel", parallel_module)?;
92
93    let async_module = async_io::create_module(lua, &root, sandbox)?;
94    // Use raw_set to avoid "async" being a reserved word in some contexts
95    rs_module.raw_set("async", async_module)?;
96
97    let crypt_module = crypt::create_module(lua, global_password)?;
98    rs_module.set("crypt", crypt_module)?;
99
100    // Register as a preloaded module so require("rs-web") works
101    let preload: Table = lua
102        .globals()
103        .get::<Table>("package")?
104        .get::<Table>("preload")?;
105
106    let rs_module_clone = rs_module.clone();
107    let loader = lua.create_function(move |_, _: ()| Ok(rs_module_clone.clone()))?;
108    preload.set("rs-web", loader)?;
109    lua.globals().set("rs", rs_module)?;
110
111    Ok(())
112}