diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8ff9f4a..b955251 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,12 +17,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - with: - path: rustscript-bevy-gameplay - - uses: actions/checkout@v4 - with: - repository: rustscript-lang/rustscript - path: rustscript - uses: dtolnay/rust-toolchain@stable with: components: rustfmt, clippy @@ -40,14 +34,10 @@ jobs: libxrandr-dev \ pkg-config - name: Format check - working-directory: rustscript-bevy-gameplay run: cargo fmt --all -- --check - name: Clippy - working-directory: rustscript-bevy-gameplay - run: cargo clippy --all-targets + run: cargo clippy --all-targets --all-features -- -D warnings - name: Tests (skip perf) - working-directory: rustscript-bevy-gameplay run: cargo test --tests - name: Example run - working-directory: rustscript-bevy-gameplay run: cargo run --example combat diff --git a/Cargo.lock b/Cargo.lock index 532dbfa..8827cd2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -95,9 +95,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" dependencies = [ "memchr", ] @@ -115,7 +115,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f2a1bb052857d5dd49572219344a7332b31b76405648eabac5bc68978251bcd" dependencies = [ "android-properties", - "bitflags 2.13.0", + "bitflags 2.13.2", "cc", "jni", "libc", @@ -124,7 +124,7 @@ dependencies = [ "ndk-context", "ndk-sys", "num_enum", - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] @@ -141,18 +141,18 @@ checksum = "84521a3cf562bc62942e294181d9eef17eb38ceb8c68677bc49f144e4c3d4f8d" [[package]] name = "android_system_properties" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +checksum = "ae221649c9976a6f6c56ae1facf410f3ddb33cc661c4b7b61020a912d4237fbc" dependencies = [ "libc", ] [[package]] name = "anyhow" -version = "1.0.103" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" [[package]] name = "approx" @@ -185,16 +185,10 @@ dependencies = [ "objc2-foundation 0.3.2", "parking_lot", "percent-encoding", - "windows-sys 0.59.0", + "windows-sys 0.60.2", "x11rb", ] -[[package]] -name = "arrayref" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" - [[package]] name = "arrayvec" version = "0.7.8" @@ -224,7 +218,7 @@ checksum = "f548ad2c4031f2902e3edc1f29c29e835829437de49562d8eb5dc5584d3a1043" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -289,7 +283,7 @@ dependencies = [ "futures-lite", "parking", "polling", - "rustix 1.1.4", + "rustix 1.1.5", "slab", "windows-sys 0.61.2", ] @@ -393,7 +387,7 @@ dependencies = [ "ctrlc", "downcast-rs 2.0.2", "log", - "thiserror 2.0.18", + "thiserror 2.0.20", "variadics_please", "wasm-bindgen", "web-sys", @@ -420,7 +414,7 @@ dependencies = [ "bevy_reflect", "bevy_tasks", "bevy_utils", - "bitflags 2.13.0", + "bitflags 2.13.2", "blake3", "crossbeam-channel", "derive_more", @@ -434,7 +428,7 @@ dependencies = [ "ron", "serde", "stackfuture", - "thiserror 2.0.18", + "thiserror 2.0.20", "tracing", "uuid", "wasm-bindgen", @@ -451,7 +445,7 @@ dependencies = [ "bevy_macro_utils", "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -476,7 +470,7 @@ dependencies = [ "downcast-rs 2.0.2", "serde", "smallvec", - "thiserror 2.0.18", + "thiserror 2.0.20", "wgpu-types", ] @@ -492,7 +486,7 @@ dependencies = [ "derive_more", "encase", "serde", - "thiserror 2.0.18", + "thiserror 2.0.20", "wgpu-types", ] @@ -518,11 +512,11 @@ dependencies = [ "bevy_transform", "bevy_utils", "bevy_window", - "bitflags 2.13.0", + "bitflags 2.13.2", "nonmax", "radsort", "smallvec", - "thiserror 2.0.18", + "thiserror 2.0.20", "tracing", ] @@ -534,7 +528,7 @@ checksum = "318ee0532c3da93749859d18f89a889c638fbc56aabac4d866583df7b951d103" dependencies = [ "bevy_macro_utils", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -567,7 +561,7 @@ dependencies = [ "bevy_reflect", "bevy_tasks", "bevy_utils", - "bitflags 2.13.0", + "bitflags 2.13.2", "bumpalo", "concurrent-queue", "derive_more", @@ -578,7 +572,7 @@ dependencies = [ "serde", "slotmap", "smallvec", - "thiserror 2.0.18", + "thiserror 2.0.20", "variadics_please", ] @@ -591,7 +585,7 @@ dependencies = [ "bevy_macro_utils", "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -678,7 +672,7 @@ checksum = "6960ea308d7e94adcac5c712553ff86614bba6b663511f3f3812f6bec028b51e" dependencies = [ "bevy_macro_utils", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -719,7 +713,7 @@ dependencies = [ "bevy_platform", "bevy_reflect", "bevy_utils", - "bitflags 2.13.0", + "bitflags 2.13.2", "bytemuck", "futures-lite", "guillotiere", @@ -728,7 +722,7 @@ dependencies = [ "rectangle-pack", "ruzstd", "serde", - "thiserror 2.0.18", + "thiserror 2.0.20", "tracing", "wgpu-types", ] @@ -747,7 +741,7 @@ dependencies = [ "derive_more", "log", "smol_str", - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] @@ -763,7 +757,7 @@ dependencies = [ "bevy_reflect", "bevy_window", "log", - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] @@ -834,7 +828,7 @@ checksum = "3b147843b81a7ec548876ff97fa7bfdc646ef2567cb465566259237b39664438" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", "toml_edit 0.23.10+spec-1.0.0", ] @@ -854,7 +848,7 @@ dependencies = [ "rand", "rand_distr", "serde", - "thiserror 2.0.18", + "thiserror 2.0.20", "variadics_please", ] @@ -872,11 +866,11 @@ dependencies = [ "bevy_platform", "bevy_reflect", "bevy_transform", - "bitflags 2.13.0", + "bitflags 2.13.2", "bytemuck", "derive_more", "hexasphere", - "thiserror 2.0.18", + "thiserror 2.0.20", "tracing", "wgpu-types", ] @@ -953,7 +947,7 @@ dependencies = [ "serde", "smallvec", "smol_str", - "thiserror 2.0.18", + "thiserror 2.0.20", "uuid", "variadics_please", "wgpu-types", @@ -969,7 +963,7 @@ dependencies = [ "indexmap", "proc-macro2", "quote", - "syn", + "syn 2.0.119", "uuid", ] @@ -1000,7 +994,7 @@ dependencies = [ "bevy_transform", "bevy_utils", "bevy_window", - "bitflags 2.13.0", + "bitflags 2.13.2", "bytemuck", "derive_more", "downcast-rs 2.0.2", @@ -1015,7 +1009,7 @@ dependencies = [ "offset-allocator", "send_wrapper", "smallvec", - "thiserror 2.0.18", + "thiserror 2.0.20", "tracing", "variadics_please", "wasm-bindgen", @@ -1032,7 +1026,7 @@ dependencies = [ "bevy_macro_utils", "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -1047,7 +1041,7 @@ dependencies = [ "naga", "naga_oil", "serde", - "thiserror 2.0.18", + "thiserror 2.0.20", "tracing", "wgpu-types", ] @@ -1100,7 +1094,7 @@ dependencies = [ "bevy_text", "bevy_transform", "bevy_utils", - "bitflags 2.13.0", + "bitflags 2.13.2", "bytemuck", "derive_more", "fixedbitset", @@ -1132,7 +1126,7 @@ checksum = "73d32f90f9cfcef5a44401db7ce206770daaa1707b0fb95eb7a96a6933f54f1b" dependencies = [ "bevy_macro_utils", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -1174,7 +1168,7 @@ dependencies = [ "serde", "smallvec", "sys-locale", - "thiserror 2.0.18", + "thiserror 2.0.20", "tracing", "wgpu-types", ] @@ -1209,7 +1203,7 @@ dependencies = [ "bevy_utils", "derive_more", "serde", - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] @@ -1240,7 +1234,7 @@ dependencies = [ "derive_more", "smallvec", "taffy", - "thiserror 2.0.18", + "thiserror 2.0.20", "tracing", ] @@ -1362,20 +1356,19 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.13.0" +version = "2.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" +checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06" dependencies = [ "serde_core", ] [[package]] name = "blake3" -version = "1.8.5" +version = "1.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0aa83c34e62843d924f905e0f5c866eb1dd6545fc4d719e803d9ba6030371fce" +checksum = "6d9e454fc11f76977dc803893aff6304ed33d6a26efae8696573bea74baa27ae" dependencies = [ - "arrayref", "arrayvec", "cc", "cfg-if", @@ -1409,9 +1402,9 @@ dependencies = [ [[package]] name = "blocking" -version = "1.6.2" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21" +checksum = "a70e4329df6cb94385eed412ec92375c3cdd8a6e502493d1229b6414e4036dfa" dependencies = [ "async-channel", "async-task", @@ -1431,22 +1424,22 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.25.0" +version = "1.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" +checksum = "95832e849adfb21180ccb6826a99da14e5d266ae5c2e668e1602cf234f153797" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.10.2" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" +checksum = "6a1f896587b6f2c069c73d2f0913e2d590c3990285cd2f0b6aa02b786b4c679c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", ] [[package]] @@ -1473,7 +1466,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", "log", "polling", "rustix 0.38.44", @@ -1483,9 +1476,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.66" +version = "1.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5d6cac793997bd970000024b2934968efe83b382de4fdcf4fcb46b6ee4ad996" +checksum = "a3eb0f42d6c360dc3f8a821f6bf2fdea7f72bfd36b3076eb0e6d1e9e0752fff4" dependencies = [ "find-msvc-tools", "jobserver", @@ -1495,15 +1488,15 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600" [[package]] name = "cfg_aliases" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" [[package]] name = "clipboard-win" @@ -1527,9 +1520,9 @@ dependencies = [ [[package]] name = "combine" -version = "4.6.7" +version = "4.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +checksum = "cfc320937d09e6de266b31b9afb480f197d7a861be86be7cb2ea7e5d1bfffc5e" dependencies = [ "bytes", "memchr", @@ -1563,9 +1556,9 @@ checksum = "32b13ea120a812beba79e34316b3942a857c86ec1593cb34f27bb28272ce2cca" [[package]] name = "const_panic" -version = "0.2.15" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e262cdaac42494e3ae34c43969f9cdeb7da178bdb4b66fa6a1ea2edb4c8ae652" +checksum = "9603f79528ece8163c496f8932121cb36cfe46259e9c907bb3d8205139d7caa3" dependencies = [ "typewit", ] @@ -1656,7 +1649,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", "core-foundation 0.10.1", "libc", ] @@ -1676,7 +1669,7 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4cadaea21e24c49c0c82116f2b465ae6a49d63c90e428b0f8d9ae1f638ac91f" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", "fontdb", "harfrust", "linebender_resource_handle", @@ -1696,9 +1689,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +checksum = "5ca28b0ae3115b884660db4118d803791fd6756b6e88f39c0f3f7859060d7566" dependencies = [ "libc", ] @@ -1871,9 +1864,9 @@ checksum = "4a1a001a9dc4557d9e2be324bc932621c0aa9bf33b74dfefa2338f0bf8913329" [[package]] name = "crc32fast" -version = "1.5.0" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +checksum = "01a7799fd6b852db0e61728dde9a204c423b44d689dbd432522543614b490e78" dependencies = [ "cfg-if", ] @@ -1886,27 +1879,27 @@ checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" [[package]] name = "crossbeam-channel" -version = "0.5.16" +version = "0.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d85363c37faeca707aef026efa9f3b34d077bce547e48f770770625c6013679e" +checksum = "98b0cc327b5bc766e7fda9c9260cc0fa81b43a8e240440422dff70788e3f9ef1" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-queue" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "803d13fb3b09d88be9f4dbc29062c66b19bf7170867ceb746d2a8689bf6c7a26" +checksum = "03e8bd762f7479489c70ed6c768ddca99d7296857de437a68dcb2a94365b3fae" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.22" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" +checksum = "a31eee39dddec8330830986fcd7625edb5a24ec90ea038215273bbc3adb08ac6" [[package]] name = "crunchy" @@ -1933,9 +1926,9 @@ checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f" [[package]] name = "data-encoding" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8" +checksum = "4583a4551df46e2792f82ceeac45e850d2e2d5debba0b91f102385cda5b11f06" [[package]] name = "derive_more" @@ -1956,7 +1949,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn", + "syn 2.0.119", "unicode-xid", ] @@ -1978,7 +1971,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", "block2 0.6.2", "libc", "objc2 0.6.4", @@ -1986,20 +1979,20 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" +checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", ] [[package]] name = "disqualified" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9c272297e804878a2a4b707cfcfc6d2328b5bb936944613b4fdf2b9269afdfd" +checksum = "e90a5dd66beeca277ae954f8055b02a712792b6b6b43f2bc2f92b0b7d8291614" [[package]] name = "dlib" @@ -2054,7 +2047,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a9b567d356674e9a5121ed3fedfb0a7c31e059fe71f6972b691bcd0bfc284e3" dependencies = [ "ahash", - "bitflags 2.13.0", + "bitflags 2.13.2", "emath", "epaint", "log", @@ -2066,9 +2059,9 @@ dependencies = [ [[package]] name = "either" -version = "1.16.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" +checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34" [[package]] name = "emath" @@ -2081,33 +2074,33 @@ dependencies = [ [[package]] name = "encase" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e3e0ff2ee0b7aa97428308dd9e1e42369cb22f5fb8dc1c55546637443a60f1e" +checksum = "b1acbc46b960480c4959213714511e22f9a2e0d361520693bcf5057b5924f53e" dependencies = [ "const_panic", "encase_derive", - "thiserror 2.0.18", + "thiserror 2.0.20", ] [[package]] name = "encase_derive" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4d90c5d7d527c6cb8a3b114efd26a6304d9ab772656e73d8f4e32b1f3d601a2" +checksum = "1e30d38c47336a0afbdfde297b442944041cf6dccbb1a79eceea16abfb27a92a" dependencies = [ "encase_derive_impl", ] [[package]] name = "encase_derive_impl" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8bad72d8308f7a382de2391ec978ddd736e0103846b965d7e2a63a75768af30" +checksum = "495d24abe406f090f2ba8fc362ecaa8a001e192522aa75eae7b144163c3235ff" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -2163,9 +2156,9 @@ dependencies = [ [[package]] name = "error-code" -version = "3.3.2" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59" +checksum = "0b5343afd4a8365a643ac588dab4cf234a190c7f6c88c9f6dd6ffe00837661b7" [[package]] name = "euclid" @@ -2178,11 +2171,10 @@ dependencies = [ [[package]] name = "event-listener" -version = "5.4.1" +version = "5.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" +checksum = "5a23add41df1562121a9393cb065eab5146a1242410f23a644851e90cfd669d2" dependencies = [ - "concurrent-queue", "parking", "pin-project-lite", ] @@ -2199,9 +2191,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" +checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" [[package]] name = "fax" @@ -2220,9 +2212,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.9" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" +checksum = "3e0f1c7c3a72c66fd80abe965175f7523475c0489a87d3ff9d6e8c87d87a9d2d" [[package]] name = "fixedbitset" @@ -2232,12 +2224,13 @@ checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" [[package]] name = "flate2" -version = "1.1.9" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +checksum = "6e634e2e0ebac1ee034020da1ca582e17ffe4e0f5e985823721e168928136dcb" dependencies = [ "crc32fast", - "miniz_oxide", + "miniz_oxide 0.9.1", + "zlib-rs", ] [[package]] @@ -2269,9 +2262,9 @@ dependencies = [ [[package]] name = "font-types" -version = "0.11.3" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b38ad915f6dadd993ced50848a8291a543bd41ca62bc10740d5e64e2ab4cfd7" +checksum = "b8eb065f3251655b3c90e22e5e363f310fc5332fb3402e37bbc94752283248f6" dependencies = [ "bytemuck", ] @@ -2311,13 +2304,13 @@ dependencies = [ [[package]] name = "foreign-types-macros" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +checksum = "ea5190182e6915eb873ddbc16e23b711b6eb1f9c00a0d0a3a91b5f6228475225" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", ] [[package]] @@ -2337,24 +2330,24 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" dependencies = [ "futures-core", ] [[package]] name = "futures-core" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" [[package]] name = "futures-io" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" [[package]] name = "futures-lite" @@ -2371,26 +2364,26 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", ] [[package]] name = "futures-task" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" [[package]] name = "futures-util" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" dependencies = [ "futures-core", "futures-macro", @@ -2405,7 +2398,7 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8" dependencies = [ - "rustix 1.1.4", + "rustix 1.1.5", "windows-link 0.2.1", ] @@ -2465,7 +2458,7 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45cf04b2726f02df5508c6de726acdc90cdf97ac771a9a0ffd8ba10a6e696bf9" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", "gpu-alloc-types", ] @@ -2475,7 +2468,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2bbed164dd10ed526c2e4fe3e721ca4a71c61730e5aafac6844b417b3227058" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", ] [[package]] @@ -2496,7 +2489,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b89c83349105e3732062a895becfc71a8f921bb71ecbbdd8ff99263e3b53a0ca" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", "gpu-descriptor-types", "hashbrown 0.15.5", ] @@ -2507,7 +2500,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", ] [[package]] @@ -2544,7 +2537,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0caaee032384c10dd597af4579c67dee16650d862a9ccbe1233ff1a379abc07" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", "bytemuck", "core_maths", "read-fonts 0.36.0", @@ -2606,9 +2599,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" +checksum = "e17592d60ebacc7d5e169f4663c5f84f9161cc90328abcfe8456f41e4dfcb284" [[package]] name = "hexasphere" @@ -2629,9 +2622,9 @@ checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" [[package]] name = "icu_collections" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" +checksum = "fa68d21081c4a05d5a901a1c62add574c77048b6a1c67be3b50ce0b60d4ca513" dependencies = [ "displaydoc", "potential_utf", @@ -2643,9 +2636,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" +checksum = "d56e28588da92eee5c3201a6eff33fabdd49b62269c8938d4ff050ce4d900deb" dependencies = [ "displaydoc", "litemap", @@ -2656,9 +2649,9 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" +checksum = "12f9cf5f235641ed274641dd81c3f28d870e276763d0797aeeab72317b1c646f" dependencies = [ "icu_collections", "icu_normalizer_data", @@ -2670,16 +2663,17 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" +checksum = "1563da1ed3e0b3bf3d74c9b85917ac9c56464d2f57242270c09c9e752f8021a0" [[package]] name = "icu_properties" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" +checksum = "7e7ca276ad3145661a65914e6daf131ca5120cd3dcee8f8f3214b8875184a148" dependencies = [ + "displaydoc", "icu_collections", "icu_locale_core", "icu_properties_data", @@ -2690,15 +2684,15 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" +checksum = "e590f038c1464a96894fd6d10127e90a8be4509f56ff7ecef851b15cee0b7caa" [[package]] name = "icu_provider" -version = "2.2.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" +checksum = "d27bbb9d3abbefac45d55f647c9de1d44aafcd1186eb91879afef17c396c3e73" dependencies = [ "displaydoc", "icu_locale_core", @@ -2746,9 +2740,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.14.0" +version = "2.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" dependencies = [ "equivalent", "hashbrown 0.17.1", @@ -2790,7 +2784,7 @@ dependencies = [ "jni-sys 0.4.1", "log", "simd_cesu8", - "thiserror 2.0.18", + "thiserror 2.0.20", "walkdir", "windows-link 0.2.1", ] @@ -2805,7 +2799,7 @@ dependencies = [ "quote", "rustc_version", "simd_cesu8", - "syn", + "syn 2.0.119", ] [[package]] @@ -2833,7 +2827,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" dependencies = [ "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -2848,9 +2842,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.103" +version = "0.3.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" +checksum = "ce57d20d1ea864ce2ac172ab472d409214f4fd359f0b2a2775abdf522e2af99e" dependencies = [ "cfg-if", "futures-util", @@ -2865,9 +2859,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.186" +version = "0.2.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" [[package]] name = "libloading" @@ -2887,14 +2881,14 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libredox" -version = "0.1.18" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c943259e342f1e06ff2da7a83eabdfe7f92ce10262688dbf1895ff0b3e6e4652" +checksum = "6480ccc157a1389bb2e4891b24751b0f798ba640d22386f23143fbcc89da195a" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", "libc", "plain", - "redox_syscall 0.9.0", + "redox_syscall 0.9.4", ] [[package]] @@ -2917,9 +2911,9 @@ checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] name = "litemap" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" +checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae" [[package]] name = "litrs" @@ -2938,9 +2932,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.33" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" [[package]] name = "mach2" @@ -2990,7 +2984,7 @@ version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00c15a6f673ff72ddcc22394663290f870fb224c1bfce55734a75c414150e605" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", "block", "core-graphics-types 0.2.0", "foreign-types", @@ -3009,6 +3003,16 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "miniz_oxide" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63fbc4a50860e98e7b2aa7804ded1db5cbc3aff9193adaff57a6931bf7c4b4c" +dependencies = [ + "adler2", + "simd-adler32", +] + [[package]] name = "moxcms" version = "0.8.1" @@ -3027,7 +3031,7 @@ checksum = "066cf25f0e8b11ee0df221219010f213ad429855f57c494f995590c861a9a7d8" dependencies = [ "arrayvec", "bit-set", - "bitflags 2.13.0", + "bitflags 2.13.2", "cfg-if", "cfg_aliases", "codespan-reporting", @@ -3042,7 +3046,7 @@ dependencies = [ "pp-rs", "rustc-hash 1.1.0", "spirv", - "thiserror 2.0.18", + "thiserror 2.0.20", "unicode-ident", ] @@ -3058,7 +3062,7 @@ dependencies = [ "naga", "regex", "rustc-hash 1.1.0", - "thiserror 2.0.18", + "thiserror 2.0.20", "tracing", "unicode-ident", ] @@ -3069,7 +3073,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", "jni-sys 0.3.1", "log", "ndk-sys", @@ -3099,7 +3103,7 @@ version = "0.31.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", "cfg-if", "cfg_aliases", "libc", @@ -3155,7 +3159,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -3198,7 +3202,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", "block2 0.5.1", "libc", "objc2 0.5.2", @@ -3214,7 +3218,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", "block2 0.6.2", "objc2 0.6.4", "objc2-core-graphics", @@ -3227,7 +3231,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", "block2 0.5.1", "objc2 0.5.2", "objc2-core-location", @@ -3251,7 +3255,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", @@ -3263,7 +3267,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", "dispatch2", "objc2 0.6.4", ] @@ -3274,7 +3278,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", "dispatch2", "objc2 0.6.4", "objc2-core-foundation", @@ -3317,7 +3321,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", "block2 0.5.1", "dispatch", "libc", @@ -3330,7 +3334,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", "objc2 0.6.4", "objc2-core-foundation", ] @@ -3341,7 +3345,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", "objc2 0.6.4", "objc2-core-foundation", ] @@ -3364,7 +3368,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", @@ -3376,7 +3380,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", @@ -3399,7 +3403,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", "block2 0.5.1", "objc2 0.5.2", "objc2-cloud-kit", @@ -3431,7 +3435,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", "block2 0.5.1", "objc2 0.5.2", "objc2-core-location", @@ -3466,9 +3470,9 @@ dependencies = [ [[package]] name = "ordered-float" -version = "5.3.0" +version = "5.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7d950ca161dc355eaf28f82b11345ed76c6e1f6eb1f4f4479e0323b9e2fbd0e" +checksum = "8c7c9e0d9b23589f26070720bac724174bfec1083e82f7854cdd0267518343c0" dependencies = [ "num-traits", ] @@ -3520,15 +3524,27 @@ checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pd-host-function" version = "0.1.0" +source = "git+https://github.com/rustscript-lang/rustscript?rev=b1d6cffede77f49410bf63525f30b9a46b02dc01#b1d6cffede77f49410bf63525f30b9a46b02dc01" dependencies = [ + "pd-host-schema", "proc-macro2", "quote", - "syn", + "syn 2.0.119", +] + +[[package]] +name = "pd-host-schema" +version = "0.1.0" +source = "git+https://github.com/rustscript-lang/rustscript?rev=b1d6cffede77f49410bf63525f30b9a46b02dc01#b1d6cffede77f49410bf63525f30b9a46b02dc01" +dependencies = [ + "proc-macro2", + "syn 2.0.119", ] [[package]] name = "pd-vm" version = "0.1.0" +source = "git+https://github.com/rustscript-lang/rustscript?rev=b1d6cffede77f49410bf63525f30b9a46b02dc01#b1d6cffede77f49410bf63525f30b9a46b02dc01" dependencies = [ "base64", "cranelift-codegen", @@ -3540,11 +3556,13 @@ dependencies = [ "libc", "paste", "pd-host-function", + "pd-host-schema", "regex", "rt-format", + "self_cell", "serde", "serde_json", - "syn", + "syn 2.0.119", "windows-sys 0.59.0", ] @@ -3571,7 +3589,7 @@ checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -3593,9 +3611,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" +checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" [[package]] name = "plain" @@ -3609,11 +3627,11 @@ version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", "crc32fast", "fdeflate", "flate2", - "miniz_oxide", + "miniz_oxide 0.8.9", ] [[package]] @@ -3626,7 +3644,7 @@ dependencies = [ "concurrent-queue", "hermit-abi", "pin-project-lite", - "rustix 1.1.4", + "rustix 1.1.5", "windows-sys 0.61.2", ] @@ -3638,24 +3656,24 @@ checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3" [[package]] name = "portable-atomic" -version = "1.13.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" +checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" [[package]] name = "portable-atomic-util" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" +checksum = "10ab3eb7f3becc3a1cbc4f2c6f20267996cfc1a6467a873763411b136a122715" dependencies = [ "portable-atomic", ] [[package]] name = "potential_utf" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" +checksum = "d83eb9bc6d8e5cf568e7a1101d60ee05e81ed50ea106026f3d18deeb046d7661" dependencies = [ "zerovec", ] @@ -3700,14 +3718,14 @@ version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" dependencies = [ - "toml_edit 0.25.12+spec-1.1.0", + "toml_edit 0.25.15+spec-1.1.0", ] [[package]] name = "proc-macro2" -version = "1.0.106" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" dependencies = [ "unicode-ident", ] @@ -3732,18 +3750,18 @@ checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" [[package]] name = "quick-xml" -version = "0.39.4" +version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdcc8dd4e2f670d309a5f0e83fe36dfdc05af317008fea29144da1a2ac858e5e" +checksum = "e660451e55124f798a69a5af3f49ccfbefbd41910eefd25caf2393e1f3473ec1" dependencies = [ "memchr", ] [[package]] name = "quote" -version = "1.0.46" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" dependencies = [ "proc-macro2", ] @@ -3768,9 +3786,9 @@ checksum = "019b4b213425016d7d84a153c4c73afb0946fbb4840e4eece7ba8848b9d6da22" [[package]] name = "rand" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" +checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" dependencies = [ "rand_chacha", "rand_core", @@ -3813,9 +3831,9 @@ checksum = "ca45419789ae5a7899559e9512e58ca889e41f04f1f2445e9f4b290ceccd1d08" [[package]] name = "rangemap" -version = "1.7.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "973443cf09a9c8656b574a866ab68dfa19f0867d0340648c7d2f6a71b8a8ea68" +checksum = "a611d15b50743feb4c76b7d03edcb0e64f399c26961e4efe6975bc398be6aa3d" [[package]] name = "raw-window-handle" @@ -3836,12 +3854,13 @@ dependencies = [ [[package]] name = "read-fonts" -version = "0.39.2" +version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4ed38b89c2c77ff968c524145ad65fb010f38af5c7a224b53b81d47ac2daa81" +checksum = "046a7d674daf459825b32f5062056d6882db0d2f5a479fbd76ccfc870ac18709" dependencies = [ "bytemuck", - "font-types 0.11.3", + "font-types 0.12.5", + "once_cell", ] [[package]] @@ -3865,16 +3884,16 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", ] [[package]] name = "redox_syscall" -version = "0.9.0" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5102a6aaa05aa011a238e178e6bca86d2cb56fc9f586d37cb80f5bca6e07759" +checksum = "737970939a87c6fa31e7acad13307bccbb017a073b695b6089a2c484f929e20e" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", ] [[package]] @@ -3893,9 +3912,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.12.4" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" dependencies = [ "aho-corasick", "memchr", @@ -3905,9 +3924,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.14" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" dependencies = [ "aho-corasick", "memchr", @@ -3971,7 +3990,7 @@ version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81116b9531d61eabc41aeb228e4b6b2435bcca3233b98cf3b3077d4e6e9debb3" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", "once_cell", "serde", "serde_derive", @@ -4022,7 +4041,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", "errno", "libc", "linux-raw-sys 0.4.15", @@ -4031,11 +4050,11 @@ dependencies = [ [[package]] name = "rustix" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +checksum = "891efababe418670775f199f0d233d84843c227a0949a883ce15b37c78d6629d" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", "errno", "libc", "linux-raw-sys 0.12.1", @@ -4094,9 +4113,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "self_cell" -version = "1.2.2" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b12e76d157a900eb52e81bc6e9f3069344290341720e9178cde2407113ac8d89" +checksum = "2ab42ca02749e120097e328d91d415325bdf43b1c72c4c8badf37375fe40a813" [[package]] name = "semver" @@ -4112,9 +4131,9 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" dependencies = [ "serde_core", "serde_derive", @@ -4122,29 +4141,29 @@ dependencies = [ [[package]] name = "serde_core" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", ] [[package]] name = "serde_json" -version = "1.0.150" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" dependencies = [ "itoa", "memchr", @@ -4170,15 +4189,15 @@ checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" [[package]] name = "simd-adler32" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" +checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" [[package]] name = "simd_cesu8" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33" +checksum = "11031e251abf8611c80f460e19dbdeb54a66db918e49c65a7065b46ac7aec520" dependencies = [ "rustc_version", "simdutf8", @@ -4202,12 +4221,12 @@ dependencies = [ [[package]] name = "skrifa" -version = "0.42.1" +version = "0.44.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c34617370ae968efb7161bb2beb517d9084659aae19e24b89e3db25b46e4564" +checksum = "819ab7d62b1d3e72d9d9dea5650bac30424f9111364bb94928dbf5ecad1baa68" dependencies = [ "bytemuck", - "read-fonts 0.39.2", + "read-fonts 0.41.0", ] [[package]] @@ -4227,9 +4246,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.15.2" +version = "1.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" +checksum = "ba467056f1b547ed52077911161fc86985becbc60e8e1857c8a144dab0def891" [[package]] name = "smol_str" @@ -4242,9 +4261,9 @@ dependencies = [ [[package]] name = "spin" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" +checksum = "023a211cb3138dbc438680b32560ad89f699977624c9f8dbb95a47d5b4c07dd3" dependencies = [ "portable-atomic", ] @@ -4255,7 +4274,7 @@ version = "0.3.0+sdk-1.3.268.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", ] [[package]] @@ -4287,20 +4306,31 @@ checksum = "0193cc4331cfd2f3d2011ef287590868599a2f33c3e69bc22c1a3d3acf9e02fb" [[package]] name = "swash" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0811b01ca2c4e8718760713911feaf4675c24f94e50530a015ec646cfb622f7c" +checksum = "6c2499c2d826531388872b2268718aed907a39bd785ab0dcfe57fab26283f92e" dependencies = [ - "skrifa 0.42.1", + "skrifa 0.44.0", "yazi", "zeno", ] [[package]] name = "syn" -version = "2.0.118" +version = "2.0.119" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee" dependencies = [ "proc-macro2", "quote", @@ -4309,13 +4339,13 @@ dependencies = [ [[package]] name = "synstructure" -version = "0.13.2" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +checksum = "901704edd0dfe137f1987838ee4f259e4e063c31371bdb423f7ae38ec6f77f02" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", ] [[package]] @@ -4365,11 +4395,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.18" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" dependencies = [ - "thiserror-impl 2.0.18", + "thiserror-impl 2.0.20", ] [[package]] @@ -4380,25 +4410,25 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "thiserror-impl" -version = "2.0.18" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", ] [[package]] name = "thread_local" -version = "1.1.9" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070" dependencies = [ "cfg-if", ] @@ -4419,9 +4449,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" +checksum = "b1e27c91459209c2986af3dcf603a5a74a4368754ce37414f59acc971167f643" dependencies = [ "displaydoc", "zerovec", @@ -4429,18 +4459,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" +version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +checksum = "fd3ca314f692efd6c868f8408f53fe444634a845f96c028b97d35f6a1f79f0ee" [[package]] name = "toml_datetime" @@ -4474,23 +4495,23 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.25.12+spec-1.1.0" +version = "0.25.15+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2153edc6955a6c354fad8f5efd38b6a8769bdccf9fe50f8e1329f81b0baa5d7" +checksum = "1340ea94a5856333492c9064b02c778b191dd2c853778d9609debdcdfea3a614" dependencies = [ "indexmap", "toml_datetime 1.1.1+spec-1.1.0", "toml_parser", - "winnow 1.0.3", + "winnow 1.0.4", ] [[package]] name = "toml_parser" -version = "1.1.2+spec-1.1.0" +version = "1.1.3+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +checksum = "1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56" dependencies = [ - "winnow 1.0.3", + "winnow 1.0.4", ] [[package]] @@ -4512,7 +4533,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -4588,9 +4609,9 @@ dependencies = [ [[package]] name = "twox-hash" -version = "2.1.2" +version = "2.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ea3136b675547379c4bd395ca6b938e5ad3c3d20fad76e7fe85f9e0d011419c" +checksum = "5283634e518fe9e82c7b20520bb4bc209009fd16c82077c802f8111ecbb0117a" [[package]] name = "typeid" @@ -4612,9 +4633,9 @@ checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" [[package]] name = "unicode-ident" -version = "1.0.24" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" +checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954" [[package]] name = "unicode-linebreak" @@ -4666,9 +4687,9 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "uuid" -version = "1.23.4" +version = "1.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf80a72845275afea99e7f2b434723d3bc7e38470fcd1c7ed39a599c73319a53" +checksum = "2ef6dac1e96601b4fb3acccccff2139741fcb757cb9a36089bf5be91cfb285ce" dependencies = [ "getrandom 0.4.3", "js-sys", @@ -4690,7 +4711,7 @@ checksum = "41b6d82be61465f97d42bd1d15bf20f3b0a3a0905018f38f9d6f6962055b0b5c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -4720,9 +4741,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.126" +version = "0.2.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" +checksum = "aecb87a33d3b0c5e3b7aa46336eaf486cffafbd281b195e4c8b80d50df2351bf" dependencies = [ "cfg-if", "once_cell", @@ -4733,9 +4754,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.76" +version = "0.4.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62df1340f32221cb9c54d6a27b030e3dba64361d4a95bed55f9aacb44da291d" +checksum = "6ef4c5d3d2cdf5c54f4231181768f5510842e350db025faf1f7163b1030ed928" dependencies = [ "js-sys", "wasm-bindgen", @@ -4743,9 +4764,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.126" +version = "0.2.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" +checksum = "a690d511e3c1a8b3a55e33511e3c2c00c78415cd23650f32b808627f5696b9ed" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4753,22 +4774,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.126" +version = "0.2.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" +checksum = "411e4887f0071ef2d2164a9d5fdf2d20efbef78fccd3a78b0c10a1dc5295e48a" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn", + "syn 3.0.6", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.126" +version = "0.2.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" +checksum = "81941cd78d0c92026c33e5e01312845a4cb1e9af3407f9134b100dd03144103e" dependencies = [ "unicode-ident", ] @@ -4796,13 +4817,13 @@ dependencies = [ [[package]] name = "wayland-backend" -version = "0.3.15" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2857dd20b54e916ec7253b3d6b4d5c4d7d4ca2c33c2e11c6c76a99bd8744755d" +checksum = "38a91b4eaddff87b1cd1074985e3713da4af2c49742d1b356b2c01670a67a078" dependencies = [ "cc", "downcast-rs 1.2.1", - "rustix 1.1.4", + "rustix 1.1.5", "scoped-tls", "smallvec", "wayland-sys", @@ -4810,12 +4831,12 @@ dependencies = [ [[package]] name = "wayland-client" -version = "0.31.14" +version = "0.31.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c7c96bb74690c3189b5c9cb4ca1627062bb23693a4fad9d8c3de958260144" +checksum = "e3c36a0f861ad76d0901f2800b46321410d9f73f2ea88aac0650d86c32688073" dependencies = [ - "bitflags 2.13.0", - "rustix 1.1.4", + "bitflags 2.13.2", + "rustix 1.1.5", "wayland-backend", "wayland-scanner", ] @@ -4826,7 +4847,7 @@ version = "0.32.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23d0c813de3daa2ed6520af85a3bd49b0e722a3078506899aa9686fea58dc4b6" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", "wayland-backend", "wayland-client", "wayland-scanner", @@ -4834,9 +4855,9 @@ dependencies = [ [[package]] name = "wayland-scanner" -version = "0.31.10" +version = "0.31.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c324a910fd86ebdc364a3e61ec1f11737d3b1d6c273c0239ee8ff4bc0d24b4a" +checksum = "338e30461b3a2b67d70eb30a6d89f8e0c93a833e07d2ae89085cd070c4a00ac0" dependencies = [ "proc-macro2", "quick-xml", @@ -4856,9 +4877,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.103" +version = "0.3.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8622dcb61c0bcc9fffa6938bed81210af2da9a7e4a1a834b2e37a59b6dfb6141" +checksum = "9fbddc4a036f00ec4f18c83445bd3115cb306a91da554919a099d9222fe4a7f8" dependencies = [ "js-sys", "wasm-bindgen", @@ -4876,15 +4897,15 @@ dependencies = [ [[package]] name = "webbrowser" -version = "1.2.1" +version = "1.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fc95580916af1e68ff6a7be07446fc5db73ebf71cf092de939bbf5f7e189f72" +checksum = "62c35be770821a214dbc362fc26908c853e776c0004294d0b10b8a6bad582f94" dependencies = [ - "core-foundation 0.10.1", "jni", "log", "ndk-context", "objc2 0.6.4", + "objc2-app-kit 0.3.2", "objc2-foundation 0.3.2", "url", "web-sys", @@ -4903,7 +4924,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfe68bac7cde125de7a731c3400723cadaaf1703795ad3f4805f187459cd7a77" dependencies = [ "arrayvec", - "bitflags 2.13.0", + "bitflags 2.13.2", "cfg-if", "cfg_aliases", "document-features", @@ -4929,7 +4950,7 @@ dependencies = [ "arrayvec", "bit-set", "bit-vec", - "bitflags 2.13.0", + "bitflags 2.13.2", "bytemuck", "cfg_aliases", "document-features", @@ -4944,7 +4965,7 @@ dependencies = [ "raw-window-handle", "rustc-hash 1.1.0", "smallvec", - "thiserror 2.0.18", + "thiserror 2.0.20", "wgpu-core-deps-apple", "wgpu-core-deps-windows-linux-android", "wgpu-hal", @@ -4979,7 +5000,7 @@ dependencies = [ "arrayvec", "ash", "bit-set", - "bitflags 2.13.0", + "bitflags 2.13.2", "block", "bytemuck", "cfg-if", @@ -5005,7 +5026,7 @@ dependencies = [ "raw-window-handle", "renderdoc-sys", "smallvec", - "thiserror 2.0.18", + "thiserror 2.0.20", "wgpu-types", "windows 0.58.0", "windows-core 0.58.0", @@ -5017,12 +5038,12 @@ version = "27.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afdcf84c395990db737f2dd91628706cb31e86d72e53482320d368e52b5da5eb" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", "bytemuck", "js-sys", "log", "serde", - "thiserror 2.0.18", + "thiserror 2.0.20", "web-sys", ] @@ -5042,7 +5063,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" dependencies = [ "windows-core 0.58.0", - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -5077,7 +5098,7 @@ dependencies = [ "windows-interface 0.58.0", "windows-result 0.2.0", "windows-strings 0.1.0", - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -5112,7 +5133,7 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -5123,7 +5144,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -5134,7 +5155,7 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -5145,7 +5166,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -5176,7 +5197,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -5195,7 +5216,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" dependencies = [ "windows-result 0.2.0", - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -5213,7 +5234,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -5222,7 +5243,16 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.5", ] [[package]] @@ -5240,14 +5270,31 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "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-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link 0.2.1", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", ] [[package]] @@ -5265,48 +5312,96 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + [[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_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + [[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_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + [[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_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + [[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_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + [[package]] name = "winit" version = "0.30.13" @@ -5315,7 +5410,7 @@ checksum = "a6755fa58a9f8350bd1e472d4c3fcc25f824ec358933bba33306d0b63df5978d" dependencies = [ "android-activity", "atomic-waker", - "bitflags 2.13.0", + "bitflags 2.13.2", "block2 0.5.1", "bytemuck", "calloop", @@ -5362,9 +5457,9 @@ dependencies = [ [[package]] name = "winnow" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" dependencies = [ "memchr", ] @@ -5377,9 +5472,9 @@ checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" [[package]] name = "writeable" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" +checksum = "3ad82d2a33cdc9674dc7465672f271e096168fcdbe0f799d9e6db8c5892679dc" [[package]] name = "x11-dl" @@ -5403,7 +5498,7 @@ dependencies = [ "libc", "libloading", "once_cell", - "rustix 1.1.4", + "rustix 1.1.5", "x11rb-protocol", ] @@ -5419,7 +5514,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.2", "dlib", "log", "once_cell", @@ -5457,13 +5552,13 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" +checksum = "33811428bee40dbceb6d545e95754741d17a6aef9a4849f0fd62e2ba4f412a78" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", "synstructure", ] @@ -5475,22 +5570,22 @@ checksum = "6df3dc4292935e51816d896edcd52aa30bc297907c26167fec31e2b0c6a32524" [[package]] name = "zerocopy" -version = "0.8.54" +version = "0.8.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7cbbc0a705a0fd05cc3676525980d2bf5a9bc4adac6d6475209a7887cf59d19" +checksum = "d35102a9f36d089ccae9e4c6802bc118be4487b80aaffc0ab4e0cf5ce92d2873" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.54" +version = "0.8.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e817b7b52d0c7358d3246da9d69935ebb18116b2b102b4230dac079b4862f5" +checksum = "146c01f5ab44258da43cf276c74a2763db2ff3969c9c652c3f2de07041d0b2bc" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -5504,21 +5599,21 @@ dependencies = [ [[package]] name = "zerofrom-derive" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" +checksum = "f75b4683f6c7f45248d4d64056a24298c6281e0993356d7d1b4a1a962ef10d4a" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", "synstructure", ] [[package]] name = "zerotrie" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" +checksum = "4ea269c3bd32f0a32c321907a2ae912ba6f4649bb0fc764a15627e99a7095a3f" dependencies = [ "displaydoc", "yoke", @@ -5527,9 +5622,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.6" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" +checksum = "bb0464e17806c1d976d5cba29399c7f08e516e279e2ba493f63123b5fca67dd8" dependencies = [ "yoke", "zerofrom", @@ -5538,26 +5633,32 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.3" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" +checksum = "34df6fc39dbd26ddc9c10e6a2984476e13acce22e64e4487636ef494369225da" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", ] +[[package]] +name = "zlib-rs" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b268e58e7c693d7c271f93ffc4ba3b380412554231c85bf61ca7af91042a4112" + [[package]] name = "zmij" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" [[package]] name = "zune-core" -version = "0.5.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb8a0807f7c01457d0379ba880ba6322660448ddebc890ce29bb64da71fb40f9" +checksum = "d56377fd46368984a170bc5aac5567e52ca5da874caa60bea39fcbca78fb658b" [[package]] name = "zune-jpeg" diff --git a/Cargo.toml b/Cargo.toml index a2df1bd..e405dc0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,8 +6,8 @@ license = "Apache-2.0" [dependencies] bevy_ecs = "0.18.1" -pd-host-function = { path = "../rustscript/pd-host-function" } -vm = { package = "pd-vm", path = "../rustscript", default-features = false, features = ["runtime", "cranelift-jit"] } +pd-host-function = { git = "https://github.com/rustscript-lang/rustscript", rev = "b1d6cffede77f49410bf63525f30b9a46b02dc01" } +vm = { package = "pd-vm", git = "https://github.com/rustscript-lang/rustscript", rev = "b1d6cffede77f49410bf63525f30b9a46b02dc01", default-features = false, features = ["runtime", "cranelift-jit"] } [dev-dependencies] bevy = { version = "0.18.1", default-features = false, features = ["default_app", "bevy_winit", "x11", "bevy_render", "bevy_core_pipeline", "bevy_sprite", "bevy_sprite_render", "bevy_text", "bevy_ui", "bevy_ui_render", "default_font", "png"] } diff --git a/examples/common/board_save.rs b/examples/common/board_save.rs index 3a5d9d6..8be9f94 100644 --- a/examples/common/board_save.rs +++ b/examples/common/board_save.rs @@ -58,6 +58,7 @@ pub fn display_file_name(path: &std::path::Path) -> String { .unwrap_or_else(|| path.display().to_string()) } +#[allow(dead_code)] pub fn encode_board_save(game: &str, cells: &[i64], scripts: &[(&str, &str)]) -> String { encode_board_save_with_history(game, cells, scripts, None, &[], &[]) } @@ -208,7 +209,7 @@ fn hex_decode(input: &str) -> Result, String> { } let mut output = Vec::with_capacity(input.len() / 2); let bytes = input.as_bytes(); - for chunk in bytes.chunks_exact(2) { + for chunk in bytes.as_chunks::<2>().0 { let high = hex_value(chunk[0])?; let low = hex_value(chunk[1])?; output.push((high << 4) | low); diff --git a/examples/common/script_editor.rs b/examples/common/script_editor.rs index cde0790..7c5bd12 100644 --- a/examples/common/script_editor.rs +++ b/examples/common/script_editor.rs @@ -5,7 +5,10 @@ use std::{ }; use bevy_egui::egui; -use vm::{DebugCommandBridge, DebugCommandBridgeError, SourceError, SourceMap, compile_source}; +use rustscript_bevy_gameplay::compile_bevy_script; +#[cfg(test)] +use vm::compile_source; +use vm::{DebugCommandBridge, DebugCommandBridgeError, SourceError, SourceMap, SourcePathError}; const CODE_FONT_SIZE: f32 = 13.0; @@ -842,7 +845,7 @@ struct ScriptToken { } impl ScriptToken { - fn text<'a>(self, source: &'a str) -> &'a str { + fn text(self, source: &str) -> &str { &source[self.start..self.end] } } @@ -1057,9 +1060,15 @@ fn next_non_ws_starts_with(source: &str, cursor: usize, needle: char) -> bool { fn script_compile_diagnostics(source: &str, prefix: &str) -> Vec { let full_source = format!("{prefix}{source}"); let prefix_lines = prefix.lines().count(); - match compile_source(&full_source) { + match compile_bevy_script(&full_source) { Ok(_) => Vec::new(), - Err(SourceError::Parse(err)) => { + Err( + SourcePathError::Source(SourceError::Parse(err)) + | SourcePathError::SourceWithMap { + error: SourceError::Parse(err), + .. + }, + ) => { let mut source_map = SourceMap::new(); let source_id = source_map.add_source("", full_source); let err = err.with_line_span_from_source(&source_map, source_id); @@ -1080,7 +1089,13 @@ fn script_compile_diagnostics(source: &str, prefix: &str) -> Vec { + Err( + SourcePathError::Source(SourceError::Compile(err)) + | SourcePathError::SourceWithMap { + error: SourceError::Compile(err), + .. + }, + ) => { let mut source_map = SourceMap::new(); let source_id = source_map.add_source("", full_source); let full_line = err.line().unwrap_or(1).max(1); @@ -1095,6 +1110,19 @@ fn script_compile_diagnostics(source: &str, prefix: &str) -> Vec { + let mut source_map = SourceMap::new(); + let source_id = source_map.add_source("", full_source); + vec![script_diagnostic_from_parts( + source, + &source_map, + source_id, + 1, + prefix_lines, + None, + other.to_string(), + )] + } } } diff --git a/examples/gomoku.rs b/examples/gomoku.rs index fd8e0a4..4d75b87 100644 --- a/examples/gomoku.rs +++ b/examples/gomoku.rs @@ -1,3 +1,5 @@ +#![allow(clippy::drop_non_drop)] + use std::{ sync::{Arc, Mutex, mpsc}, thread, @@ -496,11 +498,11 @@ fn draw_board( let y = grid.top() + offset; painter.line_segment( [egui::pos2(x, grid.top()), egui::pos2(x, grid.bottom())], - egui::Stroke::new(1.2, line), + egui::Stroke::new(1.2_f32, line), ); painter.line_segment( [egui::pos2(grid.left(), y), egui::pos2(grid.right(), y)], - egui::Stroke::new(1.2, line), + egui::Stroke::new(1.2_f32, line), ); } @@ -514,7 +516,7 @@ fn draw_board( painter.circle_stroke( center, step * 0.48, - egui::Stroke::new(2.0, egui::Color32::from_rgb(94, 132, 196)), + egui::Stroke::new(2.0_f32, egui::Color32::from_rgb(94, 132, 196)), ); } @@ -537,7 +539,7 @@ fn draw_board( painter.circle_stroke( center, step * 0.38, - egui::Stroke::new(1.0, egui::Color32::from_rgb(168, 160, 144)), + egui::Stroke::new(1.0_f32, egui::Color32::from_rgb(168, 160, 144)), ); } _ => {} diff --git a/examples/shooter.rs b/examples/shooter.rs index ec89750..bce53f3 100644 --- a/examples/shooter.rs +++ b/examples/shooter.rs @@ -1,3 +1,5 @@ +#![allow(clippy::type_complexity)] + use bevy::{ asset::RenderAssetUsages, camera::{OrthographicProjection, Projection, ScalingMode}, @@ -11,10 +13,10 @@ use bevy_egui::{ use rustscript_bevy_gameplay::{ AttackCooldownMs, AttackPower, AttackStyle, Enemy, Health, Player, PlayerProjectileLoadout, Position, RewardItem, ScriptManagedEnemy, ShooterSpawnRules, Velocity, apply_shooter_script, - tick_shooter_spawn_rules, + compile_bevy_script, tick_shooter_spawn_rules, }; use std::f32::consts::FRAC_PI_2; -use vm::{SourceError, SourceMap, compile_source}; +use vm::{SourceError, SourceMap, SourcePathError}; const SCRIPT: &str = include_str!("../scripts/shooter_game.rss"); const LEFT: f32 = -260.0; @@ -178,7 +180,7 @@ struct ScriptToken { } impl ScriptToken { - fn text<'a>(self, source: &'a str) -> &'a str { + fn text(self, source: &str) -> &str { &source[self.start..self.end] } } @@ -388,7 +390,7 @@ fn next_non_ws_starts_with(source: &str, cursor: usize, needle: char) -> bool { } fn script_compile_diagnostics(source: &str, fallback_error: &str) -> Vec { - match compile_source(source) { + match compile_bevy_script(source) { Ok(_) => { if fallback_error.trim().is_empty() { Vec::new() @@ -396,7 +398,13 @@ fn script_compile_diagnostics(source: &str, fallback_error: &str) -> Vec { + Err( + SourcePathError::Source(SourceError::Parse(err)) + | SourcePathError::SourceWithMap { + error: SourceError::Parse(err), + .. + }, + ) => { let mut source_map = SourceMap::new(); let source_id = source_map.add_source("", source.to_string()); let err = err.with_line_span_from_source(&source_map, source_id); @@ -414,7 +422,13 @@ fn script_compile_diagnostics(source: &str, fallback_error: &str) -> Vec { + Err( + SourcePathError::Source(SourceError::Compile(err)) + | SourcePathError::SourceWithMap { + error: SourceError::Compile(err), + .. + }, + ) => { let mut source_map = SourceMap::new(); let source_id = source_map.add_source("", source.to_string()); let line = err.line().unwrap_or(1).max(1); @@ -427,6 +441,7 @@ fn script_compile_diagnostics(source: &str, fallback_error: &str) -> Vec vec![fallback_script_diagnostic(source, &other.to_string())], } } @@ -1132,7 +1147,6 @@ fn spawn_starfield(commands: &mut Commands, assets: &ShooterAssets) { translation: Vec3::new(x, y, -8.0), scale: Vec3::splat(scale), rotation: Quat::from_rotation_z((index as f32 * 0.37) % std::f32::consts::TAU), - ..default() }, VisualMotion { base_scale: Vec3::splat(scale), @@ -2509,7 +2523,7 @@ fn script_panel( egui::Frame::new() .fill(egui::Color32::from_rgba_unmultiplied(8, 14, 24, 215)) .stroke(egui::Stroke::new( - 1.0, + 1.0_f32, egui::Color32::from_rgb(120, 170, 210), )) .corner_radius(egui::CornerRadius::same(6)) @@ -2529,7 +2543,7 @@ fn script_panel( egui::Frame::new() .fill(egui::Color32::from_rgba_unmultiplied(8, 16, 28, 190)) .stroke(egui::Stroke::new( - 1.0, + 1.0_f32, egui::Color32::from_rgb(70, 115, 150), )) .corner_radius(egui::CornerRadius::same(6)) diff --git a/examples/xiangqi.rs b/examples/xiangqi.rs index 80b2487..d85b50f 100644 --- a/examples/xiangqi.rs +++ b/examples/xiangqi.rs @@ -1,3 +1,5 @@ +#![allow(clippy::drop_non_drop, clippy::too_many_arguments)] + use std::{ sync::{Arc, Mutex, mpsc}, thread, @@ -508,14 +510,14 @@ fn draw_board( let px = grid.left() + x as f32 * step_x; painter.line_segment( [egui::pos2(px, grid.top()), egui::pos2(px, grid.bottom())], - egui::Stroke::new(1.25, line_color), + egui::Stroke::new(1.25_f32, line_color), ); } for y in 0..10 { let py = grid.top() + y as f32 * step_y; painter.line_segment( [egui::pos2(grid.left(), py), egui::pos2(grid.right(), py)], - egui::Stroke::new(1.25, line_color), + egui::Stroke::new(1.25_f32, line_color), ); } @@ -542,14 +544,14 @@ fn draw_board( painter.circle_stroke( board_point(grid, step_x, step_y, x, y), step_x.min(step_y) * 0.42, - egui::Stroke::new(3.0, egui::Color32::from_rgb(60, 105, 190)), + egui::Stroke::new(3.0_f32, egui::Color32::from_rgb(60, 105, 190)), ); } if let Some(last) = state.last_ai_move { painter.circle_stroke( board_point(grid, step_x, step_y, last.to_x, last.to_y), step_x.min(step_y) * 0.47, - egui::Stroke::new(2.0, egui::Color32::from_rgb(36, 118, 88)), + egui::Stroke::new(2.0_f32, egui::Color32::from_rgb(36, 118, 88)), ); } @@ -583,8 +585,8 @@ fn draw_palace( let right = board_point(grid, step_x, step_y, 5, top_y); let bottom_left = board_point(grid, step_x, step_y, 3, top_y + 2); let bottom_right = board_point(grid, step_x, step_y, 5, top_y + 2); - painter.line_segment([left, bottom_right], egui::Stroke::new(1.2, color)); - painter.line_segment([right, bottom_left], egui::Stroke::new(1.2, color)); + painter.line_segment([left, bottom_right], egui::Stroke::new(1.2_f32, color)); + painter.line_segment([right, bottom_left], egui::Stroke::new(1.2_f32, color)); } fn draw_piece( @@ -613,7 +615,7 @@ fn draw_piece( let text_color = stroke; painter.circle_filled(center + egui::vec2(2.0, 3.0), radius, shadow); painter.circle_filled(center, radius, fill); - painter.circle_stroke(center, radius, egui::Stroke::new(2.0, stroke)); + painter.circle_stroke(center, radius, egui::Stroke::new(2.0_f32, stroke)); painter.text( center, egui::Align2::CENTER_CENTER, diff --git a/src/lib.rs b/src/lib.rs index fd0286d..93ef5f5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,11 +1,20 @@ -use std::{cell::RefCell, collections::HashMap, time::Instant}; +use std::{ + cell::RefCell, + collections::HashMap, + sync::{Arc, OnceLock}, + time::Instant, +}; use bevy_ecs::prelude::*; -pub(crate) use vm::Vm; use vm::{ - CallOutcome, CallReturn, Debugger, JitConfig, Value, VmError, VmResult, VmStatus, - compile_source, + CompileSourceFileOptions, Debugger, HostApiCatalog, HostFunctionDescriptor, + HostFunctionRegistry, HostModuleDescriptor, HostTypeSchema, JitConfig, SourceFlavor, + SourcePathError, VmError, VmStatus, compile_source_with_flavor_and_options, }; +pub(crate) use vm::{Value, Vm, VmResult}; + +/// Frozen `rustscript-lang/rustscript` revision this crate is pinned to. +pub const FROZEN_RUSTSCRIPT_REV: &str = "b1d6cffede77f49410bf63525f30b9a46b02dc01"; #[derive(Component, Debug, Clone, Copy, PartialEq, Eq)] pub struct Health(pub i64); @@ -337,10 +346,9 @@ pub struct DamageRules { impl DamageRules { pub fn from_source(source: impl Into) -> Result { let source = source.into(); - compile_source(&format!( + compile_bevy_source(&format!( "let incoming = 0;\nlet critical = false;\n{source}" - )) - .map_err(|err| err.to_string())?; + ))?; Ok(Self { source }) } } @@ -360,7 +368,7 @@ pub fn apply_scripted_damage( } pub fn apply_shooter_script(world: &mut World, source: &str) -> Result { - compile_source(source).map_err(|err| err.to_string())?; + compile_bevy_source(source)?; world.insert_resource(ShooterSpawnRules::default()); let (_, jit) = with_shooter_context(world, || run_shooter_script(source))?; summarize_shooter_world(world, jit) @@ -555,6 +563,7 @@ pub fn choose_xiangqi_ai_move_with_bias( }) } +#[allow(clippy::too_many_arguments)] pub fn debug_xiangqi_move_script( world: &mut World, source: &str, @@ -880,6 +889,12 @@ struct XiangqiContext { } thread_local! { + // Raw host-private Bevy world/entity boundary. Guest scripts do not receive + // a world or entity handle; each evaluation installs a call-scoped pointer + // for the duration of one synchronous VM run. This is not a guest resource + // and is not HostState, so cached AI VMs can keep their compiled program + // while the live Bevy world changes between runs. Combat, shooter, Gomoku, + // and Xiangqi each own one of these slots. static BEVY_CONTEXT: RefCell> = const { RefCell::new(None) }; static SHOOTER_CONTEXT: RefCell> = const { RefCell::new(None) }; static GOMOKU_CONTEXT: RefCell> = const { RefCell::new(None) }; @@ -1014,7 +1029,7 @@ fn with_xiangqi_world(f: impl FnOnce(&mut World) -> VmResult) -> VmResult< } fn run_value(source: &str) -> Result { - let compiled = compile_source(source).map_err(|err| err.to_string())?; + let compiled = compile_bevy_source(source)?; let mut vm = Vm::new(compiled.program); bind_bevy_hosts(&mut vm); let status = vm.run().map_err(|err| err.to_string())?; @@ -1029,7 +1044,7 @@ fn run_value(source: &str) -> Result { fn run_gomoku_script(source: &str) -> Result<(Value, GomokuScriptTelemetry), String> { let started = Instant::now(); - let compiled = compile_source(source).map_err(|err| err.to_string())?; + let compiled = compile_bevy_source(source)?; let mut vm = Vm::new_with_jit_config(compiled.program, gomoku_jit_config()); bind_gomoku_hosts(&mut vm); let status = vm.run().map_err(|err| err.to_string())?; @@ -1059,7 +1074,7 @@ fn run_cached_gomoku_ai_script(source: &str) -> Result<(Value, GomokuScriptTelem if cache.len() >= AI_VM_CACHE_LIMIT { cache.clear(); } - let compiled = compile_source(source).map_err(|err| err.to_string())?; + let compiled = compile_bevy_source(source)?; let mut vm = Vm::new_with_jit_config(compiled.program, gomoku_jit_config()); bind_gomoku_hosts(&mut vm); cache.insert(source.to_string(), vm); @@ -1068,7 +1083,7 @@ fn run_cached_gomoku_ai_script(source: &str) -> Result<(Value, GomokuScriptTelem let vm = cache .get_mut(source) .ok_or_else(|| "gomoku AI VM cache missed after insert".to_string())?; - vm.reset_for_reuse(); + vm.reset_for_reuse().map_err(|err| err.to_string())?; let started = Instant::now(); let status = vm.run().map_err(|err| err.to_string())?; if status != VmStatus::Halted { @@ -1096,7 +1111,7 @@ fn run_gomoku_script_with_debugger( debugger: &mut Debugger, ) -> Result<(Value, GomokuScriptTelemetry), String> { let started = Instant::now(); - let compiled = compile_source(source).map_err(|err| err.to_string())?; + let compiled = compile_bevy_source(source)?; let mut vm = Vm::new(compiled.program); bind_gomoku_hosts(&mut vm); let status = vm @@ -1125,7 +1140,7 @@ fn run_xiangqi_script( enable_jit: bool, ) -> Result<(Value, XiangqiScriptTelemetry), String> { let started = Instant::now(); - let compiled = compile_source(source).map_err(|err| err.to_string())?; + let compiled = compile_bevy_source(source)?; let mut vm = if enable_jit { Vm::new_with_jit_config(compiled.program, xiangqi_jit_config()) } else { @@ -1159,7 +1174,7 @@ fn run_cached_xiangqi_ai_script(source: &str) -> Result<(Value, XiangqiScriptTel if cache.len() >= AI_VM_CACHE_LIMIT { cache.clear(); } - let compiled = compile_source(source).map_err(|err| err.to_string())?; + let compiled = compile_bevy_source(source)?; let mut vm = Vm::new_with_jit_config(compiled.program, xiangqi_jit_config()); bind_xiangqi_hosts(&mut vm); cache.insert(source.to_string(), vm); @@ -1168,7 +1183,7 @@ fn run_cached_xiangqi_ai_script(source: &str) -> Result<(Value, XiangqiScriptTel let vm = cache .get_mut(source) .ok_or_else(|| "xiangqi AI VM cache missed after insert".to_string())?; - vm.reset_for_reuse(); + vm.reset_for_reuse().map_err(|err| err.to_string())?; let started = Instant::now(); let status = vm.run().map_err(|err| err.to_string())?; if status != VmStatus::Halted { @@ -1196,7 +1211,7 @@ fn run_xiangqi_script_with_debugger( debugger: &mut Debugger, ) -> Result<(Value, XiangqiScriptTelemetry), String> { let started = Instant::now(); - let compiled = compile_source(source).map_err(|err| err.to_string())?; + let compiled = compile_bevy_source(source)?; let mut vm = Vm::new(compiled.program); bind_xiangqi_hosts(&mut vm); let status = vm @@ -1245,7 +1260,7 @@ fn xiangqi_jit_config() -> JitConfig { } fn run_shooter_script(source: &str) -> Result<(Value, ShooterJitSummary), String> { - let compiled = compile_source(source).map_err(|err| err.to_string())?; + let compiled = compile_bevy_source(source)?; let mut vm = Vm::new_with_jit_config(compiled.program, shooter_jit_config()); bind_shooter_hosts(&mut vm); let status = vm.run().map_err(|err| err.to_string())?; @@ -1267,155 +1282,168 @@ fn run_shooter_script(source: &str) -> Result<(Value, ShooterJitSummary), String )) } +/// Compiles RustScript against the composed Bevy host catalog. +pub fn compile_bevy_script(source: &str) -> Result { + compile_source_with_flavor_and_options( + source, + SourceFlavor::RustScript, + CompileSourceFileOptions::default().with_host_api_catalog(bevy_host_catalog()), + ) +} + +fn compile_bevy_source(source: &str) -> Result { + compile_bevy_script(source).map_err(|err| err.to_string()) +} + +/// Deterministic ordered Bevy host modules. Catalog construction and exact +/// runtime binding both walk this list and no other registration table. +pub fn bevy_host_modules() -> [HostModuleDescriptor; 4] { + [ + bevy_world_host_module(), + bevy_shooter_host_module(), + bevy_gomoku_host_module(), + bevy_xiangqi_host_module(), + ] +} + +fn bevy_world_host_module() -> HostModuleDescriptor { + HostModuleDescriptor { + name: "bevy.world", + functions: &[ + host::bevy::world_contains_entity_descriptor, + host::bevy::world_get_health_descriptor, + host::bevy::world_get_armor_descriptor, + host::bevy::world_set_health_descriptor, + ], + resources: &[], + } +} + +fn bevy_shooter_host_module() -> HostModuleDescriptor { + HostModuleDescriptor { + name: "bevy.shooter", + functions: &[ + host::bevy::shooter_set_player_health_descriptor, + host::bevy::shooter_set_player_attack_descriptor, + host::bevy::shooter_set_player_projectiles_descriptor, + host::bevy::shooter_spawn_enemy_descriptor, + host::bevy::shooter_spawn_reward_descriptor, + host::bevy::shooter_spawn_enemy_every_descriptor, + host::bevy::shooter_spawn_reward_every_descriptor, + host::bevy::shooter_spawn_enemy_after_kills_descriptor, + ], + resources: &[], + } +} + +fn bevy_gomoku_host_module() -> HostModuleDescriptor { + HostModuleDescriptor { + name: "bevy.gomoku", + functions: &[ + host::bevy::gomoku_board_descriptor, + host::bevy::gomoku_board_size_descriptor, + host::bevy::gomoku_cell_descriptor, + host::bevy::gomoku_set_cell_descriptor, + host::bevy::gomoku_set_move_result_descriptor, + host::bevy::gomoku_set_ai_move_descriptor, + ], + resources: &[], + } +} + +fn bevy_xiangqi_host_module() -> HostModuleDescriptor { + HostModuleDescriptor { + name: "bevy.xiangqi", + functions: &[ + host::bevy::xiangqi_board_descriptor, + host::bevy::xiangqi_board_width_descriptor, + host::bevy::xiangqi_board_height_descriptor, + host::bevy::xiangqi_cell_descriptor, + host::bevy::xiangqi_set_cell_descriptor, + host::bevy::xiangqi_set_move_result_descriptor, + host::bevy::xiangqi_set_ai_move_descriptor, + ], + resources: &[], + } +} + +/// Guest catalog derived from [`bevy_host_modules`] in declaration order. +/// +/// Fingerprint policy: [`HostApiCatalog::fingerprint`] is pd-vm's 64-bit FNV-1a +/// over the guest surface (resource keys, named structs, function names, +/// parameter labels/types/passing modes, and return types), prefixed by pd-vm's +/// domain magic and fingerprint format version. Documentation and runtime-only +/// adapter/effect details are excluded. Tests pin the exact hex and `u64` +/// digest. Update that golden snapshot when this catalog's guest surface +/// changes, or when the frozen RustScript revision changes pd-vm's fingerprint +/// encoding. Do not change the snapshot for host-private TLS/`HostState`, +/// adapter bodies, timings, or documentation-only edits. pd-vm owns the +/// fingerprint format version; this crate does not carry a parallel schema +/// version. +pub fn bevy_host_catalog() -> Arc { + static CATALOG: OnceLock> = OnceLock::new(); + CATALOG + .get_or_init(|| { + Arc::new( + compose_bevy_host_catalog().expect("bevy host composition must build a catalog"), + ) + }) + .clone() +} + +fn compose_bevy_host_catalog() -> Result { + let descriptors: Vec<_> = bevy_host_modules() + .iter() + .flat_map(|module| module.descriptors()) + .collect(); + HostFunctionDescriptor::collect_catalog(&descriptors) +} + +/// Installs every composed Bevy module into `registry` against `catalog`. +/// +/// The whole composition is transactional: a later module failure leaves +/// `registry` unchanged. +pub fn install_bevy_host_modules( + registry: &mut HostFunctionRegistry, + catalog: &HostApiCatalog, +) -> VmResult { + registry.transactionally(|registry| { + let mut installed = None; + for module in bevy_host_modules() { + installed = Some(module.install_from_catalog(registry, catalog)?); + } + installed.ok_or_else(|| VmError::HostError("bevy host composition is empty".to_string())) + }) +} + +fn bind_composed_bevy_hosts(vm: &mut Vm) -> Result<(), String> { + let catalog = bevy_host_catalog(); + let mut registry = HostFunctionRegistry::restricted(); + install_bevy_host_modules(&mut registry, catalog.as_ref()).map_err(|err| err.to_string())?; + registry.bind_vm_cached(vm).map_err(|err| err.to_string()) +} + fn bind_bevy_hosts(vm: &mut Vm) { - vm.bind_static_args_function( - "bevy::World::contains_entity", - host::bevy::world_contains_entity_host, - ); - vm.bind_static_args_function("bevy::World::get_health", host::bevy::world_get_health_host); - vm.bind_static_args_function("bevy::World::get_armor", host::bevy::world_get_armor_host); - vm.bind_static_args_function("bevy::World::set_health", host::bevy::world_set_health_host); + bind_composed_bevy_hosts(vm).expect("bevy world hosts install from the composed catalog"); } fn bind_shooter_hosts(vm: &mut Vm) { - vm.bind_static_args_function( - "bevy::Shooter::set_player_health", - host::bevy::shooter_set_player_health_host, - ); - vm.bind_static_args_function( - "bevy::Shooter::set_player_attack", - host::bevy::shooter_set_player_attack_host, - ); - vm.bind_static_args_function( - "bevy::Shooter::spawn_enemy", - host::bevy::shooter_spawn_enemy_host, - ); - vm.bind_static_args_function( - "bevy::Shooter::set_player_projectiles", - host::bevy::shooter_set_player_projectiles_host, - ); - vm.bind_static_args_function( - "bevy::Shooter::spawn_reward", - host::bevy::shooter_spawn_reward_host, - ); - vm.bind_static_args_function( - "bevy::Shooter::spawn_enemy_every", - host::bevy::shooter_spawn_enemy_every_host, - ); - vm.bind_static_args_function( - "bevy::Shooter::spawn_reward_every", - host::bevy::shooter_spawn_reward_every_host, - ); - vm.bind_static_args_function( - "bevy::Shooter::spawn_enemy_after_kills", - host::bevy::shooter_spawn_enemy_after_kills_host, - ); + bind_composed_bevy_hosts(vm).expect("bevy shooter hosts install from the composed catalog"); } fn bind_gomoku_hosts(vm: &mut Vm) { - vm.bind_static_args_function("bevy::Gomoku::board", host::bevy::gomoku_board_host); - vm.bind_static_args_function( - "bevy::Gomoku::board_size", - host::bevy::gomoku_board_size_host, - ); - vm.bind_static_args_function("bevy::Gomoku::cell", host::bevy::gomoku_cell_host); - vm.bind_static_args_function("bevy::Gomoku::set_cell", host::bevy::gomoku_set_cell_host); - vm.bind_static_args_function( - "bevy::Gomoku::set_move_result", - host::bevy::gomoku_set_move_result_host, - ); - vm.bind_static_args_function( - "bevy::Gomoku::set_ai_move", - host::bevy::gomoku_set_ai_move_host, - ); + bind_composed_bevy_hosts(vm).expect("bevy gomoku hosts install from the composed catalog"); } fn bind_xiangqi_hosts(vm: &mut Vm) { - vm.bind_static_args_function("bevy::Xiangqi::board", host::bevy::xiangqi_board_host); - vm.bind_static_args_function( - "bevy::Xiangqi::board_width", - host::bevy::xiangqi_board_width_host, - ); - vm.bind_static_args_function( - "bevy::Xiangqi::board_height", - host::bevy::xiangqi_board_height_host, - ); - vm.bind_static_args_function("bevy::Xiangqi::cell", host::bevy::xiangqi_cell_host); - vm.bind_static_args_function("bevy::Xiangqi::set_cell", host::bevy::xiangqi_set_cell_host); - vm.bind_static_args_function( - "bevy::Xiangqi::set_move_result", - host::bevy::xiangqi_set_move_result_host, - ); - vm.bind_static_args_function( - "bevy::Xiangqi::set_ai_move", - host::bevy::xiangqi_set_ai_move_host, - ); + bind_composed_bevy_hosts(vm).expect("bevy xiangqi hosts install from the composed catalog"); } mod host { use super::*; use pd_host_function::pd_host_function; - - pub(super) trait BorrowVmValue<'a>: Sized { - fn borrow_vm_value(value: &'a Value, label: &str) -> VmResult; - } - - pub(super) fn borrow_arg<'a, T>(args: &'a [Value], index: usize, label: &str) -> VmResult - where - T: BorrowVmValue<'a>, - { - let value = args - .get(index) - .ok_or_else(|| VmError::HostError(format!("missing argument: {label}")))?; - T::borrow_vm_value(value, label) - } - - impl BorrowVmValue<'_> for i64 { - fn borrow_vm_value(value: &Value, _label: &str) -> VmResult { - match value { - Value::Int(value) => Ok(*value), - _ => Err(VmError::TypeMismatch("int")), - } - } - } - - impl BorrowVmValue<'_> for bool { - fn borrow_vm_value(value: &Value, _label: &str) -> VmResult { - match value { - Value::Bool(value) => Ok(*value), - _ => Err(VmError::TypeMismatch("bool")), - } - } - } - - impl<'a> BorrowVmValue<'a> for &'a str { - fn borrow_vm_value(value: &'a Value, _label: &str) -> VmResult { - match value { - Value::String(value) => Ok(value.as_str()), - _ => Err(VmError::TypeMismatch("string")), - } - } - } - - trait IntoVmValue { - fn into_vm_value(self) -> Value; - } - - impl IntoVmValue for bool { - fn into_vm_value(self) -> Value { - Value::Bool(self) - } - } - - impl IntoVmValue for i64 { - fn into_vm_value(self) -> Value { - Value::Int(self) - } - } - - fn return_one(value: VmResult) -> VmResult { - Ok(CallOutcome::Return(CallReturn::one(value?.into_vm_value()))) - } + #[allow(unused_imports)] + pub(super) use vm::{arg, borrow_arg, take_arg}; pub(super) mod bevy { use super::*; @@ -1426,10 +1454,6 @@ mod host { with_world(|world, entity| Ok(world.get_entity(entity).is_ok())) } - pub(crate) fn world_contains_entity_host(args: &[Value]) -> VmResult { - return_one(world_contains_entity(args)) - } - /// Reads Health via Bevy World::get for the current entity. #[pd_host_function(name = "bevy::World::get_health")] pub(crate) fn world_get_health_impl() -> VmResult { @@ -1443,10 +1467,6 @@ mod host { }) } - pub(crate) fn world_get_health_host(args: &[Value]) -> VmResult { - return_one(world_get_health(args)) - } - /// Reads Armor via Bevy World::get for the current entity. #[pd_host_function(name = "bevy::World::get_armor")] pub(crate) fn world_get_armor_impl() -> VmResult { @@ -1460,10 +1480,6 @@ mod host { }) } - pub(crate) fn world_get_armor_host(args: &[Value]) -> VmResult { - return_one(world_get_armor(args)) - } - /// Writes Health via Bevy World::get_mut for the current entity. #[pd_host_function(name = "bevy::World::set_health")] pub(crate) fn world_set_health_impl(value: i64) -> VmResult { @@ -1476,10 +1492,6 @@ mod host { }) } - pub(crate) fn world_set_health_host(args: &[Value]) -> VmResult { - return_one(world_set_health(args)) - } - /// Updates the live Bevy ECS player Health component from RustScript. #[pd_host_function(name = "bevy::Shooter::set_player_health")] pub(crate) fn shooter_set_player_health_impl(value: i64) -> VmResult { @@ -1493,10 +1505,6 @@ mod host { }) } - pub(crate) fn shooter_set_player_health_host(args: &[Value]) -> VmResult { - return_one(shooter_set_player_health(args)) - } - /// Updates the live Bevy ECS player attack style, power, and cooldown from RustScript. #[pd_host_function(name = "bevy::Shooter::set_player_attack")] pub(crate) fn shooter_set_player_attack_impl( @@ -1522,10 +1530,6 @@ mod host { }) } - pub(crate) fn shooter_set_player_attack_host(args: &[Value]) -> VmResult { - return_one(shooter_set_player_attack(args)) - } - /// Updates the player's projectile asset type and simultaneous count from RustScript. #[pd_host_function(name = "bevy::Shooter::set_player_projectiles")] pub(crate) fn shooter_set_player_projectiles_impl( @@ -1547,10 +1551,6 @@ mod host { }) } - pub(crate) fn shooter_set_player_projectiles_host(args: &[Value]) -> VmResult { - return_one(shooter_set_player_projectiles(args)) - } - /// Spawns a script-managed enemy by calling Bevy World::spawn. #[pd_host_function(name = "bevy::Shooter::spawn_enemy")] pub(crate) fn shooter_spawn_enemy_impl( @@ -1566,10 +1566,6 @@ mod host { }) } - pub(crate) fn shooter_spawn_enemy_host(args: &[Value]) -> VmResult { - return_one(shooter_spawn_enemy(args)) - } - /// Spawns a script-managed reward pickup by calling Bevy World::spawn. #[pd_host_function(name = "bevy::Shooter::spawn_reward")] pub(crate) fn shooter_spawn_reward_impl( @@ -1584,10 +1580,6 @@ mod host { }) } - pub(crate) fn shooter_spawn_reward_host(args: &[Value]) -> VmResult { - return_one(shooter_spawn_reward(args)) - } - /// Registers a repeated enemy spawn rule from RustScript. #[pd_host_function(name = "bevy::Shooter::spawn_enemy_every")] pub(crate) fn shooter_spawn_enemy_every_impl( @@ -1616,10 +1608,6 @@ mod host { }) } - pub(crate) fn shooter_spawn_enemy_every_host(args: &[Value]) -> VmResult { - return_one(shooter_spawn_enemy_every(args)) - } - /// Registers a repeated reward spawn rule from RustScript. #[pd_host_function(name = "bevy::Shooter::spawn_reward_every")] pub(crate) fn shooter_spawn_reward_every_impl( @@ -1646,10 +1634,6 @@ mod host { }) } - pub(crate) fn shooter_spawn_reward_every_host(args: &[Value]) -> VmResult { - return_one(shooter_spawn_reward_every(args)) - } - /// Registers a one-shot enemy spawn rule gated by kills since script apply. #[pd_host_function(name = "bevy::Shooter::spawn_enemy_after_kills")] pub(crate) fn shooter_spawn_enemy_after_kills_impl( @@ -1679,29 +1663,18 @@ mod host { }) } - pub(crate) fn shooter_spawn_enemy_after_kills_host( - args: &[Value], - ) -> VmResult { - return_one(shooter_spawn_enemy_after_kills(args)) - } - - /// Returns the square Gomoku board size for RustScript scans. - #[pd_host_function(name = "bevy::Gomoku::board_size")] - pub(crate) fn gomoku_board_size_impl() -> VmResult { - with_gomoku_world(|_world| Ok(GOMOKU_BOARD_SIZE)) - } - - pub(crate) fn gomoku_board_size_host(args: &[Value]) -> VmResult { - return_one(gomoku_board_size(args)) + fn gomoku_board_contract() -> vm::HostFunctionSchema { + vm::HostFunctionSchema::with_return( + "bevy::Gomoku::board", + Vec::new(), + HostTypeSchema::Array(Box::new(HostTypeSchema::Int)), + ) } - pub(crate) fn gomoku_board_host(args: &[Value]) -> VmResult { - if !args.is_empty() { - return Err(VmError::HostError( - "bevy::Gomoku::board expects no arguments".to_string(), - )); - } - let board = with_gomoku_world(|world| { + /// Returns the Gomoku board cells in row-major order as a typed `[int]`. + #[pd_host_function(name = "bevy::Gomoku::board", contract = gomoku_board_contract)] + pub(crate) fn gomoku_board_impl() -> VmResult { + with_gomoku_world(|world| { ensure_gomoku_resources(world); Ok(Value::array( world @@ -1712,8 +1685,13 @@ mod host { .map(Value::Int) .collect(), )) - })?; - Ok(CallOutcome::Return(CallReturn::one(board))) + }) + } + + /// Returns the square Gomoku board size for RustScript scans. + #[pd_host_function(name = "bevy::Gomoku::board_size")] + pub(crate) fn gomoku_board_size_impl() -> VmResult { + with_gomoku_world(|_world| Ok(GOMOKU_BOARD_SIZE)) } /// Reads a board cell; out-of-bounds cells return a sentinel value. @@ -1726,10 +1704,6 @@ mod host { }) } - pub(crate) fn gomoku_cell_host(args: &[Value]) -> VmResult { - return_one(gomoku_cell(args)) - } - /// Writes a board cell after RustScript has accepted a move. #[pd_host_function(name = "bevy::Gomoku::set_cell")] pub(crate) fn gomoku_set_cell_impl(x: i64, y: i64, stone: i64) -> VmResult { @@ -1740,10 +1714,6 @@ mod host { }) } - pub(crate) fn gomoku_set_cell_host(args: &[Value]) -> VmResult { - return_one(gomoku_set_cell(args)) - } - /// Publishes RustScript move legality and board outcome. #[pd_host_function(name = "bevy::Gomoku::set_move_result")] pub(crate) fn gomoku_set_move_result_impl( @@ -1761,10 +1731,6 @@ mod host { }) } - pub(crate) fn gomoku_set_move_result_host(args: &[Value]) -> VmResult { - return_one(gomoku_set_move_result(args)) - } - /// Publishes the RustScript-selected AI move. #[pd_host_function(name = "bevy::Gomoku::set_ai_move")] pub(crate) fn gomoku_set_ai_move_impl(x: i64, y: i64) -> VmResult { @@ -1776,37 +1742,18 @@ mod host { }) } - pub(crate) fn gomoku_set_ai_move_host(args: &[Value]) -> VmResult { - return_one(gomoku_set_ai_move(args)) + fn xiangqi_board_contract() -> vm::HostFunctionSchema { + vm::HostFunctionSchema::with_return( + "bevy::Xiangqi::board", + Vec::new(), + HostTypeSchema::Array(Box::new(HostTypeSchema::Int)), + ) } - /// Returns the Xiangqi board width for RustScript scans. - #[pd_host_function(name = "bevy::Xiangqi::board_width")] - pub(crate) fn xiangqi_board_width_impl() -> VmResult { - with_xiangqi_world(|_world| Ok(XIANGQI_BOARD_WIDTH)) - } - - pub(crate) fn xiangqi_board_width_host(args: &[Value]) -> VmResult { - return_one(xiangqi_board_width(args)) - } - - /// Returns the Xiangqi board height for RustScript scans. - #[pd_host_function(name = "bevy::Xiangqi::board_height")] - pub(crate) fn xiangqi_board_height_impl() -> VmResult { - with_xiangqi_world(|_world| Ok(XIANGQI_BOARD_HEIGHT)) - } - - pub(crate) fn xiangqi_board_height_host(args: &[Value]) -> VmResult { - return_one(xiangqi_board_height(args)) - } - - pub(crate) fn xiangqi_board_host(args: &[Value]) -> VmResult { - if !args.is_empty() { - return Err(VmError::HostError( - "bevy::Xiangqi::board expects no arguments".to_string(), - )); - } - let board = with_xiangqi_world(|world| { + /// Returns the Xiangqi board cells in row-major order as a typed `[int]`. + #[pd_host_function(name = "bevy::Xiangqi::board", contract = xiangqi_board_contract)] + pub(crate) fn xiangqi_board_impl() -> VmResult { + with_xiangqi_world(|world| { ensure_xiangqi_resources(world); Ok(Value::array( world @@ -1817,8 +1764,19 @@ mod host { .map(Value::Int) .collect(), )) - })?; - Ok(CallOutcome::Return(CallReturn::one(board))) + }) + } + + /// Returns the Xiangqi board width for RustScript scans. + #[pd_host_function(name = "bevy::Xiangqi::board_width")] + pub(crate) fn xiangqi_board_width_impl() -> VmResult { + with_xiangqi_world(|_world| Ok(XIANGQI_BOARD_WIDTH)) + } + + /// Returns the Xiangqi board height for RustScript scans. + #[pd_host_function(name = "bevy::Xiangqi::board_height")] + pub(crate) fn xiangqi_board_height_impl() -> VmResult { + with_xiangqi_world(|_world| Ok(XIANGQI_BOARD_HEIGHT)) } /// Reads a Xiangqi cell; out-of-bounds cells return a sentinel value. @@ -1831,10 +1789,6 @@ mod host { }) } - pub(crate) fn xiangqi_cell_host(args: &[Value]) -> VmResult { - return_one(xiangqi_cell(args)) - } - /// Writes a Xiangqi cell after RustScript has accepted a move. #[pd_host_function(name = "bevy::Xiangqi::set_cell")] pub(crate) fn xiangqi_set_cell_impl(x: i64, y: i64, piece: i64) -> VmResult { @@ -1845,10 +1799,6 @@ mod host { }) } - pub(crate) fn xiangqi_set_cell_host(args: &[Value]) -> VmResult { - return_one(xiangqi_set_cell(args)) - } - /// Publishes RustScript move legality and winner. #[pd_host_function(name = "bevy::Xiangqi::set_move_result")] pub(crate) fn xiangqi_set_move_result_impl(legal: bool, winner: i64) -> VmResult { @@ -1861,10 +1811,6 @@ mod host { }) } - pub(crate) fn xiangqi_set_move_result_host(args: &[Value]) -> VmResult { - return_one(xiangqi_set_move_result(args)) - } - /// Publishes the RustScript-selected Xiangqi move. #[pd_host_function(name = "bevy::Xiangqi::set_ai_move")] pub(crate) fn xiangqi_set_ai_move_impl( @@ -1880,9 +1826,5 @@ mod host { Ok(true) }) } - - pub(crate) fn xiangqi_set_ai_move_host(args: &[Value]) -> VmResult { - return_one(xiangqi_set_ai_move(args)) - } } } diff --git a/tests/example_smoke.rs b/tests/example_smoke.rs index dc291f0..3e3fb4a 100644 --- a/tests/example_smoke.rs +++ b/tests/example_smoke.rs @@ -16,7 +16,9 @@ fn run_script_smoke_from_empty_cwd(example: &str) -> Output { let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); let manifest = manifest_dir.join("Cargo.toml"); - let target_dir = manifest_dir.join("target").join("script-smoke"); + let target_dir = std::env::var_os("CARGO_TARGET_DIR") + .map(PathBuf::from) + .unwrap_or_else(|| manifest_dir.join("target").join("script-smoke")); let output = Command::new(std::env::var("CARGO").unwrap_or_else(|_| "cargo".to_string())) .args([ "run", diff --git a/tests/host_descriptors.rs b/tests/host_descriptors.rs new file mode 100644 index 0000000..c2af813 --- /dev/null +++ b/tests/host_descriptors.rs @@ -0,0 +1,563 @@ +use std::{ + collections::BTreeSet, + fs, + path::{Path, PathBuf}, +}; + +use bevy_ecs::prelude::*; +use pretty_assertions::assert_eq; +use rustscript_bevy_gameplay::{ + Armor, FROZEN_RUSTSCRIPT_REV, Health, bevy_host_catalog, bevy_host_modules, + compile_bevy_script, install_bevy_host_modules, +}; +use vm::{ + CompileSourceFileOptions, HostApiCatalog, HostFunctionDescriptor, HostFunctionRegistry, + HostFunctionSchema, HostTypeSchema, SourceFlavor, Vm, VmError, + compile_source_with_flavor_and_options, +}; + +/// Exact hex form of [`bevy_host_catalog`]'s fingerprint (`Display` is 16 +/// lowercase hex digits). Bump together with [`BEVY_HOST_CATALOG_FINGERPRINT_U64`] +/// when the guest catalog surface or frozen pd-vm fingerprint encoding changes. +/// See [`bevy_host_catalog`] for the full policy. +const BEVY_HOST_CATALOG_FINGERPRINT_HEX: &str = "61e3eaf5de92afc7"; +/// Exact `u64` form of the same digest. Keep in lockstep with the hex snapshot. +const BEVY_HOST_CATALOG_FINGERPRINT_U64: u64 = 0x61e3eaf5de92afc7; + +const LISTED_HOST_SOURCE: &str = "use bevy;\nbevy::World::contains_entity();\n"; +const UNLISTED_HOST_SOURCE: &str = "use bevy;\nbevy::World::not_a_host();\n"; +const LISTED_HOST_NAME: &str = "bevy::World::contains_entity"; +const UNLISTED_HOST_NAME: &str = "bevy::World::not_a_host"; +const LATE_FAILURE_HOST_NAME: &str = "bevy::Xiangqi::board"; + +const EXPECTED_HOST_NAMES: &[&str] = &[ + "bevy::World::contains_entity", + "bevy::World::get_health", + "bevy::World::get_armor", + "bevy::World::set_health", + "bevy::Shooter::set_player_health", + "bevy::Shooter::set_player_attack", + "bevy::Shooter::set_player_projectiles", + "bevy::Shooter::spawn_enemy", + "bevy::Shooter::spawn_reward", + "bevy::Shooter::spawn_enemy_every", + "bevy::Shooter::spawn_reward_every", + "bevy::Shooter::spawn_enemy_after_kills", + "bevy::Gomoku::board", + "bevy::Gomoku::board_size", + "bevy::Gomoku::cell", + "bevy::Gomoku::set_cell", + "bevy::Gomoku::set_move_result", + "bevy::Gomoku::set_ai_move", + "bevy::Xiangqi::board", + "bevy::Xiangqi::board_width", + "bevy::Xiangqi::board_height", + "bevy::Xiangqi::cell", + "bevy::Xiangqi::set_cell", + "bevy::Xiangqi::set_move_result", + "bevy::Xiangqi::set_ai_move", +]; + +fn compose_catalog() -> HostApiCatalog { + let descriptors: Vec<_> = bevy_host_modules() + .iter() + .flat_map(|module| module.descriptors()) + .collect(); + HostFunctionDescriptor::collect_catalog(&descriptors).expect("composed catalog") +} + +fn compile_rss( + source: &str, + catalog: Option>, +) -> Result { + let mut options = CompileSourceFileOptions::default(); + if let Some(catalog) = catalog { + options = options.with_host_api_catalog(catalog); + } + compile_source_with_flavor_and_options(source, SourceFlavor::RustScript, options) +} + +fn catalog_from_functions( + functions: impl IntoIterator, +) -> HostApiCatalog { + let production = bevy_host_catalog(); + assert!( + production.resources().is_empty(), + "Bevy composition has no guest resources; resource rollback is N/A" + ); + assert!( + production.structs().is_empty(), + "Bevy composition has no named structs; named-struct catalog rollback is N/A" + ); + let mut builder = HostApiCatalog::builder(); + for function in functions { + builder.function(function); + } + builder.build().expect("test catalog must validate") +} + +fn late_failure_xiangqi_catalog() -> HostApiCatalog { + catalog_from_functions(bevy_host_catalog().functions().iter().map(|function| { + let mut function = function.clone(); + if function.name == LATE_FAILURE_HOST_NAME { + assert_eq!( + function.return_type, + HostTypeSchema::Array(Box::new(HostTypeSchema::Int)), + "late-failure fixture must start from the production board return" + ); + function.return_type = HostTypeSchema::Int; + } + function + })) +} + +fn catalog_with_unlisted_host() -> std::sync::Arc { + let mut functions: Vec<_> = bevy_host_catalog().functions().to_vec(); + functions.push(HostFunctionSchema::with_return( + UNLISTED_HOST_NAME, + Vec::new(), + HostTypeSchema::Bool, + )); + std::sync::Arc::new(catalog_from_functions(functions)) +} + +fn cargo_lock_package_source(lock: &str, crate_name: &str) -> Option { + let mut current_name: Option<&str> = None; + for line in lock.lines() { + let line = line.trim(); + if line == "[[package]]" { + current_name = None; + continue; + } + if let Some(name) = line + .strip_prefix("name = \"") + .and_then(|rest| rest.strip_suffix('"')) + { + current_name = Some(name); + continue; + } + if let Some(source) = line + .strip_prefix("source = \"") + .and_then(|rest| rest.strip_suffix('"')) + && current_name == Some(crate_name) + { + return Some(source.to_string()); + } + } + None +} + +fn assert_bevy_hosts_absent(registry: &HostFunctionRegistry) { + for name in EXPECTED_HOST_NAMES { + assert!( + !registry.contains_name(name), + "failed composition must not leave {name} installed" + ); + } +} + +fn assert_listed_bind_denied(registry: &HostFunctionRegistry) { + let compiled = compile_rss(LISTED_HOST_SOURCE, Some(bevy_host_catalog())) + .expect("listed host compiles against the production catalog"); + assert!( + compiled + .program + .imports + .iter() + .any(|import| import.name == LISTED_HOST_NAME), + "listed compile must record the exact host import, not an unknown-name elision" + ); + let mut vm = Vm::new(compiled.program); + match registry.bind_vm_cached(&mut vm) { + Err(VmError::UnboundImport(name)) => { + assert_eq!(name, LISTED_HOST_NAME); + } + Err(VmError::HostError(message)) + if message.contains("capability profile does not allow") => + { + panic!( + "listed bind was capability-denied; rollback must drop the registry entry entirely: {message}" + ); + } + other => panic!("listed bind must be denied as UnboundImport, got {other:?}"), + } +} + +fn schema_is_dynamic(schema: &HostTypeSchema) -> bool { + match schema { + HostTypeSchema::Unknown | HostTypeSchema::Map(_) => true, + HostTypeSchema::Array(inner) | HostTypeSchema::Optional(inner) => schema_is_dynamic(inner), + HostTypeSchema::Callable { params, result } => { + params.iter().any(schema_is_dynamic) || schema_is_dynamic(result) + } + HostTypeSchema::Named { fields, .. } => { + fields.iter().any(|field| schema_is_dynamic(&field.ty)) + } + _ => false, + } +} + +fn bundled_rss_scripts() -> Vec { + let dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("scripts"); + let mut paths: Vec = fs::read_dir(&dir) + .expect("scripts dir") + .map(|entry| entry.expect("script entry").path()) + .filter(|path| path.extension().and_then(|ext| ext.to_str()) == Some("rss")) + .collect(); + paths.sort(); + paths +} + +#[test] +fn composition_owns_every_host_function_in_declaration_order() { + let modules = bevy_host_modules(); + assert_eq!( + modules.iter().map(|module| module.name).collect::>(), + ["bevy.world", "bevy.shooter", "bevy.gomoku", "bevy.xiangqi"] + ); + + let names: Vec = modules + .iter() + .flat_map(|module| module.descriptors()) + .map(|descriptor| descriptor.schema.name.clone()) + .collect(); + assert_eq!(names, EXPECTED_HOST_NAMES); + + let unique: BTreeSet<_> = names.iter().cloned().collect(); + assert_eq!( + unique.len(), + names.len(), + "host function names must be unique" + ); + + let catalog_names: Vec = bevy_host_catalog() + .functions() + .iter() + .map(|function| function.name.clone()) + .collect(); + assert_eq!(catalog_names, names); +} + +#[test] +fn catalog_fingerprint_matches_golden_hex_and_u64() { + // Snapshot policy is documented on `bevy_host_catalog`: bump both constants + // together when the guest surface or frozen pd-vm fingerprint encoding + // changes. Adapter bodies, TLS/HostState, timings, and docs must not. + let first = compose_catalog(); + let second = compose_catalog(); + let production = bevy_host_catalog(); + assert_eq!(first.fingerprint(), second.fingerprint()); + assert_eq!(first.fingerprint(), production.fingerprint()); + + let fingerprint = first.fingerprint(); + assert_eq!(format!("{fingerprint}"), BEVY_HOST_CATALOG_FINGERPRINT_HEX); + assert_eq!(fingerprint.as_u64(), BEVY_HOST_CATALOG_FINGERPRINT_U64); + assert_eq!( + format!("{:016x}", fingerprint.as_u64()), + BEVY_HOST_CATALOG_FINGERPRINT_HEX + ); + + let board = first + .functions_named("bevy::Gomoku::board") + .into_iter() + .next() + .expect("gomoku board schema"); + assert_eq!(board.params.len(), 0); + assert_eq!( + board.return_type, + HostTypeSchema::Array(Box::new(HostTypeSchema::Int)) + ); + + let health = first + .functions_named("bevy::World::get_health") + .into_iter() + .next() + .expect("get_health schema"); + assert_eq!(health.params.len(), 0); + assert_eq!(health.return_type, HostTypeSchema::Int); +} + +#[test] +fn dynamic_map_any_unknown_allowlist_is_empty() { + // Guest host returns are bool, int, or Array(Int). World/entity access is a + // raw host-private thread-local boundary, not a guest Map/Unknown slot. + let catalog = bevy_host_catalog(); + let mut dynamic = Vec::new(); + for function in catalog.functions() { + if schema_is_dynamic(&function.return_type) { + dynamic.push(format!("{} return", function.name)); + } + for param in &function.params { + if schema_is_dynamic(¶m.ty) { + dynamic.push(format!("{} param {}", function.name, param.name)); + } + } + } + assert_eq!(dynamic, Vec::::new()); +} + +#[test] +fn listed_host_does_not_compile_without_catalog() { + match compile_rss(LISTED_HOST_SOURCE, None) { + Err(error) => { + let message = error.to_string(); + assert!( + !message.contains("UnboundImport") + && !message.to_lowercase().contains("unbound import"), + "compiler unknown-name failure must not masquerade as a bind error: {message}" + ); + assert!( + message.contains(LISTED_HOST_NAME) + || message.contains("unknown") + || message.contains("not found") + || message.contains("host") + || message.contains("namespace"), + "compile-without-catalog error should name the missing host or catalog: {message}" + ); + } + Ok(compiled) => { + assert!( + compiled + .program + .host_import_schemas() + .iter() + .all(|schema| schema + .as_ref() + .is_none_or(|schema| schema.name != LISTED_HOST_NAME)), + "without a catalog the listed host must not receive exact import schemas" + ); + } + } +} + +#[test] +fn listed_host_compiles_against_production_catalog() { + let compiled = compile_rss(LISTED_HOST_SOURCE, Some(bevy_host_catalog())) + .expect("listed host compiles against the production catalog"); + assert!( + compiled + .program + .imports + .iter() + .any(|import| import.name == LISTED_HOST_NAME && import.arity == 0), + "production catalog compile must emit the listed host import" + ); + assert!( + compiled + .program + .host_import_schemas() + .iter() + .any(|schema| schema + .as_ref() + .is_some_and(|schema| schema.name == LISTED_HOST_NAME)), + "production catalog compile must emit exact host import schemas" + ); +} + +#[test] +fn restricted_registry_denies_listed_host_before_install() { + let registry = HostFunctionRegistry::restricted(); + assert_bevy_hosts_absent(®istry); + assert_listed_bind_denied(®istry); +} + +#[test] +fn production_install_allows_listed_host_bind() { + let catalog = bevy_host_catalog(); + let mut registry = HostFunctionRegistry::restricted(); + install_bevy_host_modules(&mut registry, catalog.as_ref()).expect("install composition"); + for name in EXPECTED_HOST_NAMES { + assert!( + registry.contains_name(name), + "restricted registry missing {name}" + ); + } + let compiled = compile_rss(LISTED_HOST_SOURCE, Some(catalog)) + .expect("listed host compiles against the production catalog"); + let mut vm = Vm::new(compiled.program); + registry + .bind_vm_cached(&mut vm) + .expect("production install must allow the listed host"); +} + +#[test] +fn unlisted_host_is_denied_at_bind_when_compilation_reaches_bind() { + let extra_catalog = catalog_with_unlisted_host(); + let compiled = compile_rss(UNLISTED_HOST_SOURCE, Some(extra_catalog)) + .expect("unlisted host must compile when the catalog is constructed to include it"); + assert!( + compiled + .program + .imports + .iter() + .any(|import| import.name == UNLISTED_HOST_NAME), + "unlisted compile must reach bind with the extra import recorded" + ); + + let production = bevy_host_catalog(); + let mut registry = HostFunctionRegistry::restricted(); + install_bevy_host_modules(&mut registry, production.as_ref()).expect("install composition"); + assert!( + !registry.contains_name(UNLISTED_HOST_NAME), + "production registry must not install the unlisted host" + ); + + let mut vm = Vm::new(compiled.program); + match registry.bind_vm_cached(&mut vm) { + Err(VmError::UnboundImport(name)) => assert_eq!(name, UNLISTED_HOST_NAME), + other => panic!("unlisted import must be denied at bind as UnboundImport, got {other:?}"), + } +} + +#[test] +fn transactional_install_rolls_back_when_later_module_schema_does_not_match() { + let mut registry = HostFunctionRegistry::restricted(); + let named_structs_before = registry.named_struct_schemas().clone(); + let inert = compile_rss("1;\n", None).expect("inert program compiles without a host catalog"); + assert!( + inert.program.imports.is_empty(), + "generation probe must not introduce host imports" + ); + let generation_plan = registry + .prepare_plan(&inert.program.imports) + .expect("empty-import plan is the observable generation/capability snapshot"); + + let late_failure = late_failure_xiangqi_catalog(); + let error = install_bevy_host_modules(&mut registry, &late_failure) + .expect_err("install must enter the composition transaction and fail on the last module"); + let message = error.to_string(); + assert!( + message.contains(LATE_FAILURE_HOST_NAME), + "late-failure catalog must reach xiangqi schema/adapter mismatch, got: {message}" + ); + assert!( + !message.contains("bevy::World::contains_entity") + && !message.contains("bevy.world") + && !message.to_lowercase().contains("empty catalog"), + "failure must not be an early empty-catalog validation miss: {message}" + ); + + assert_bevy_hosts_absent(®istry); + assert_listed_bind_denied(®istry); + assert_eq!( + registry.named_struct_schemas(), + &named_structs_before, + "named-struct table must be unchanged after rollback" + ); + + let mut vm = Vm::new(inert.program); + registry + .bind_vm_with_plan(&mut vm, &generation_plan) + .expect("rollback must leave registry generation and capability snapshot unchanged"); +} + +#[test] +fn rustscript_crates_are_pinned_to_the_frozen_full_sha() { + let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let cargo_toml = fs::read_to_string(manifest_dir.join("Cargo.toml")).expect("Cargo.toml"); + let cargo_lock = fs::read_to_string(manifest_dir.join("Cargo.lock")).expect("Cargo.lock"); + assert!( + cargo_toml.contains(FROZEN_RUSTSCRIPT_REV), + "Cargo.toml must pin the frozen full SHA" + ); + assert!( + !cargo_toml.contains("path = \"../rustscript"), + "production RustScript crates must not use sibling path deps" + ); + let expected_source = format!( + "git+https://github.com/rustscript-lang/rustscript?rev={FROZEN_RUSTSCRIPT_REV}#{FROZEN_RUSTSCRIPT_REV}" + ); + for crate_name in ["pd-vm", "pd-host-function", "pd-host-schema"] { + let source = cargo_lock_package_source(&cargo_lock, crate_name) + .unwrap_or_else(|| panic!("{crate_name} must appear with a source in Cargo.lock")); + assert_eq!( + source, expected_source, + "{crate_name} must resolve to the frozen git SHA" + ); + } +} + +#[test] +fn bundled_rss_examples_compile_through_the_production_catalog() { + let scripts = bundled_rss_scripts(); + assert_eq!( + scripts + .iter() + .map(|path| path.file_name().unwrap().to_string_lossy().into_owned()) + .collect::>(), + [ + "damage_formula.rss", + "gomoku_ai.rss", + "gomoku_move.rss", + "shooter_game.rss", + "xiangqi_ai.rss", + "xiangqi_move.rss", + ] + ); + for path in scripts { + compile_rss_file(&path); + } +} + +#[test] +fn exact_binding_runs_damage_formula_against_live_ecs() { + let mut world = World::new(); + world.insert_resource( + rustscript_bevy_gameplay::DamageRules::from_source(include_str!( + "../scripts/damage_formula.rss" + )) + .expect("damage formula compiles through the production catalog"), + ); + let entity = world.spawn((Health(30), Armor(4))).id(); + let applied = rustscript_bevy_gameplay::apply_scripted_damage(&mut world, entity, 10, false) + .expect("damage applies through exact composed binding"); + assert_eq!(applied, 6); + assert_eq!(world.get::(entity).unwrap().0, 24); +} + +fn compile_rss_file(path: &Path) { + let source = + fs::read_to_string(path).unwrap_or_else(|err| panic!("read {}: {err}", path.display())); + let wrapped = match path.file_name().and_then(|name| name.to_str()) { + Some("damage_formula.rss") => { + format!("let incoming = 0;\nlet critical = false;\n{source}") + } + Some("gomoku_move.rss") => { + format!("let move_x: int = 0;\nlet move_y: int = 0;\nlet player: int = 1;\n{source}") + } + Some("gomoku_ai.rss") => { + format!("let ai_player: int = 1;\nlet ai_bias: int = 0;\n{source}") + } + Some("xiangqi_move.rss") => format!( + "let from_x: int = 0;\nlet from_y: int = 0;\nlet to_x: int = 0;\nlet to_y: int = 0;\nlet player: int = 1;\n{source}" + ), + Some("xiangqi_ai.rss") => { + format!("let ai_player: int = 1;\nlet ai_bias: int = 0;\n{source}") + } + _ => source, + }; + compile_bevy_script(&wrapped) + .unwrap_or_else(|err| panic!("{} failed to compile: {err}", path.display())); +} + +#[test] +fn composed_registry_executes_contains_entity_without_world_context_error_shape() { + // Without a live Bevy context the host still binds exactly; the raw + // world/entity boundary reports a host error instead of an unbound import. + let catalog = bevy_host_catalog(); + let compiled = compile_source_with_flavor_and_options( + "use bevy;\nbevy::World::contains_entity();\n", + SourceFlavor::RustScript, + CompileSourceFileOptions::default().with_host_api_catalog(catalog.clone()), + ) + .expect("compile"); + let mut vm = Vm::new(compiled.program); + let mut registry = HostFunctionRegistry::restricted(); + install_bevy_host_modules(&mut registry, catalog.as_ref()).expect("install"); + registry.bind_vm_cached(&mut vm).expect("bind"); + let error = vm.run().expect_err("missing world context is a host error"); + assert!( + error.to_string().contains("missing Bevy World context"), + "unexpected error: {error}" + ); +}