refactor: Overhaul Rhai scripting with multi-file hot reloading
This commit represents a major refactoring of our Rhai scripting system, transforming it from a factory-based approach to a more robust system-based architecture with improved hot reloading capabilities. Key Changes: - Renamed package from rhai_factory to rhai_system to better reflect its purpose - Renamed system_factory.rs to factory.rs for consistency and clarity - Implemented support for multiple script files in hot reloading - Added cross-script function calls, allowing functions in one script to call functions in another - Improved file watching to monitor all script files for changes - Enhanced error handling for script compilation failures - Simplified the API with a cleaner create_hot_reloadable_system function - Removed unused modules (error.rs, factory.rs, hot_reload_old.rs, module_cache.rs, relative_resolver.rs) - Updated all tests to work with the new architecture The new architecture: - Uses a System struct that holds references to script paths and provides a clean API - Compiles and merges multiple Rhai script files into a single AST - Automatically detects changes to any script file and recompiles them - Maintains thread safety with proper synchronization primitives - Provides better error messages when scripts fail to compile This refactoring aligns with our BasePathModuleResolver approach for module imports, making the resolution process more predictable and consistent. The hot reload example has been updated to demonstrate the new capabilities, showing how to: 1. Load and execute multiple script files 2. Watch for changes to these files 3. Automatically reload scripts when they change 4. Call functions across different script files All tests are passing, and the example demonstrates the improved functionality.
This commit is contained in:
950
rhai_system/examples/base_path_imports/Cargo.lock
generated
Normal file
950
rhai_system/examples/base_path_imports/Cargo.lock
generated
Normal file
@@ -0,0 +1,950 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"const-random",
|
||||
"getrandom 0.2.15",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "android-tzdata"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
|
||||
|
||||
[[package]]
|
||||
name = "android_system_properties"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||
|
||||
[[package]]
|
||||
name = "base_path_imports"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"rhai",
|
||||
"rhai_factory",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "525046617d8376e3db1deffb079e91cef90a89fc3ca5c185bbf8c9ecdd15cd5c"
|
||||
dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c"
|
||||
dependencies = [
|
||||
"android-tzdata",
|
||||
"iana-time-zone",
|
||||
"js-sys",
|
||||
"num-traits",
|
||||
"wasm-bindgen",
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "const-random"
|
||||
version = "0.1.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359"
|
||||
dependencies = [
|
||||
"const-random-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "const-random-macro"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e"
|
||||
dependencies = [
|
||||
"getrandom 0.2.15",
|
||||
"once_cell",
|
||||
"tiny-keccak",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
||||
|
||||
[[package]]
|
||||
name = "crunchy"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929"
|
||||
|
||||
[[package]]
|
||||
name = "filetime"
|
||||
version = "0.2.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"libredox",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fsevent-sys"
|
||||
version = "4.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"r-efi",
|
||||
"wasi 0.14.2+wasi-0.2.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8"
|
||||
dependencies = [
|
||||
"android_system_properties",
|
||||
"core-foundation-sys",
|
||||
"iana-time-zone-haiku",
|
||||
"js-sys",
|
||||
"log",
|
||||
"wasm-bindgen",
|
||||
"windows-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone-haiku"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inotify"
|
||||
version = "0.9.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"inotify-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inotify-sys"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.77"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kqueue"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7447f1ca1b7b563588a205fe93dea8df60fd981423a768bc1c0ded35ed147d0c"
|
||||
dependencies = [
|
||||
"kqueue-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kqueue-sys"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.171"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
|
||||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "no-std-compat"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c"
|
||||
dependencies = [
|
||||
"spin",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "notify"
|
||||
version = "5.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "729f63e1ca555a43fe3efa4f3efdf4801c479da85b432242a7b726f353c88486"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"crossbeam-channel",
|
||||
"filetime",
|
||||
"fsevent-sys",
|
||||
"inotify",
|
||||
"kqueue",
|
||||
"libc",
|
||||
"mio",
|
||||
"walkdir",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||
dependencies = [
|
||||
"portable-atomic",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "portable-atomic"
|
||||
version = "1.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.94"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "r-efi"
|
||||
version = "5.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rhai"
|
||||
version = "1.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce4d759a4729a655ddfdbb3ff6e77fb9eadd902dae12319455557796e435d2a6"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"bitflags 2.9.0",
|
||||
"instant",
|
||||
"no-std-compat",
|
||||
"num-traits",
|
||||
"once_cell",
|
||||
"rhai_codegen",
|
||||
"smallvec",
|
||||
"smartstring",
|
||||
"thin-vec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rhai_codegen"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5a11a05ee1ce44058fa3d5961d05194fdbe3ad6b40f904af764d81b86450e6b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rhai_factory"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"notify",
|
||||
"rhai",
|
||||
"thiserror",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.219"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.219"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9"
|
||||
|
||||
[[package]]
|
||||
name = "smartstring"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"static_assertions",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thin-vec"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "144f754d318415ac792f9d69fc87abbbfc043ce2ef041c60f16ad828f638717d"
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tiny-keccak"
|
||||
version = "2.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
|
||||
dependencies = [
|
||||
"crunchy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9"
|
||||
dependencies = [
|
||||
"getrandom 0.3.2",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
|
||||
dependencies = [
|
||||
"same-file",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.14.2+wasi-0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
|
||||
dependencies = [
|
||||
"wit-bindgen-rt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
"rustversion",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||
dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.61.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980"
|
||||
dependencies = [
|
||||
"windows-implement",
|
||||
"windows-interface",
|
||||
"windows-link",
|
||||
"windows-result",
|
||||
"windows-strings",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-implement"
|
||||
version = "0.60.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-interface"
|
||||
version = "0.59.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-strings"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.45.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
|
||||
dependencies = [
|
||||
"windows-targets 0.42.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.59.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.42.2",
|
||||
"windows_aarch64_msvc 0.42.2",
|
||||
"windows_i686_gnu 0.42.2",
|
||||
"windows_i686_msvc 0.42.2",
|
||||
"windows_x86_64_gnu 0.42.2",
|
||||
"windows_x86_64_gnullvm 0.42.2",
|
||||
"windows_x86_64_msvc 0.42.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.48.5",
|
||||
"windows_aarch64_msvc 0.48.5",
|
||||
"windows_i686_gnu 0.48.5",
|
||||
"windows_i686_msvc 0.48.5",
|
||||
"windows_x86_64_gnu 0.48.5",
|
||||
"windows_x86_64_gnullvm 0.48.5",
|
||||
"windows_x86_64_msvc 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.6",
|
||||
"windows_aarch64_msvc 0.52.6",
|
||||
"windows_i686_gnu 0.52.6",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc 0.52.6",
|
||||
"windows_x86_64_gnu 0.52.6",
|
||||
"windows_x86_64_gnullvm 0.52.6",
|
||||
"windows_x86_64_msvc 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-rt"
|
||||
version = "0.39.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
9
rhai_system/examples/base_path_imports/Cargo.toml
Normal file
9
rhai_system/examples/base_path_imports/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "base_path_imports"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
rhai_factory = { path = "../.." }
|
||||
rhai = "1.14.0"
|
||||
chrono = "0.4.24"
|
89
rhai_system/examples/base_path_imports/README.md
Normal file
89
rhai_system/examples/base_path_imports/README.md
Normal file
@@ -0,0 +1,89 @@
|
||||
# Base Path Module Resolver Example
|
||||
|
||||
This example demonstrates the use of the `BasePathModuleResolver` for simplifying Rhai script module imports.
|
||||
|
||||
## Overview
|
||||
|
||||
The `BasePathModuleResolver` provides a more predictable and consistent approach to module resolution by:
|
||||
|
||||
1. Using a single base path for resolving all module imports
|
||||
2. Eliminating the complexity of resolving imports relative to the importing file
|
||||
3. Requiring all import paths to be specified relative to the base path
|
||||
|
||||
## Directory Structure
|
||||
|
||||
The example follows a hierarchical directory structure:
|
||||
|
||||
```
|
||||
base_path_imports/
|
||||
├── components/
|
||||
│ ├── calendar/
|
||||
│ │ └── controller/
|
||||
│ │ └── mock/
|
||||
│ │ └── calendar_model.rhai
|
||||
│ ├── common/
|
||||
│ │ └── utils/
|
||||
│ │ ├── date_utils.rhai
|
||||
│ │ └── string_utils.rhai
|
||||
│ └── website/
|
||||
│ └── controller/
|
||||
│ └── mock/
|
||||
│ └── website_model.rhai
|
||||
├── main.rhai
|
||||
└── src/
|
||||
└── main.rs
|
||||
```
|
||||
|
||||
## Key Components
|
||||
|
||||
### 1. BasePathModuleResolver
|
||||
|
||||
Located in `rhai_factory/src/relative_resolver.rs`, this resolver simplifies module imports by:
|
||||
|
||||
- Taking a base path during initialization
|
||||
- Resolving all module imports relative to this base path
|
||||
- Providing clear logging of the resolution process
|
||||
|
||||
### 2. Utility Modules
|
||||
|
||||
Common utility functions are organized in the `components/common/utils/` directory:
|
||||
|
||||
- `string_utils.rhai`: Basic string manipulation functions
|
||||
- `date_utils.rhai`: Date formatting and validation functions
|
||||
|
||||
### 3. Component-Specific Modules
|
||||
|
||||
Component-specific functionality is organized in dedicated directories:
|
||||
|
||||
- `components/calendar/controller/mock/calendar_model.rhai`: Calendar event creation and validation
|
||||
- `components/website/controller/mock/website_model.rhai`: Website page creation and validation
|
||||
|
||||
### 4. Main Script
|
||||
|
||||
The `main.rhai` script demonstrates importing and using modules from different components.
|
||||
|
||||
## Running the Example
|
||||
|
||||
To run the example:
|
||||
|
||||
```bash
|
||||
cd rhai_factory/examples/base_path_imports
|
||||
cargo run
|
||||
```
|
||||
|
||||
## Key Benefits
|
||||
|
||||
1. **Simplified Imports**: All imports are relative to a single base path
|
||||
2. **Predictable Resolution**: No need to calculate relative paths between files
|
||||
3. **Cleaner Code**: No need for complex "../../../" style paths
|
||||
4. **Better Organization**: Encourages a modular, component-based structure
|
||||
5. **Improved Debugging**: Clear logging of the module resolution process
|
||||
|
||||
## Implementation Details
|
||||
|
||||
The example demonstrates:
|
||||
|
||||
1. Setting up the `BasePathModuleResolver` with a base path
|
||||
2. Importing modules using paths relative to the base path
|
||||
3. Using utility functions from common modules
|
||||
4. Creating component-specific functionality that leverages common utilities
|
@@ -0,0 +1,33 @@
|
||||
// Calendar model functions
|
||||
|
||||
// Import common utility functions
|
||||
import "components/common/utils/date_utils" as date_utils;
|
||||
import "components/common/utils/string_utils" as string_utils;
|
||||
|
||||
// Creates a new calendar event
|
||||
fn create_event(title, description, year, month, day) {
|
||||
let formatted_title = string_utils::to_upper(title);
|
||||
let formatted_date = date_utils::format_date(year, month, day);
|
||||
|
||||
return #{
|
||||
title: formatted_title,
|
||||
description: description,
|
||||
date: formatted_date,
|
||||
is_valid: is_valid_event_date(year, month, day)
|
||||
};
|
||||
}
|
||||
|
||||
// Checks if an event date is valid
|
||||
fn is_valid_event_date(year, month, day) {
|
||||
// Convert all parameters to integers to ensure consistent comparison
|
||||
let y = year.to_int();
|
||||
let m = month.to_int();
|
||||
let d = day.to_int();
|
||||
|
||||
if m < 1 || m > 12 {
|
||||
return false;
|
||||
}
|
||||
|
||||
let max_days = date_utils::days_in_month(y, m);
|
||||
return d >= 1 && d <= max_days;
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
// Simple date utility functions
|
||||
|
||||
// Format a date as YYYY-MM-DD
|
||||
fn format_date(year, month, day) {
|
||||
let month_str = month;
|
||||
let day_str = day;
|
||||
|
||||
return year + "-" + month_str + "-" + day_str;
|
||||
}
|
||||
|
||||
// Check if a year is a leap year
|
||||
fn is_leap_year(year) {
|
||||
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
|
||||
}
|
||||
|
||||
// Get the number of days in a month
|
||||
fn days_in_month(year, month) {
|
||||
if month == 2 {
|
||||
if is_leap_year(year) {
|
||||
return 29;
|
||||
} else {
|
||||
return 28;
|
||||
}
|
||||
}
|
||||
|
||||
if month == 4 || month == 6 || month == 9 || month == 11 {
|
||||
return 30;
|
||||
}
|
||||
|
||||
return 31;
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
// Simple string utility functions
|
||||
|
||||
// Make a string uppercase
|
||||
fn to_upper(s) {
|
||||
return s.to_upper();
|
||||
}
|
||||
|
||||
// Make a string lowercase
|
||||
fn to_lower(s) {
|
||||
return s.to_lower();
|
||||
}
|
||||
|
||||
// Get string length
|
||||
fn length(s) {
|
||||
return s.len();
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
// Website model functions
|
||||
|
||||
// Import common utility functions
|
||||
import "components/common/utils/string_utils" as string_utils;
|
||||
|
||||
// Creates a new website page
|
||||
fn create_page(title, content, slug) {
|
||||
let formatted_title = string_utils::to_upper(title);
|
||||
let slug_length = string_utils::length(slug);
|
||||
|
||||
return #{
|
||||
title: formatted_title,
|
||||
content: content,
|
||||
slug: slug,
|
||||
slug_length: slug_length,
|
||||
is_valid: is_valid_slug(slug)
|
||||
};
|
||||
}
|
||||
|
||||
// Validates a page slug
|
||||
fn is_valid_slug(slug) {
|
||||
// Simple validation - check if it's not empty and has reasonable length
|
||||
if slug.len() == 0 || slug.len() > 100 {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
36
rhai_system/examples/base_path_imports/main.rhai
Normal file
36
rhai_system/examples/base_path_imports/main.rhai
Normal file
@@ -0,0 +1,36 @@
|
||||
// Main script that demonstrates importing modules from different components
|
||||
|
||||
// Import the calendar and website models
|
||||
import "components/calendar/controller/mock/calendar_model" as calendar;
|
||||
import "components/website/controller/mock/website_model" as website;
|
||||
|
||||
// Create a calendar event
|
||||
fn create_calendar_event(title, description, year, month, day) {
|
||||
if !calendar::is_valid_event_date(year, month, day) {
|
||||
return #{ error: "Invalid date" };
|
||||
}
|
||||
|
||||
return calendar::create_event(title, description, year, month, day);
|
||||
}
|
||||
|
||||
// Create a website page
|
||||
fn create_website_page(title, content, slug) {
|
||||
if !website::is_valid_slug(slug) {
|
||||
return #{ error: "Invalid slug" };
|
||||
}
|
||||
|
||||
return website::create_page(title, content, slug);
|
||||
}
|
||||
|
||||
// Example function that combines calendar and website functionality
|
||||
fn demo() {
|
||||
// Create a calendar event
|
||||
let event = create_calendar_event("Team Meeting", "Weekly sync", 2025, 4, 15);
|
||||
print("Calendar event: " + event);
|
||||
|
||||
// Create a website page
|
||||
let page = create_website_page("About Us", "Company information", "about-us");
|
||||
print("Website page: " + page);
|
||||
|
||||
return "Demo completed successfully";
|
||||
}
|
69
rhai_system/examples/base_path_imports/src/main.rs
Normal file
69
rhai_system/examples/base_path_imports/src/main.rs
Normal file
@@ -0,0 +1,69 @@
|
||||
use rhai_factory::{RhaiFactory, BasePathModuleResolver};
|
||||
use std::path::Path;
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Get the base path for our scripts
|
||||
let base_path = Path::new(env!("CARGO_MANIFEST_DIR"));
|
||||
|
||||
println!("Base path: {}", base_path.display());
|
||||
println!("This example demonstrates the BasePathModuleResolver which resolves all imports relative to a base path");
|
||||
|
||||
// Create a new RhaiFactory
|
||||
let factory = RhaiFactory::new();
|
||||
|
||||
// Create an engine with the base path for module resolution
|
||||
let mut engine = factory.create_engine();
|
||||
|
||||
// Set up the BasePathModuleResolver - this is the key component that simplifies module imports
|
||||
// All module imports will be resolved relative to this base path
|
||||
let resolver = BasePathModuleResolver::new_with_path(&base_path);
|
||||
engine.set_module_resolver(resolver);
|
||||
|
||||
// Register basic functions needed by our scripts
|
||||
engine.register_fn("now", || chrono::Utc::now().to_rfc3339());
|
||||
|
||||
// Path to our main script
|
||||
let main_script_path = base_path.join("main.rhai");
|
||||
println!("\nEvaluating script: {}", main_script_path.display());
|
||||
|
||||
// Compile the main script to an AST
|
||||
let ast = engine.compile_file(main_script_path)?;
|
||||
|
||||
// Create a scope for evaluation
|
||||
let mut scope = rhai::Scope::new();
|
||||
|
||||
// Example 1: Call the demo function which demonstrates both calendar and website functionality
|
||||
println!("\nExample 1: Running demo function");
|
||||
let result: String = engine.call_fn(
|
||||
&mut scope,
|
||||
&ast,
|
||||
"demo",
|
||||
()
|
||||
)?;
|
||||
println!("Demo result: {}", result);
|
||||
|
||||
// Example 2: Call the calendar event creation function
|
||||
println!("\nExample 2: Creating a calendar event");
|
||||
let result: rhai::Map = engine.call_fn(
|
||||
&mut scope,
|
||||
&ast,
|
||||
"create_calendar_event",
|
||||
("Conference", "Annual tech conference", 2025, 6, 15)
|
||||
)?;
|
||||
println!("Calendar event: {:#?}", result);
|
||||
|
||||
// Example 3: Call the website page creation function
|
||||
println!("\nExample 3: Creating a website page");
|
||||
let result: rhai::Map = engine.call_fn(
|
||||
&mut scope,
|
||||
&ast,
|
||||
"create_website_page",
|
||||
("Contact", "Our contact information", "contact-us")
|
||||
)?;
|
||||
println!("Website page: {:#?}", result);
|
||||
|
||||
println!("\nThe BasePathModuleResolver successfully resolved all module imports relative to the base path.");
|
||||
println!("This approach simplifies module imports and makes the resolution process more predictable.");
|
||||
|
||||
Ok(())
|
||||
}
|
105
rhai_system/examples/hot_reload/README.md
Normal file
105
rhai_system/examples/hot_reload/README.md
Normal file
@@ -0,0 +1,105 @@
|
||||
# Hot Reload Example
|
||||
|
||||
This example demonstrates hot reloading of multiple Rhai script files using the `rhai_system` crate. It shows how to:
|
||||
|
||||
1. Load and execute multiple script files
|
||||
2. Watch for changes to these files
|
||||
3. Automatically reload scripts when they change
|
||||
4. Call functions across different script files
|
||||
|
||||
## How It Works
|
||||
|
||||
The example uses two main components:
|
||||
|
||||
1. **The System**: Created by `create_hot_reloadable_system` which:
|
||||
- Loads multiple script files (`script.rhai` and `utils.rhai`)
|
||||
- Compiles them into a single AST
|
||||
- Sets up file watchers for each script file
|
||||
- Provides a clean API for calling functions
|
||||
|
||||
2. **Two Threads**:
|
||||
- **Execution Thread**: Continuously executes functions from the scripts
|
||||
- **Modification Thread**: Modifies the script files at specific intervals to demonstrate hot reloading
|
||||
|
||||
## Cross-Script Function Calls
|
||||
|
||||
The example demonstrates how functions in one script can call functions in another:
|
||||
|
||||
- `script.rhai` contains the main functions (`greet`, `advanced_calculation`, `multiply`, `divide`)
|
||||
- `utils.rhai` contains utility functions (`calculate`, `greet_from_utils`)
|
||||
- Functions in `script.rhai` call functions in `utils.rhai`
|
||||
|
||||
This shows how you can organize your code into multiple script files while still maintaining the ability to call functions across files.
|
||||
|
||||
## Running the Example
|
||||
|
||||
To run this example, navigate to the root of the rhai_system project and execute:
|
||||
|
||||
```bash
|
||||
cargo run --example hot_reload
|
||||
```
|
||||
|
||||
## What to Expect
|
||||
|
||||
When you run the example, you'll see:
|
||||
|
||||
1. The system loads both `script.rhai` and `utils.rhai`
|
||||
2. The execution thread calls functions from the scripts every second
|
||||
3. After 5 seconds, the modification thread updates `script.rhai` to add new functions
|
||||
4. The execution thread automatically starts using the updated script
|
||||
5. After another 5 seconds, both script files are modified again
|
||||
6. The system reloads both scripts and the execution thread uses the latest versions
|
||||
|
||||
This demonstrates how the system automatically detects and reloads scripts when they change, without requiring any restart of the application.
|
||||
|
||||
## Key Implementation Details
|
||||
|
||||
### Multiple Script Support
|
||||
|
||||
The system supports multiple script files through:
|
||||
|
||||
```rust
|
||||
// Create a hot reloadable system with multiple script files
|
||||
let script_paths = vec![
|
||||
PathBuf::from("examples/hot_reload/script.rhai"),
|
||||
PathBuf::from("examples/hot_reload/utils.rhai"),
|
||||
];
|
||||
let system = create_hot_reloadable_system(&script_paths, None).unwrap();
|
||||
```
|
||||
|
||||
### File Watching
|
||||
|
||||
The system automatically sets up file watchers for all script files:
|
||||
|
||||
```rust
|
||||
// Start watching for changes to the script files
|
||||
system.watch();
|
||||
```
|
||||
|
||||
### Thread-Safe Usage
|
||||
|
||||
The system is thread-safe and can be used from multiple threads:
|
||||
|
||||
```rust
|
||||
// Clone the system for use in another thread
|
||||
let system_clone = Arc::clone(&system);
|
||||
|
||||
// Create a thread-local clone for the execution thread
|
||||
let thread_system = system_clone.clone_for_thread();
|
||||
```
|
||||
|
||||
## Modifying Scripts at Runtime
|
||||
|
||||
The example includes functions to modify the script files programmatically:
|
||||
|
||||
```rust
|
||||
// Modify the script file with new content
|
||||
modify_script(
|
||||
&script_path,
|
||||
"examples/hot_reload/modified_script.rhai",
|
||||
5,
|
||||
"Modifying the script to add multiply function..."
|
||||
);
|
||||
```
|
||||
|
||||
This simulates a developer editing the script files during development, demonstrating how the system automatically detects and reloads the scripts.
|
21
rhai_system/examples/hot_reload/initial_script.rhai
Normal file
21
rhai_system/examples/hot_reload/initial_script.rhai
Normal file
@@ -0,0 +1,21 @@
|
||||
// This is a simple Rhai script that will be hot reloaded
|
||||
// It contains functions that will be called by the main program
|
||||
// It also uses functions from the utils.rhai script
|
||||
|
||||
// A simple greeting function
|
||||
fn greet(name) {
|
||||
// Use the format_greeting function from utils.rhai
|
||||
let utils_greeting = format_greeting(name);
|
||||
"Hello, " + name + "! This is the original script. " + utils_greeting
|
||||
}
|
||||
|
||||
// A function to calculate the sum of two numbers
|
||||
fn add(a, b) {
|
||||
a + b
|
||||
}
|
||||
|
||||
// A function that uses the calculate function from utils.rhai
|
||||
fn advanced_calculation(x, y) {
|
||||
// Use the calculate function from utils.rhai
|
||||
calculate(x, y) * 2
|
||||
}
|
13
rhai_system/examples/hot_reload/initial_utils.rhai
Normal file
13
rhai_system/examples/hot_reload/initial_utils.rhai
Normal file
@@ -0,0 +1,13 @@
|
||||
// Utility functions for the hot reload example
|
||||
|
||||
// A function to format a greeting message
|
||||
fn format_greeting(name) {
|
||||
"Greetings, " + name + "! (from utils.rhai)"
|
||||
}
|
||||
|
||||
// A function to perform a calculation
|
||||
// Keep it simple to avoid type issues
|
||||
fn calculate(a, b) {
|
||||
// Simple integer arithmetic
|
||||
(a * b) + 10
|
||||
}
|
152
rhai_system/examples/hot_reload/main.rs
Normal file
152
rhai_system/examples/hot_reload/main.rs
Normal file
@@ -0,0 +1,152 @@
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
use std::path::PathBuf;
|
||||
use std::fs::{self, File};
|
||||
use std::io::Write;
|
||||
|
||||
// Import the create_hot_reloadable_system from the library
|
||||
use rhai_system::create_hot_reloadable_system;
|
||||
|
||||
/// Function to modify a script file with content from another file
|
||||
fn modify_script(target_path: &PathBuf, source_path: &str, delay_secs: u64, message: &str) {
|
||||
println!("\n🔄 {}", message);
|
||||
|
||||
// Read the source script content
|
||||
let source_script_path = PathBuf::from(source_path);
|
||||
let source_content = fs::read_to_string(&source_script_path)
|
||||
.expect(&format!("Failed to read source script file: {}", source_path));
|
||||
|
||||
// Write the content to the target file
|
||||
let mut file = File::create(target_path)
|
||||
.expect("Failed to open target script file for writing");
|
||||
file.write_all(source_content.as_bytes())
|
||||
.expect("Failed to write to target script file");
|
||||
|
||||
println!("✅ Script modified successfully!");
|
||||
|
||||
// Wait before the next modification if delay is specified
|
||||
if delay_secs > 0 {
|
||||
thread::sleep(Duration::from_secs(delay_secs));
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Set up the script paths
|
||||
let main_script_path = PathBuf::from("examples/hot_reload/script.rhai");
|
||||
let utils_script_path = PathBuf::from("examples/hot_reload/utils.rhai");
|
||||
println!("Main script path: {:?}", main_script_path);
|
||||
println!("Utils script path: {:?}", utils_script_path);
|
||||
|
||||
// Initialize script.rhai with the content from initial_script.rhai
|
||||
let initial_script_path = PathBuf::from("examples/hot_reload/initial_script.rhai");
|
||||
let initial_content = fs::read_to_string(&initial_script_path)
|
||||
.expect("Failed to read initial script file");
|
||||
|
||||
let mut file = File::create(&main_script_path)
|
||||
.expect("Failed to open script file for writing");
|
||||
file.write_all(initial_content.as_bytes())
|
||||
.expect("Failed to write to script file");
|
||||
|
||||
// Initialize utils.rhai with the content from initial_utils.rhai
|
||||
let initial_utils_path = PathBuf::from("examples/hot_reload/initial_utils.rhai");
|
||||
let initial_utils_content = fs::read_to_string(&initial_utils_path)
|
||||
.expect("Failed to read initial utils file");
|
||||
|
||||
let mut utils_file = File::create(&utils_script_path)
|
||||
.expect("Failed to open utils file for writing");
|
||||
utils_file.write_all(initial_utils_content.as_bytes())
|
||||
.expect("Failed to write to utils file");
|
||||
|
||||
// Create the hot-reloadable system with both script paths
|
||||
// We're passing a slice with both paths and using None for main_script_index
|
||||
// to use the default (first script in the slice)
|
||||
let system = create_hot_reloadable_system(&[main_script_path.clone(), utils_script_path.clone()], None)?;
|
||||
|
||||
// Start a thread that periodically executes the script
|
||||
let execution_thread = thread::spawn(move || {
|
||||
// Every second, call the greet function from the script
|
||||
loop {
|
||||
// Call the greet function
|
||||
match system.call_fn::<String>("greet", ("User",)) {
|
||||
Ok(result) => println!("Execution result: {}", result),
|
||||
Err(err) => println!("Error executing script: {}", err),
|
||||
}
|
||||
|
||||
// Call the add function
|
||||
match system.call_fn::<i32>("add", (40, 2)) {
|
||||
Ok(result) => println!("Add result: {}", result),
|
||||
Err(err) => println!("Error executing add function: {}", err),
|
||||
}
|
||||
|
||||
// Call the advanced_calculation function that uses utils.rhai
|
||||
match system.call_fn::<i64>("advanced_calculation", (5_i64, 7_i64)) {
|
||||
Ok(result) => println!("Advanced calculation result: {}", result),
|
||||
Err(err) => println!("Error executing advanced_calculation function: {}", err),
|
||||
}
|
||||
|
||||
// Try to call the multiply function, catch any errors
|
||||
match system.call_fn::<i32>("multiply", (40, 2)) {
|
||||
Ok(result) => println!("Multiply result: {}", result),
|
||||
Err(err) => {
|
||||
if err.to_string().contains("function not found") {
|
||||
println!("Multiply function not available yet");
|
||||
} else {
|
||||
println!("Error executing multiply function: {}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Try to call the divide function, catch any errors
|
||||
match system.call_fn::<i32>("divide", (40, 2)) {
|
||||
Ok(result) => println!("Divide result: {}", result),
|
||||
Err(err) => {
|
||||
if err.to_string().contains("function not found") {
|
||||
println!("Divide function not available yet");
|
||||
} else {
|
||||
println!("Error executing divide function: {}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Wait before the next execution
|
||||
thread::sleep(Duration::from_secs(1));
|
||||
}
|
||||
});
|
||||
|
||||
// Start a thread to modify the script files at intervals
|
||||
let main_script_path_clone = main_script_path.clone();
|
||||
let utils_script_path_clone = utils_script_path.clone();
|
||||
thread::spawn(move || {
|
||||
// Wait 5 seconds before first modification
|
||||
thread::sleep(Duration::from_secs(5));
|
||||
|
||||
// First modification - add multiply function
|
||||
modify_script(
|
||||
&main_script_path_clone,
|
||||
"examples/hot_reload/modified_script.rhai",
|
||||
10,
|
||||
"Modifying the script to add multiply function..."
|
||||
);
|
||||
|
||||
// Second modification - add divide function
|
||||
modify_script(
|
||||
&main_script_path_clone,
|
||||
"examples/hot_reload/second_modified_script.rhai",
|
||||
0,
|
||||
"Modifying the script again to add divide function..."
|
||||
);
|
||||
|
||||
// Third modification - modify utils.rhai
|
||||
modify_script(
|
||||
&utils_script_path_clone,
|
||||
"examples/hot_reload/modified_utils.rhai",
|
||||
0,
|
||||
"Modifying the utils script..."
|
||||
);
|
||||
});
|
||||
|
||||
// Wait for the execution thread to finish (it won't, but this keeps the main thread alive)
|
||||
execution_thread.join().unwrap();
|
||||
|
||||
Ok(())
|
||||
}
|
22
rhai_system/examples/hot_reload/modified_script.rhai
Normal file
22
rhai_system/examples/hot_reload/modified_script.rhai
Normal file
@@ -0,0 +1,22 @@
|
||||
// This is a modified script
|
||||
// The AST will be replaced with this new version
|
||||
|
||||
// A simple greeting function with modified message
|
||||
fn greet(name) {
|
||||
"Hello, " + name + "! This is the MODIFIED script! Hot reloading works!"
|
||||
}
|
||||
|
||||
// A function to calculate the sum of two numbers
|
||||
fn add(a, b) {
|
||||
a + b
|
||||
}
|
||||
|
||||
// A new function added during hot reload
|
||||
fn multiply(a, b) {
|
||||
a * b
|
||||
}
|
||||
|
||||
// A new function added during hot reload
|
||||
fn divide(a, b) {
|
||||
a / b
|
||||
}
|
18
rhai_system/examples/hot_reload/modified_utils.rhai
Normal file
18
rhai_system/examples/hot_reload/modified_utils.rhai
Normal file
@@ -0,0 +1,18 @@
|
||||
// Utility functions for the hot reload example - MODIFIED VERSION
|
||||
|
||||
// A function to format a greeting message
|
||||
fn format_greeting(name) {
|
||||
"ENHANCED Greetings, " + name + "! (from modified utils.rhai)"
|
||||
}
|
||||
|
||||
// A function to perform a calculation
|
||||
// Keep it simple to avoid type issues
|
||||
fn calculate(a, b) {
|
||||
// Enhanced calculation with additional operations
|
||||
(a * b * 2) + 20
|
||||
}
|
||||
|
||||
// A new utility function
|
||||
fn format_message(text) {
|
||||
"*** " + text + " ***"
|
||||
}
|
22
rhai_system/examples/hot_reload/script.rhai
Normal file
22
rhai_system/examples/hot_reload/script.rhai
Normal file
@@ -0,0 +1,22 @@
|
||||
// This is a completely overwritten script
|
||||
// The AST will be replaced with this new version
|
||||
|
||||
// A simple greeting function with modified message
|
||||
fn greet(name) {
|
||||
"Hello, " + name + "! This is the COMPLETELY OVERWRITTEN script!"
|
||||
}
|
||||
|
||||
// A function to calculate the sum of two numbers
|
||||
fn add(a, b) {
|
||||
a + b
|
||||
}
|
||||
|
||||
// A new function added during hot reload
|
||||
fn multiply(a, b) {
|
||||
a * b
|
||||
}
|
||||
|
||||
// Another new function added during hot reload
|
||||
fn divide(a, b) {
|
||||
a / b
|
||||
}
|
22
rhai_system/examples/hot_reload/second_modified_script.rhai
Normal file
22
rhai_system/examples/hot_reload/second_modified_script.rhai
Normal file
@@ -0,0 +1,22 @@
|
||||
// This is a completely overwritten script
|
||||
// The AST will be replaced with this new version
|
||||
|
||||
// A simple greeting function with modified message
|
||||
fn greet(name) {
|
||||
"Hello, " + name + "! This is the COMPLETELY OVERWRITTEN script!"
|
||||
}
|
||||
|
||||
// A function to calculate the sum of two numbers
|
||||
fn add(a, b) {
|
||||
a + b
|
||||
}
|
||||
|
||||
// A new function added during hot reload
|
||||
fn multiply(a, b) {
|
||||
a * b
|
||||
}
|
||||
|
||||
// Another new function added during hot reload
|
||||
fn divide(a, b) {
|
||||
a / b
|
||||
}
|
18
rhai_system/examples/hot_reload/utils.rhai
Normal file
18
rhai_system/examples/hot_reload/utils.rhai
Normal file
@@ -0,0 +1,18 @@
|
||||
// Utility functions for the hot reload example - MODIFIED VERSION
|
||||
|
||||
// A function to format a greeting message
|
||||
fn format_greeting(name) {
|
||||
"ENHANCED Greetings, " + name + "! (from modified utils.rhai)"
|
||||
}
|
||||
|
||||
// A function to perform a calculation
|
||||
// Keep it simple to avoid type issues
|
||||
fn calculate(a, b) {
|
||||
// Enhanced calculation with additional operations
|
||||
(a * b * 2) + 20
|
||||
}
|
||||
|
||||
// A new utility function
|
||||
fn format_message(text) {
|
||||
"*** " + text + " ***"
|
||||
}
|
10
rhai_system/examples/relative_imports/Cargo.toml
Normal file
10
rhai_system/examples/relative_imports/Cargo.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "relative_imports_example"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
rhai_factory = { path = "../.." }
|
||||
rhai = { version = "1.21.0", features = ["serde"] }
|
||||
log = "0.4"
|
||||
env_logger = "0.10"
|
@@ -0,0 +1,67 @@
|
||||
// Calendar controller module
|
||||
// This demonstrates importing from a different directory level
|
||||
|
||||
// Import the common utils using a relative path
|
||||
import "../../../utils/common" as common;
|
||||
|
||||
/// Returns data for a single calendar event
|
||||
fn get_event_data() {
|
||||
let event = #{
|
||||
id: 1,
|
||||
title: "Team Meeting",
|
||||
date: "2025-04-15",
|
||||
time: "10:00 AM",
|
||||
location: "Conference Room A",
|
||||
description: "Weekly team sync meeting"
|
||||
};
|
||||
|
||||
// Use the common utils to check if the date is in the future
|
||||
if common::is_future_date(event.date) {
|
||||
event.status = "Upcoming";
|
||||
} else {
|
||||
event.status = "Past";
|
||||
}
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
/// Returns a list of all calendar events
|
||||
fn get_all_events() {
|
||||
let events = [
|
||||
#{
|
||||
id: 1,
|
||||
title: "Team Meeting",
|
||||
date: "2025-04-15",
|
||||
time: "10:00 AM",
|
||||
location: "Conference Room A",
|
||||
description: "Weekly team sync meeting"
|
||||
},
|
||||
#{
|
||||
id: 2,
|
||||
title: "Project Review",
|
||||
date: "2025-04-17",
|
||||
time: "2:00 PM",
|
||||
location: "Meeting Room B",
|
||||
description: "Review project progress and next steps"
|
||||
},
|
||||
#{
|
||||
id: 3,
|
||||
title: "Client Presentation",
|
||||
date: "2025-04-20",
|
||||
time: "11:30 AM",
|
||||
location: "Main Auditorium",
|
||||
description: "Present new features to the client"
|
||||
}
|
||||
];
|
||||
|
||||
// Update the status of each event using the common utils
|
||||
for event in events {
|
||||
if common::is_future_date(event.date) {
|
||||
event.status = "Upcoming";
|
||||
} else {
|
||||
event.status = "Past";
|
||||
}
|
||||
}
|
||||
|
||||
return events;
|
||||
}
|
23
rhai_system/examples/relative_imports/scripts/main.rhai
Normal file
23
rhai_system/examples/relative_imports/scripts/main.rhai
Normal file
@@ -0,0 +1,23 @@
|
||||
// Import modules using relative paths
|
||||
import "utils/common" as common;
|
||||
import "components/calendar/controller/calendar" as calendar;
|
||||
|
||||
// Main function that demonstrates the relative imports
|
||||
fn main() {
|
||||
// Print a message using the common utils
|
||||
let greeting = common::get_greeting("User");
|
||||
print(greeting);
|
||||
|
||||
// Get calendar events using the calendar controller
|
||||
let events = calendar::get_all_events();
|
||||
|
||||
// Print the events using the common utils format function
|
||||
print("\nCalendar Events:");
|
||||
for event in events {
|
||||
let formatted = common::format_event(event);
|
||||
print(formatted);
|
||||
}
|
||||
|
||||
// Return a success message
|
||||
"All imports worked correctly!"
|
||||
}
|
@@ -0,0 +1,18 @@
|
||||
// Common utility functions used across the application
|
||||
|
||||
/// Returns a greeting message for the given name
|
||||
fn get_greeting(name) {
|
||||
return `Hello, ${name}! Welcome to the Rhai relative imports example.`;
|
||||
}
|
||||
|
||||
/// Formats an event object into a readable string
|
||||
fn format_event(event) {
|
||||
return `- ${event.title} on ${event.date} at ${event.time} (${event.location})`;
|
||||
}
|
||||
|
||||
/// Utility function to check if a date is in the future
|
||||
fn is_future_date(date_str) {
|
||||
// Simple implementation for the example
|
||||
// In a real application, you would parse the date and compare with current date
|
||||
return true;
|
||||
}
|
58
rhai_system/examples/relative_imports/src/main.rs
Normal file
58
rhai_system/examples/relative_imports/src/main.rs
Normal file
@@ -0,0 +1,58 @@
|
||||
use std::path::Path;
|
||||
use rhai_factory::{RhaiFactory, RelativeFileModuleResolver};
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Initialize the logger with debug level
|
||||
std::env::set_var("RUST_LOG", "debug");
|
||||
env_logger::init();
|
||||
|
||||
println!("Starting Relative Imports Example...");
|
||||
|
||||
// Get the paths to our script files
|
||||
let scripts_dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("scripts");
|
||||
let main_script_path = scripts_dir.join("main.rhai");
|
||||
|
||||
println!("Scripts directory: {:?}", scripts_dir);
|
||||
println!("Main script path: {:?}", main_script_path);
|
||||
|
||||
// Create a RhaiFactory instance
|
||||
let factory = RhaiFactory::new();
|
||||
|
||||
// Method 1: Using the RhaiFactory which now uses RelativeFileModuleResolver by default
|
||||
println!("\nMethod 1: Using RhaiFactory with RelativeFileModuleResolver (default)");
|
||||
let ast = factory.compile_modules(&[&main_script_path], Some(&scripts_dir))?;
|
||||
let engine = factory.create_engine();
|
||||
|
||||
// Evaluate the main script
|
||||
let result: String = engine.eval_ast(&ast)?;
|
||||
println!("Result: {}", result);
|
||||
|
||||
// Method 2: Creating an engine manually with RelativeFileModuleResolver
|
||||
println!("\nMethod 2: Creating an engine manually with RelativeFileModuleResolver");
|
||||
let mut manual_engine = rhai::Engine::new();
|
||||
manual_engine.set_module_resolver(RelativeFileModuleResolver::new_with_path(&scripts_dir));
|
||||
|
||||
// Evaluate the main script directly
|
||||
let result: String = manual_engine.eval_file(main_script_path)?;
|
||||
println!("Result: {}", result);
|
||||
|
||||
// Demonstrate hot reloading capability
|
||||
println!("\nDemonstrating hot reload capability:");
|
||||
println!("1. The engine will watch for changes to the script files");
|
||||
println!("2. If you modify any of the script files, the changes will be detected");
|
||||
println!("3. The engine will automatically reload the modified scripts");
|
||||
|
||||
// Create a hot reloadable engine
|
||||
let (hot_engine, hot_ast, hot_reload_handle) =
|
||||
factory.create_hot_reloadable_rhai_engine(&[&main_script_path], Some(&scripts_dir))?;
|
||||
|
||||
// Evaluate the main script with hot reloading
|
||||
let result: String = hot_engine.eval_ast(&hot_ast.read().unwrap())?;
|
||||
println!("Hot reload result: {}", result);
|
||||
|
||||
println!("\nExample completed successfully!");
|
||||
println!("This example demonstrates how the RelativeFileModuleResolver makes imports work");
|
||||
println!("relative to the file importing them, rather than just relative to a fixed base path.");
|
||||
|
||||
Ok(())
|
||||
}
|
Reference in New Issue
Block a user