Skip to main content

zoi_lua/api/
lifecycle.rs

1use mlua::{self, Lua, LuaSerdeExt, Table, Value};
2use std::fs;
3use std::path::Path;
4
5pub fn add_import_util(lua: &Lua, current_path: &Path) -> Result<(), mlua::Error> {
6    let current_path_buf = current_path.to_path_buf();
7    let import_fn = lua.create_function(move |lua, file_name: String| {
8        let parent = current_path_buf.parent().ok_or_else(|| {
9            mlua::Error::RuntimeError(
10                "Could not determine parent directory of package file".to_string(),
11            )
12        })?;
13        let path = parent.join(&file_name);
14        let content =
15            fs::read_to_string(&path).map_err(|e| mlua::Error::RuntimeError(e.to_string()))?;
16
17        if let Some(extension) = path.extension().and_then(|s| s.to_str()) {
18            match extension {
19                "json" => {
20                    let value: serde_json::Value = serde_json::from_str(&content)
21                        .map_err(|e| mlua::Error::RuntimeError(e.to_string()))?;
22                    return lua.to_value(&value);
23                }
24                "yaml" | "yml" => {
25                    let value: serde_yaml::Value = serde_yaml::from_str(&content)
26                        .map_err(|e| mlua::Error::RuntimeError(e.to_string()))?;
27                    return lua.to_value(&value);
28                }
29                "toml" => {
30                    let value: toml::Value = toml::from_str(&content)
31                        .map_err(|e| mlua::Error::RuntimeError(e.to_string()))?;
32                    return lua.to_value(&value);
33                }
34                _ => {
35                    return lua.to_value(&content);
36                }
37            }
38        }
39
40        lua.to_value(&content)
41    })?;
42    lua.globals().set("IMPORT", import_fn)?;
43    Ok(())
44}
45
46pub fn add_include_util(lua: &Lua, current_path: &Path) -> Result<(), mlua::Error> {
47    let current_path_buf = current_path.to_path_buf();
48    let include_fn =
49        lua.create_function(move |lua, file_name: String| -> Result<(), mlua::Error> {
50            let parent = current_path_buf.parent().ok_or_else(|| {
51                mlua::Error::RuntimeError(
52                    "Could not determine parent directory of package file".to_string(),
53                )
54            })?;
55            let path = parent.join(file_name);
56            let code =
57                fs::read_to_string(path).map_err(|e| mlua::Error::RuntimeError(e.to_string()))?;
58            lua.load(&code).exec()?;
59            Ok(())
60        })?;
61    lua.globals().set("INCLUDE", include_fn)?;
62    Ok(())
63}
64
65pub fn add_package_lifecycle_functions(lua: &Lua) -> Result<(), mlua::Error> {
66    let metadata_fn = lua.create_function(move |lua, pkg_def: Table| {
67        if let Ok(meta_table) = lua.globals().get::<Table>("__ZoiPackageMeta")
68            && let Ok(pkg_global) = lua.globals().get::<Table>("PKG")
69        {
70            for pair in pkg_def.pairs::<Value, Value>() {
71                let (key, value) = pair?;
72                meta_table.set(key.clone(), value.clone())?;
73                pkg_global.set(key, value)?;
74            }
75        }
76        Ok(())
77    })?;
78    lua.globals().set("metadata", metadata_fn)?;
79
80    let dependencies_fn = lua.create_function(move |lua, deps_def: Table| {
81        if let Ok(deps_table) = lua.globals().get::<Table>("__ZoiPackageDeps") {
82            for pair in deps_def.pairs::<String, Value>() {
83                let (key, value) = pair?;
84                deps_table.set(key, value)?;
85            }
86        }
87        Ok(())
88    })?;
89    lua.globals().set("dependencies", dependencies_fn)?;
90
91    let updates_fn = lua.create_function(move |lua, updates_list: Table| {
92        if let Ok(updates_table) = lua.globals().get::<Table>("__ZoiPackageUpdates") {
93            for pair in updates_list.pairs::<Value, Table>() {
94                let (_, update_info) = pair?;
95                updates_table.push(update_info)?;
96            }
97        }
98        Ok(())
99    })?;
100    lua.globals().set("updates", updates_fn)?;
101
102    let hooks_fn = lua.create_function(move |lua, hooks_def: Table| {
103        if let Ok(hooks_table) = lua.globals().get::<Table>("__ZoiPackageHooks") {
104            for pair in hooks_def.pairs::<String, Value>() {
105                let (key, value) = pair?;
106                hooks_table.set(key, value)?;
107            }
108        }
109        Ok(())
110    })?;
111    lua.globals().set("hooks", hooks_fn)?;
112
113    let service_fn = lua.create_function(move |lua, service_def: Table| {
114        if let Ok(service_table) = lua.globals().get::<Table>("__ZoiPackageService") {
115            for pair in service_def.pairs::<String, Value>() {
116                let (key, value) = pair?;
117                service_table.set(key, value)?;
118            }
119        }
120        Ok(())
121    })?;
122    lua.globals().set("service", service_fn)?;
123
124    let prepare_fn = lua.create_function(|_, _: mlua::MultiValue| Ok(()))?;
125    lua.globals().set("prepare", prepare_fn)?;
126    let package_fn = lua.create_function(|_, _: mlua::MultiValue| Ok(()))?;
127    lua.globals().set("package", package_fn)?;
128    let verify_fn = lua.create_function(|_, _: mlua::MultiValue| Ok(true))?;
129    lua.globals().set("verify", verify_fn)?;
130    let test_fn = lua.create_function(|_, _: mlua::MultiValue| Ok(true))?;
131    lua.globals().set("test", test_fn)?;
132    let uninstall_fn = lua.create_function(|_, _: mlua::MultiValue| Ok(()))?;
133    lua.globals().set("uninstall", uninstall_fn)?;
134
135    Ok(())
136}