diff --git a/.github/ci_generator/templates/job_steps/build_docs.jinja b/.github/ci_generator/templates/job_steps/build_docs.jinja index 9c4a33fbd..7e90cd62b 100644 --- a/.github/ci_generator/templates/job_steps/build_docs.jinja +++ b/.github/ci_generator/templates/job_steps/build_docs.jinja @@ -41,8 +41,10 @@ --exclude-path="site/api_reference/settings.html" --exclude-path="site/404.html" --exclude=".*crate#per-style$" + --exclude=".*#setting-the-default-subscriber$" --exclude="https://doc.rust-lang.org/*" --exclude="https://stackoverflow.com/*" + --exclude="https://rust-random.github.io/*" --exclude="https://github.com/LukeMathWalker/pavex/edit/main/*" --exclude="https://docs.rs/**/*" --exclude-path="site/api_reference/static.files" diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 643ef68f5..ce8a8caf2 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -1749,8 +1749,10 @@ jobs: --exclude-path="site/api_reference/settings.html" --exclude-path="site/404.html" --exclude=".*crate#per-style$" + --exclude=".*#setting-the-default-subscriber$" --exclude="https://doc.rust-lang.org/*" --exclude="https://stackoverflow.com/*" + --exclude="https://rust-random.github.io/*" --exclude="https://github.com/LukeMathWalker/pavex/edit/main/*" --exclude="https://docs.rs/**/*" --exclude-path="site/api_reference/static.files" diff --git a/.gitignore b/.gitignore index 2cdcc1149..5a807ca48 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,5 @@ trace-*.json .direnv/ site target +# The file generated by `samply` when tracing execution +profile.json diff --git a/Cargo.lock b/Cargo.lock index 219c91cf0..84c41f70c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -77,9 +77,9 @@ dependencies = [ [[package]] name = "aligned" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "377e4c0ba83e4431b10df45c1d4666f178ea9c552cac93e60c3a88bf32785923" +checksum = "ee4508988c62edf04abd8d92897fca0c2995d907ce1dfeaf369dac3716a40685" dependencies = [ "as-slice", ] @@ -254,9 +254,9 @@ dependencies = [ [[package]] name = "aws-lc-rs" -version = "1.15.0" +version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5932a7d9d28b0d2ea34c6b3779d35e3dd6f6345317c34e73438c4f1f29144151" +checksum = "6a88aab2464f1f25453baa7a07c84c5b7684e274054ba06817f382357f77a288" dependencies = [ "aws-lc-fips-sys", "aws-lc-sys", @@ -265,11 +265,10 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.33.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1826f2e4cfc2cd19ee53c42fbf68e2f81ec21108e0b7ecf6a71cf062137360fc" +checksum = "b45afffdee1e7c9126814751f88dddc747f41d91da16c9551a0f1e8a11e788a1" dependencies = [ - "bindgen", "cc", "cmake", "dunce", @@ -323,9 +322,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" +checksum = "0e050f626429857a27ddccb31e0aca21356bfa709c04041aefddac081a8f068a" [[package]] name = "better-panic" @@ -369,7 +368,7 @@ version = "0.72.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" dependencies = [ - "bitflags 2.10.0", + "bitflags", "cexpr", "clang-sys", "itertools 0.13.0", @@ -402,12 +401,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - [[package]] name = "bitflags" version = "2.10.0" @@ -438,9 +431,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.19.0" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" [[package]] name = "bytemuck" @@ -462,9 +455,9 @@ checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" [[package]] name = "camino" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "276a59bf2b2c967788139340c9f0c5b12d7fd6630315c15c217e559de85d2609" +checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" dependencies = [ "serde_core", ] @@ -502,11 +495,12 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "122ec45a44b270afd1402f351b782c676b173e3c3fb28d86ff7ebfb4d86a4ee4" +checksum = "87a0c0e6148f11f01f32650a2ea02d532b2ad4e81d8bd41e6e565b5adc5e6082" dependencies = [ "serde", + "serde_core", ] [[package]] @@ -525,9 +519,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.46" +version = "1.2.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97463e1064cb1b1c1384ad0a0b9c8abd0988e2a91f52606c80ef14aadb63e36" +checksum = "9f50d563227a1c37cc0a263f64eca3334388c01c5e4c4861a9def205c614383c" dependencies = [ "find-msvc-tools", "jobserver", @@ -552,9 +546,9 @@ dependencies = [ [[package]] name = "cfg-expr" -version = "0.20.4" +version = "0.20.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9acd0bdbbf4b2612d09f52ba61da432140cb10930354079d0d53fafc12968726" +checksum = "21be0e1ce6cdb2ee7fff840f922fb04ead349e5cfb1e750b769132d44ce04720" dependencies = [ "smallvec", "target-lexicon", @@ -595,9 +589,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.51" +version = "4.5.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c26d721170e0295f191a69bd9a1f93efcdb0aff38684b61ab5750468972e5f5" +checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" dependencies = [ "clap_builder", "clap_derive", @@ -605,18 +599,18 @@ dependencies = [ [[package]] name = "clap-stdin" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce9eaafece93d07ba62941de901e54d8df03800b7d775000d0d8cd5f876a592d" +checksum = "d80e97074da664d8e2c49e82cba54c40b9cec15c73810d90bf6a78261ab3ccaa" dependencies = [ "thiserror 2.0.17", ] [[package]] name = "clap_builder" -version = "4.5.51" +version = "4.5.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75835f0c7bf681bfd05abe44e965760fea999a5286c6eb2d59883634fd02011a" +checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" dependencies = [ "anstream", "anstyle", @@ -644,9 +638,9 @@ checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "cmake" -version = "0.1.54" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" +checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d" dependencies = [ "cc", ] @@ -690,12 +684,12 @@ dependencies = [ "convert_case 0.6.0", "json5", "pathdiff", - "ron 0.12.0", + "ron", "rust-ini", "serde-untagged", "serde_core", "serde_json", - "toml 0.9.8", + "toml 0.9.10+spec-1.1.0", "winnow", "yaml-rust2", ] @@ -714,9 +708,9 @@ dependencies = [ [[package]] name = "console" -version = "0.16.1" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b430743a6eb14e9764d4260d4c0d8123087d504eeb9c48f2b2a5e810dd369df4" +checksum = "03e45a4a8926227e4197636ba97a9fc9b00477e9f4bd711395687c5f0734bec4" dependencies = [ "encode_unicode", "libc", @@ -762,9 +756,9 @@ dependencies = [ [[package]] name = "convert_case" -version = "0.8.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baaaa0ecca5b51987b9423ccdc971514dd8b0bb7b4060b983d3664dad3f1f89f" +checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9" dependencies = [ "unicode-segmentation", ] @@ -825,9 +819,9 @@ dependencies = [ [[package]] name = "crc" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9710d3b3739c2e349eb44fe848ad0b7c8cb1e42bd87ee49371df2f7acaf3e675" +checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d" dependencies = [ "crc-catalog", ] @@ -967,12 +961,12 @@ dependencies = [ [[package]] name = "darling" -version = "0.21.3" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" +checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" dependencies = [ - "darling_core 0.21.3", - "darling_macro 0.21.3", + "darling_core 0.23.0", + "darling_macro 0.23.0", ] [[package]] @@ -991,11 +985,10 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.21.3" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" +checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" dependencies = [ - "fnv", "ident_case", "proc-macro2", "quote", @@ -1016,11 +1009,11 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.21.3" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" +checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" dependencies = [ - "darling_core 0.21.3", + "darling_core 0.23.0", "quote", "syn", ] @@ -1415,9 +1408,9 @@ dependencies = [ [[package]] name = "fs-err" -version = "3.2.0" +version = "3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62d91fd049c123429b018c47887d3f75a265540dd3c30ba9cb7bae9197edb03a" +checksum = "824f08d01d0f496b3eca4f001a13cf17690a6ee930043d20817f547455fd98f8" dependencies = [ "autocfg", ] @@ -1492,7 +1485,7 @@ checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" dependencies = [ "futures-core", "lock_api", - "parking_lot 0.12.5", + "parking_lot", ] [[package]] @@ -1557,7 +1550,7 @@ dependencies = [ "regex", "sanitize-filename", "tempfile", - "toml 0.9.8", + "toml 0.9.10+spec-1.1.0", "tracing", "walkdir", ] @@ -1631,7 +1624,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757" dependencies = [ - "bitflags 2.10.0", + "bitflags", "ignore", "walkdir", ] @@ -1744,9 +1737,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" [[package]] name = "hashlink" @@ -1813,12 +1806,11 @@ dependencies = [ [[package]] name = "http" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" dependencies = [ "bytes", - "fnv", "itoa", ] @@ -1899,9 +1891,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52e9a2a24dc5c6821e71a7030e1e14b7b632acac55c40e9d2e082c621261bb56" +checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f" dependencies = [ "base64", "bytes", @@ -1969,9 +1961,9 @@ checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" [[package]] name = "icu_properties" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" dependencies = [ "icu_collections", "icu_locale_core", @@ -1983,9 +1975,9 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" [[package]] name = "icu_provider" @@ -2066,12 +2058,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.12.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" +checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" dependencies = [ "equivalent", - "hashbrown 0.16.0", + "hashbrown 0.16.1", "serde", "serde_core", ] @@ -2082,7 +2074,7 @@ version = "0.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9375e112e4b463ec1b1c6c011953545c65a30164fbab5b581df32b3abf0dcb88" dependencies = [ - "console 0.16.1", + "console 0.16.2", "portable-atomic", "unicode-width 0.2.2", "unit-prefix", @@ -2106,25 +2098,14 @@ dependencies = [ [[package]] name = "insta" -version = "1.43.2" +version = "1.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fdb647ebde000f43b5b53f773c30cf9b0cb4300453208713fa38b2c70935a0" +checksum = "b76866be74d68b1595eb8060cb9191dca9c021db2316558e52ddc5d55d41b66c" dependencies = [ "console 0.15.11", "once_cell", "similar", -] - -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", + "tempfile", ] [[package]] @@ -2218,9 +2199,9 @@ dependencies = [ [[package]] name = "jiff-tzdb" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1283705eb0a21404d2bfd6eef2a7593d240bc42a0bdb39db0ad6fa2ec026524" +checksum = "68971ebff725b9e2ca27a601c5eb38a4c5d64422c4cbab0c535f248087eda5c2" [[package]] name = "jiff-tzdb-platform" @@ -2265,9 +2246,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.82" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65" +checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" dependencies = [ "once_cell", "wasm-bindgen", @@ -2334,9 +2315,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.177" +version = "0.2.178" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" +checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" [[package]] name = "libloading" @@ -2356,13 +2337,13 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "libredox" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" +checksum = "df15f6eac291ed1cf25865b1ee60399f57e7c227e7f51bdbd4c5270396a9ed50" dependencies = [ - "bitflags 2.10.0", + "bitflags", "libc", - "redox_syscall 0.5.18", + "redox_syscall 0.6.0", ] [[package]] @@ -2471,9 +2452,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.28" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "lru-slab" @@ -2517,6 +2498,12 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f926ade0c4e170215ae43342bf13b9310a437609c81f29f86c5df6657582ef9" +[[package]] +name = "matchit" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea5f97102eb9e54ab99fb70bb175589073f554bdadfb74d9bd656482ea73e2a" + [[package]] name = "md-5" version = "0.10.6" @@ -2587,15 +2574,35 @@ dependencies = [ [[package]] name = "mio" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" +checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" dependencies = [ "libc", "wasi", "windows-sys 0.61.2", ] +[[package]] +name = "munge" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e17401f259eba956ca16491461b6e8f72913a0a114e39736ce404410f915a0c" +dependencies = [ + "munge_macro", +] + +[[package]] +name = "munge_macro" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4568f25ccbd45ab5d5603dc34318c1ec56b117531781260002151b8530a9f931" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "nested" version = "0.1.1" @@ -2608,7 +2615,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.10.0", + "bitflags", "cfg-if", "cfg_aliases", "libc", @@ -2747,7 +2754,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ceffa2e6ccecd71e60a0f06b655df2c66acd1c0c892dafefc96fd49d65f71d53" dependencies = [ - "parking_lot 0.12.5", + "parking_lot", ] [[package]] @@ -2820,17 +2827,6 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.6", -] - [[package]] name = "parking_lot" version = "0.12.5" @@ -2838,21 +2834,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", - "parking_lot_core 0.9.12", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "winapi", + "parking_lot_core", ] [[package]] @@ -2921,7 +2903,7 @@ dependencies = [ "insta", "itertools 0.14.0", "jiff", - "matchit", + "matchit 0.9.0", "mime", "paste", "pavex_bp_schema", @@ -2932,7 +2914,7 @@ dependencies = [ "pin-project-lite", "px_workspace_hack", "reqwest", - "ron 0.11.0", + "ron", "rustls", "rustls-platform-verifier", "secrecy", @@ -2956,6 +2938,7 @@ dependencies = [ name = "pavex_bp_schema" version = "0.2.10" dependencies = [ + "bincode", "px_workspace_hack", "serde", ] @@ -3009,7 +2992,7 @@ dependencies = [ "tempfile", "thiserror 2.0.17", "tokio", - "toml 0.9.8", + "toml 0.9.10+spec-1.1.0", "tracing", "tracing-chrome", "tracing-subscriber", @@ -3080,8 +3063,8 @@ dependencies = [ name = "pavex_macros" version = "0.2.10" dependencies = [ - "convert_case 0.8.0", - "darling 0.21.3", + "convert_case 0.10.0", + "darling 0.23.0", "paste", "pavex", "pavexc_attr_parser", @@ -3108,6 +3091,17 @@ dependencies = [ "unicode-width 0.2.2", ] +[[package]] +name = "pavex_rustdoc_types" +version = "0.2.10" +dependencies = [ + "bincode", + "rkyv", + "rustc-hash", + "serde", + "serde_derive", +] + [[package]] name = "pavex_session" version = "0.2.10" @@ -3186,8 +3180,9 @@ version = "0.2.10" dependencies = [ "ahash", "anyhow", + "cargo-like-utils", "cargo_metadata", - "console 0.16.1", + "console 0.16.2", "fs-err", "globwalk", "guppy", @@ -3197,6 +3192,7 @@ dependencies = [ "num_cpus", "object-pool", "once_cell", + "pavex_cli_shell", "pavexc", "persist_if_changed", "px_workspace_hack", @@ -3208,7 +3204,7 @@ dependencies = [ "sha2", "similar", "textwrap", - "toml 0.9.8", + "toml 0.9.10+spec-1.1.0", "tracing-subscriber", "walkdir", ] @@ -3234,8 +3230,8 @@ dependencies = [ "camino", "cargo-like-utils", "cargo-manifest", - "convert_case 0.8.0", - "darling 0.21.3", + "convert_case 0.10.0", + "darling 0.23.0", "elsa", "fixedbitset", "fs-err", @@ -3245,7 +3241,7 @@ dependencies = [ "insta", "itertools 0.14.0", "la-arena", - "matchit", + "matchit 0.9.0", "miette", "num_cpus", "once_cell", @@ -3253,6 +3249,7 @@ dependencies = [ "pavex_bp_schema", "pavex_cli_diagnostic", "pavex_cli_shell", + "pavex_rustdoc_types", "pavexc_attr_parser", "persist_if_changed", "petgraph", @@ -3264,9 +3261,9 @@ dependencies = [ "r2d2_sqlite", "rayon", "relative-path", + "rkyv", "rusqlite", "rustc-hash", - "rustdoc-types", "semver", "serde", "serde_json", @@ -3274,8 +3271,8 @@ dependencies = [ "syn", "textwrap", "thiserror 2.0.17", - "toml 0.9.8", - "toml_edit 0.23.7", + "toml 0.9.10+spec-1.1.0", + "toml_edit 0.24.0+spec-1.1.0", "tracing", "tracing_log_error", "vergen-gitcl", @@ -3287,7 +3284,8 @@ dependencies = [ name = "pavexc_attr_parser" version = "0.2.10" dependencies = [ - "darling 0.21.3", + "bincode", + "darling 0.23.0", "insta", "itertools 0.14.0", "pavex_bp_schema", @@ -3323,7 +3321,7 @@ dependencies = [ "pavexc", "pavexc_cli_client", "px_workspace_hack", - "ron 0.11.0", + "ron", "serde", "serde_json", "supports-color", @@ -3408,9 +3406,9 @@ dependencies = [ [[package]] name = "pest" -version = "2.8.3" +version = "2.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "989e7521a040efde50c3ab6bbadafbe15ab6dc042686926be59ac35d74607df4" +checksum = "cbcfd20a6d4eeba40179f05735784ad32bdaef05ce8e8af05f180d45bb3e7e22" dependencies = [ "memchr", "ucd-trie", @@ -3418,9 +3416,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.8.3" +version = "2.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "187da9a3030dbafabbbfb20cb323b976dc7b7ce91fcd84f2f74d6e31d378e2de" +checksum = "51f72981ade67b1ca6adc26ec221be9f463f2b5839c7508998daa17c23d94d7f" dependencies = [ "pest", "pest_generator", @@ -3428,9 +3426,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.8.3" +version = "2.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b401d98f5757ebe97a26085998d6c0eecec4995cad6ab7fc30ffdf4b052843" +checksum = "dee9efd8cdb50d719a80088b76f81aec7c41ed6d522ee750178f83883d271625" dependencies = [ "pest", "pest_meta", @@ -3441,9 +3439,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.8.3" +version = "2.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72f27a2cfee9f9039c4d86faa5af122a0ac3851441a34865b8a043b46be0065a" +checksum = "bf1d70880e76bdc13ba52eafa6239ce793d85c8e43896507e43dd8984ff05b82" dependencies = [ "pest", "sha2", @@ -3514,9 +3512,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.11.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" +checksum = "f59e70c4aef1e55797c2e8fd94a4f2a973fc972cfde0e0b05f683667b0cd39dd" [[package]] name = "portable-atomic-util" @@ -3602,6 +3600,26 @@ dependencies = [ "cc", ] +[[package]] +name = "ptr_meta" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9a0cf95a1196af61d4f1cbdab967179516d9a4a4312af1f31948f8f6224a79" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "px_workspace_hack" version = "0.1.0" @@ -3612,10 +3630,10 @@ dependencies = [ "byteorder", "clap", "clap_builder", - "console 0.16.1", + "console 0.16.2", "crossbeam-utils", "crypto-common", - "darling_core 0.21.3", + "darling_core 0.23.0", "digest", "either", "fastrand", @@ -3649,7 +3667,6 @@ dependencies = [ "petgraph", "proc-macro2", "quote", - "rand 0.8.5", "rand_core 0.6.4", "regex-automata", "regex-syntax", @@ -3659,7 +3676,7 @@ dependencies = [ "serde", "serde_core", "serde_json", - "serde_spanned 1.0.3", + "serde_spanned 1.0.4", "sha2", "smallvec", "spin", @@ -3676,9 +3693,8 @@ dependencies = [ "textwrap", "time", "tokio", - "toml 0.8.23", - "toml 0.9.8", - "toml_datetime 0.7.3", + "toml 0.9.10+spec-1.1.0", + "toml_datetime 0.7.5+spec-1.1.0", "toml_parser", "toml_writer", "tracing", @@ -3766,7 +3782,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93" dependencies = [ "log", - "parking_lot 0.12.5", + "parking_lot", "scheduled-thread-pool", ] @@ -3781,6 +3797,15 @@ dependencies = [ "uuid", ] +[[package]] +name = "rancor" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a063ea72381527c2a0561da9c80000ef822bdd7c3241b1cc1b12100e3df081ee" +dependencies = [ + "ptr_meta", +] + [[package]] name = "rand" version = "0.8.5" @@ -3896,20 +3921,20 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.16" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 1.3.2", + "bitflags", ] [[package]] name = "redox_syscall" -version = "0.5.18" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +checksum = "ec96166dafa0886eb81fe1c0a388bece180fbef2135f97c1e2cf8302e74b43b5" dependencies = [ - "bitflags 2.10.0", + "bitflags", ] [[package]] @@ -3964,11 +3989,17 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "rend" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cadadef317c2f20755a64d7fdc48f9e7178ee6b0e1f7fce33fa60f1d68a276e6" + [[package]] name = "reqwest" -version = "0.12.24" +version = "0.12.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d0946410b9f7b082a427e4ef5c8ff541a88b357bc6c637c40db3a68ac70a36f" +checksum = "3b4c14b2d9afca6a60277086b0cc6a6ae0b568f6f7916c943a8cdc79f8be240f" dependencies = [ "base64", "bytes", @@ -4019,9 +4050,9 @@ dependencies = [ [[package]] name = "reqwest-retry" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c73e4195a6bfbcb174b790d9b3407ab90646976c55de58a6515da25d851178" +checksum = "105747e3a037fe5bf17458d794de91149e575b6183fc72c85623a44abb9683f5" dependencies = [ "anyhow", "async-trait", @@ -4029,14 +4060,13 @@ dependencies = [ "getrandom 0.2.16", "http", "hyper", - "parking_lot 0.11.2", "reqwest", "reqwest-middleware", "retry-policies", - "thiserror 1.0.69", + "thiserror 2.0.17", "tokio", "tracing", - "wasm-timer", + "wasmtimer", ] [[package]] @@ -4049,7 +4079,7 @@ dependencies = [ "async-trait", "getrandom 0.2.16", "http", - "matchit", + "matchit 0.8.6", "reqwest", "reqwest-middleware", "tracing", @@ -4057,11 +4087,11 @@ dependencies = [ [[package]] name = "retry-policies" -version = "0.4.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5875471e6cab2871bc150ecb8c727db5113c9338cc3354dc5ee3425b6aa40a1c" +checksum = "46a4bd6027df676bcb752d3724db0ea3c0c5fc1dd0376fec51ac7dcaf9cc69be" dependencies = [ - "rand 0.8.5", + "rand 0.9.2", ] [[package]] @@ -4089,25 +4119,41 @@ dependencies = [ ] [[package]] -name = "rlimit" -version = "0.10.2" +name = "rkyv" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7043b63bd0cd1aaa628e476b80e6d4023a3b50eb32789f2728908107bd0c793a" +checksum = "35a640b26f007713818e9a9b65d34da1cf58538207b052916a83d80e43f3ffa4" dependencies = [ - "libc", + "bytes", + "hashbrown 0.15.5", + "indexmap", + "munge", + "ptr_meta", + "rancor", + "rend", + "rkyv_derive", + "tinyvec", + "uuid", ] [[package]] -name = "ron" -version = "0.11.0" +name = "rkyv_derive" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db09040cc89e461f1a265139777a2bde7f8d8c67c4936f700c63ce3e2904d468" +checksum = "bd83f5f173ff41e00337d97f6572e416d022ef8a19f371817259ae960324c482" dependencies = [ - "base64", - "bitflags 2.10.0", - "serde", - "serde_derive", - "unicode-ident", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "rlimit" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7043b63bd0cd1aaa628e476b80e6d4023a3b50eb32789f2728908107bd0c793a" +dependencies = [ + "libc", ] [[package]] @@ -4116,7 +4162,7 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd490c5b18261893f14449cbd28cb9c0b637aebf161cd77900bfdedaff21ec32" dependencies = [ - "bitflags 2.10.0", + "bitflags", "once_cell", "serde", "serde_derive", @@ -4150,7 +4196,7 @@ version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7753b721174eb8ff87a9a0e799e2d7bc3749323e773db92e0984debb00019d6e" dependencies = [ - "bitflags 2.10.0", + "bitflags", "fallible-iterator", "fallible-streaming-iterator", "hashlink 0.9.1", @@ -4189,24 +4235,13 @@ dependencies = [ "semver", ] -[[package]] -name = "rustdoc-types" -version = "0.56.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27bf787c529efe523ed9eb6dcdbaa5954d34329f08d5c243fce928441826ca90" -dependencies = [ - "rustc-hash", - "serde", - "serde_derive", -] - [[package]] name = "rustix" version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ - "bitflags 2.10.0", + "bitflags", "errno", "libc", "linux-raw-sys", @@ -4243,9 +4278,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.13.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94182ad936a0c91c324cd46c6511b9510ed16af436d7b5bab34beab0afd55f7a" +checksum = "21e6f2ab2928ca4291b86736a8bd920a277a399bba1589409d72154ff87c1282" dependencies = [ "web-time", "zeroize", @@ -4335,7 +4370,7 @@ version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19" dependencies = [ - "parking_lot 0.12.5", + "parking_lot", ] [[package]] @@ -4374,7 +4409,7 @@ version = "3.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" dependencies = [ - "bitflags 2.10.0", + "bitflags", "core-foundation", "core-foundation-sys", "libc", @@ -4502,9 +4537,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e24345aa0fe688594e73770a5f6d1b216508b4f93484c0026d521acd30134392" +checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776" dependencies = [ "serde_core", ] @@ -4600,9 +4635,9 @@ dependencies = [ [[package]] name = "simd-adler32" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" [[package]] name = "similar" @@ -4778,7 +4813,7 @@ checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526" dependencies = [ "atoi", "base64", - "bitflags 2.10.0", + "bitflags", "byteorder", "bytes", "crc", @@ -4821,7 +4856,7 @@ checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46" dependencies = [ "atoi", "base64", - "bitflags 2.10.0", + "bitflags", "byteorder", "crc", "dotenvy", @@ -4935,9 +4970,9 @@ dependencies = [ [[package]] name = "supports-hyperlinks" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "804f44ed3c63152de6a9f90acbea1a110441de43006ea51bcce8f436196a288b" +checksum = "e396b6523b11ccb83120b115a0b7366de372751aa6edf19844dfb13a6af97e91" [[package]] name = "supports-unicode" @@ -4947,9 +4982,9 @@ checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2" [[package]] name = "syn" -version = "2.0.110" +version = "2.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a99801b5bd34ede4cf3fc688c5919368fea4e4814a4664359503e6015b280aea" +checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" dependencies = [ "proc-macro2", "quote", @@ -5244,14 +5279,14 @@ dependencies = [ [[package]] name = "toml" -version = "0.9.8" +version = "0.9.10+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dc8b1fb61449e27716ec0e1bdf0f6b8f3e8f6b05391e8497b8b6d7804ea6d8" +checksum = "0825052159284a1a8b4d6c0c86cbc801f2da5afd2b225fa548c72f2e74002f48" dependencies = [ "indexmap", "serde_core", - "serde_spanned 1.0.3", - "toml_datetime 0.7.3", + "serde_spanned 1.0.4", + "toml_datetime 0.7.5+spec-1.1.0", "toml_parser", "toml_writer", "winnow", @@ -5268,9 +5303,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.7.3" +version = "0.7.5+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" dependencies = [ "serde_core", ] @@ -5285,20 +5320,19 @@ dependencies = [ "serde", "serde_spanned 0.6.9", "toml_datetime 0.6.11", - "toml_write", "winnow", ] [[package]] name = "toml_edit" -version = "0.23.7" +version = "0.24.0+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6485ef6d0d9b5d0ec17244ff7eb05310113c3f316f2d14200d4de56b3cb98f8d" +checksum = "8c740b185920170a6d9191122cafef7010bd6270a3824594bff6784c04d7f09e" dependencies = [ "indexmap", "serde_core", - "serde_spanned 1.0.3", - "toml_datetime 0.7.3", + "serde_spanned 1.0.4", + "toml_datetime 0.7.5+spec-1.1.0", "toml_parser", "toml_writer", "winnow", @@ -5306,24 +5340,18 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.0.4" +version = "1.0.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" +checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" dependencies = [ "winnow", ] -[[package]] -name = "toml_write" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" - [[package]] name = "toml_writer" -version = "1.0.4" +version = "1.0.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df8b2b54733674ad286d16267dcfc7a71ed5c776e4ac7aa3c3e2561f7c637bf2" +checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607" [[package]] name = "tower" @@ -5342,11 +5370,11 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" dependencies = [ - "bitflags 2.10.0", + "bitflags", "bytes", "futures-util", "http", @@ -5372,9 +5400,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.41" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "log", "pin-project-lite", @@ -5384,9 +5412,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", @@ -5406,9 +5434,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.34" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", "valuable", @@ -5427,9 +5455,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.20" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" +checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" dependencies = [ "matchers", "nu-ansi-term", @@ -5470,7 +5498,7 @@ dependencies = [ "serde_json", "target-triple", "termcolor", - "toml 0.9.8", + "toml 0.9.10+spec-1.1.0", ] [[package]] @@ -5574,9 +5602,9 @@ checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] name = "unit-prefix" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "323402cff2dd658f39ca17c789b502021b3f18707c91cdf22e3838e1b4023817" +checksum = "81e544489bf3d8ef66c953931f56617f423cd4b5494be343d9b9d3dda037b9a3" [[package]] name = "universal-hash" @@ -5628,9 +5656,9 @@ dependencies = [ [[package]] name = "ureq-proto" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b4531c118335662134346048ddb0e54cc86bd7e81866757873055f0e38f5d2" +checksum = "d81f9efa9df032be5934a46a068815a10a042b494b6a58cb0a1a97bb5467ed6f" dependencies = [ "base64", "http", @@ -5670,14 +5698,14 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.18.1" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" +checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" dependencies = [ "getrandom 0.3.4", "js-sys", "rand 0.9.2", - "serde", + "serde_core", "wasm-bindgen", ] @@ -5785,9 +5813,9 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.105" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60" +checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" dependencies = [ "cfg-if", "once_cell", @@ -5798,9 +5826,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.55" +version = "0.4.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "551f88106c6d5e7ccc7cd9a16f312dd3b5d36ea8b4954304657d5dfba115d4a0" +checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c" dependencies = [ "cfg-if", "js-sys", @@ -5811,9 +5839,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.105" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2" +checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5821,9 +5849,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.105" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc" +checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" dependencies = [ "bumpalo", "proc-macro2", @@ -5834,33 +5862,32 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.105" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76" +checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" dependencies = [ "unicode-ident", ] [[package]] -name = "wasm-timer" -version = "0.2.5" +name = "wasmtimer" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f" +checksum = "1c598d6b99ea013e35844697fc4670d08339d5cda15588f193c6beedd12f644b" dependencies = [ "futures", "js-sys", - "parking_lot 0.11.2", + "parking_lot", "pin-utils", + "slab", "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", ] [[package]] name = "web-sys" -version = "0.3.82" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a1f95c0d03a47f4ae1f7a64643a6bb97465d9b740f0fa8f90ea33915c99a9a1" +checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" dependencies = [ "js-sys", "wasm-bindgen", @@ -5913,22 +5940,6 @@ dependencies = [ "wasite", ] -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - [[package]] name = "winapi-util" version = "0.1.11" @@ -5938,12 +5949,6 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - [[package]] name = "windows-link" version = "0.2.1" @@ -6249,9 +6254,9 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" -version = "0.7.13" +version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" dependencies = [ "memchr", ] @@ -6345,18 +6350,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.27" +version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" +checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.27" +version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" +checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index da048a24a..53bc1d107 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,6 +36,8 @@ pavexc = { path = "compiler/pavexc", version = "0.2.10" } pavexc_attr_parser = { path = "compiler/pavexc_attr_parser", version = "0.2.10" } pavexc_cli_client = { path = "compiler/pavexc_cli_client", version = "0.2.10" } persist_if_changed = { path = "compiler/persist_if_changed", version = "0.2.10" } +# Our own fork of `rustdoc-types` to minimise (de)ser overhead. +rustdoc-types = { path = "compiler/pavex_rustdoc_types", version = "0.2.10", features = ["rustc-hash"], package = "pavex_rustdoc_types" } vergen-gitcl = { version = "1.0.8", features = ["build"] } ahash = "0.8" @@ -51,11 +53,11 @@ cargo_metadata = "0.23.1" cargo-like-utils = "0.2" cargo-manifest = "0.19.1" clap = "4" -clap-stdin = "0.7.0" +clap-stdin = "0.8.0" config = "0.15.19" -console = "0.16.1" -convert_case = "0.8" -darling = "0.21" +console = "0.16.2" +convert_case = "0.10" +darling = "0.23" xxhash-rust = "0.8.15" elsa = "1.11.2" fixedbitset = "0.5" @@ -75,17 +77,17 @@ hyper-util = "0.1" include_dir = "0.7.4" indexmap = "2" indicatif = "0.18.3" -insta = "1.43.2" +insta = "1.45.0" itertools = "0.14" jiff = "0.2.16" jiff-sqlx = "0.1.1" jsonwebtoken = { version = "10.2.0", features = ["rust_crypto"] } la-arena = "0.3" -libc = "0.2.177" +libc = "0.2.178" libtest-mimic = "0.8.1" liquid = "0.26.11" liquid-core = "0.26.11" -matchit = "0.8.6" +matchit = "0.9.0" miette = "7.6.0" mime = "0.3" num_cpus = "1.17.0" @@ -111,21 +113,21 @@ redis = { version = "0.31.0", features = [ ] } regex = "1.12.2" relative-path = "2.0" +rkyv = { version = "0.8", default-features = false, features = ["std"] } remove_dir_all = "1" reqwest = { version = "0.12", default-features = false, features = [ "rustls-tls", ] } reqwest-middleware = "0.4" -reqwest-retry = "0.7.0" +reqwest-retry = "0.8.0" reqwest-tracing = "0.5.8" rustls = { version = "0.23", default-features = false } rustls-platform-verifier = "0.6.2" ring = "0.17.14" rlimit = "0.10.2" -ron = "0.11" +ron = "0.12" rustc-hash = "2" rusqlite = "0.32" -rustdoc-types = { version = "0.56.0", features = ["rustc-hash"] } sanitize-filename = "0.6" self-replace = "1.5.0" secrecy = "0.10.3" @@ -143,7 +145,7 @@ sqlx = { version = "0.8", default-features = false } socket2 = "0.6.1" static_assertions = "1.1.0" supports-color = "3.0.2" -supports-hyperlinks = "3.1.0" +supports-hyperlinks = "3.2.0" supports-unicode = "3.0.0" syn = "2.0" tar = "0.4.44" @@ -152,9 +154,9 @@ terminal_size = "0.4" textwrap = "0.16.2" thiserror = "2" tokio = "1.48.0" -toml = "0.9.8" -toml_edit = "0.23.7" -tracing = { version = "0.1.41", default-features = false } +toml = "0.9.10" +toml_edit = "0.24" +tracing = { version = "0.1.44", default-features = false } tracing-log = "0.2" tracing_log_error = "0.1" tracing-chrome = "0.7" diff --git a/compiler/.gitignore b/compiler/.gitignore index 2e62407d4..a8b099a1e 100644 --- a/compiler/.gitignore +++ b/compiler/.gitignore @@ -1,4 +1,4 @@ target metadata.json -**/generated_app/ +**/generated_app/blueprint.ron Cargo.lock diff --git a/compiler/pavex_bp_schema/Cargo.toml b/compiler/pavex_bp_schema/Cargo.toml index 5edfef7d6..7867b49de 100644 --- a/compiler/pavex_bp_schema/Cargo.toml +++ b/compiler/pavex_bp_schema/Cargo.toml @@ -9,4 +9,5 @@ license.workspace = true [dependencies] serde = { workspace = true, features = ["derive"] } +bincode = { workspace = true } px_workspace_hack = { version = "0.1", path = "../../px_workspace_hack" } diff --git a/compiler/pavex_bp_schema/src/lib.rs b/compiler/pavex_bp_schema/src/lib.rs index 4521b8325..d4f458869 100644 --- a/compiler/pavex_bp_schema/src/lib.rs +++ b/compiler/pavex_bp_schema/src/lib.rs @@ -285,7 +285,18 @@ pub struct Domain { pub registered_at: Location, } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] +#[derive( + Debug, + Clone, + Copy, + PartialEq, + Eq, + Hash, + serde::Serialize, + serde::Deserialize, + bincode::Encode, + bincode::Decode, +)] #[serde(rename_all = "snake_case")] pub enum Lifecycle { Singleton, @@ -303,7 +314,18 @@ impl fmt::Display for Lifecycle { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] +#[derive( + Debug, + Clone, + Copy, + PartialEq, + Eq, + Hash, + serde::Serialize, + serde::Deserialize, + bincode::Encode, + bincode::Decode, +)] #[serde(rename_all = "snake_case")] #[non_exhaustive] pub enum CloningPolicy { @@ -315,7 +337,17 @@ pub enum CloningPolicy { } #[derive( - Debug, Clone, Hash, PartialEq, Eq, Ord, PartialOrd, serde::Serialize, serde::Deserialize, + Debug, + Clone, + Hash, + PartialEq, + Eq, + Ord, + PartialOrd, + serde::Serialize, + serde::Deserialize, + bincode::Encode, + bincode::Decode, )] #[serde(rename_all = "snake_case")] pub enum MethodGuard { diff --git a/compiler/pavex_cli/src/activation/mod.rs b/compiler/pavex_cli/src/activation/mod.rs index 5456b0a0b..0044dce12 100644 --- a/compiler/pavex_cli/src/activation/mod.rs +++ b/compiler/pavex_cli/src/activation/mod.rs @@ -1,3 +1,4 @@ +#![allow(unused_assignments)] // False positive due to fields only used in the Diagnostic/Display impl derived by the miette macro. use crate::activation::token::ValidatedClaims; use crate::command::Command; use crate::locator::PavexLocator; diff --git a/compiler/pavex_cli_deps/src/installers.rs b/compiler/pavex_cli_deps/src/installers.rs index 81c3056dd..cb7838ae3 100644 --- a/compiler/pavex_cli_deps/src/installers.rs +++ b/compiler/pavex_cli_deps/src/installers.rs @@ -1,3 +1,4 @@ +#![allow(unused_assignments)] // False positives due to fields only used in Display impls. use crate::commands::{ install_rustdoc_json, install_rustup_toolchain, is_cargo_px_installed, is_rustdoc_json_installed, is_rustup_installed, is_rustup_toolchain_installed, diff --git a/compiler/pavex_miette/src/graphical_report_handler.rs b/compiler/pavex_miette/src/graphical_report_handler.rs index a58b47a66..ad04a2695 100644 --- a/compiler/pavex_miette/src/graphical_report_handler.rs +++ b/compiler/pavex_miette/src/graphical_report_handler.rs @@ -824,7 +824,6 @@ impl GraphicalReportHandler { }; for _ in 0..n_leading_whitespaces { write!(f, " ")?; - curr_offset += 1; } let label_line = if i == 0 { diff --git a/compiler/pavex_rustdoc_types/Cargo.toml b/compiler/pavex_rustdoc_types/Cargo.toml new file mode 100644 index 000000000..92c56f728 --- /dev/null +++ b/compiler/pavex_rustdoc_types/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "pavex_rustdoc_types" +edition.workspace = true +repository.workspace = true +homepage.workspace = true +license.workspace = true +version.workspace = true + +[dependencies] +serde = {version="1.0.186"} +serde_derive = {version="1.0.186"} +rustc-hash = {version="2", optional=true} +bincode = "2" +rkyv = { version = "0.8", default-features = false, features = ["std"] } + +[features] +default = [] + +# Switch the hashmaps used in rustdoc-types to the FxHashMap from rustc-hash. +# +# This might improve performace if your are reading the rustdoc JSON from large +# crates like aws_sdk_ec2 +rustc-hash = ["dep:rustc-hash"] diff --git a/compiler/pavex_rustdoc_types/src/lib.rs b/compiler/pavex_rustdoc_types/src/lib.rs new file mode 100644 index 000000000..078c0197c --- /dev/null +++ b/compiler/pavex_rustdoc_types/src/lib.rs @@ -0,0 +1,2253 @@ +//! Rustdoc's JSON output interface +//! +//! These types are the public API exposed through the `--output-format json` flag. The [`Crate`] +//! struct is the root of the JSON blob and all other items are contained within. +//! +//! We expose a `rustc-hash` feature that is disabled by default. This feature switches the +//! [`std::collections::HashMap`] for [`rustc_hash::FxHashMap`] to improve the performance of said +//! `HashMap` in specific situations. +//! +//! `cargo-semver-checks` for example, saw a [-3% improvement][1] when benchmarking using the +//! `aws_sdk_ec2` JSON output (~500MB of JSON). As always, we recommend measuring the impact before +//! turning this feature on, as [`FxHashMap`][2] only concerns itself with hash speed, and may +//! increase the number of collisions. +//! +//! [1]: https://rust-lang.zulipchat.com/#narrow/channel/266220-t-rustdoc/topic/rustc-hash.20and.20performance.20of.20rustdoc-types/near/474855731 +//! [2]: https://crates.io/crates/rustc-hash + +#[cfg(not(feature = "rustc-hash"))] +use std::collections::HashMap; +use std::path::PathBuf; + +use bincode::{Decode, Encode}; +#[cfg(feature = "rustc-hash")] +use rustc_hash::FxHashMap as HashMap; +use serde_derive::{Deserialize, Serialize}; + +/// The version of JSON output that this crate represents. +/// +/// This integer is incremented with every breaking change to the API, +/// and is returned along with the JSON blob as [`Crate::format_version`]. +/// Consuming code should assert that this value matches the format version(s) that it supports. +// +// WARNING: When you update `FORMAT_VERSION`, please also update the "Latest feature" line with a +// description of the change. This minimizes the risk of two concurrent PRs changing +// `FORMAT_VERSION` from N to N+1 and git merging them without conflicts; the "Latest feature" line +// will instead cause conflicts. See #94591 for more. (This paragraph and the "Latest feature" line +// are deliberately not in a doc comment, because they need not be in public docs.) +// +// Latest feature: Add `ExternCrate::path`. +pub const FORMAT_VERSION: u32 = 57; + +/// The root of the emitted JSON blob. +/// +/// It contains all type/documentation information +/// about the language items in the local crate, as well as info about external items to allow +/// tools to find or link to them. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +pub struct Crate { + /// The id of the root [`Module`] item of the local crate. + pub root: Id, + /// The version string given to `--crate-version`, if any. + pub crate_version: Option, + /// Whether or not the output includes private items. + pub includes_private: bool, + /// A collection of all items in the local crate as well as some external traits and their + /// items that are referenced locally. + pub index: HashMap, + /// Maps IDs to fully qualified paths and other info helpful for generating links. + pub paths: HashMap, + /// Maps `crate_id` of items to a crate name and html_root_url if it exists. + pub external_crates: HashMap, + /// Information about the target for which this documentation was generated + pub target: Target, + /// A single version number to be used in the future when making backwards incompatible changes + /// to the JSON output. + pub format_version: u32, +} + +/// Information about a target +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +pub struct Target { + /// The target triple for which this documentation was generated + pub triple: String, + /// A list of features valid for use in `#[target_feature]` attributes + /// for the target where this rustdoc JSON was generated. + pub target_features: Vec, +} + +/// Information about a target feature. +/// +/// Rust target features are used to influence code generation, especially around selecting +/// instructions which are not universally supported by the target architecture. +/// +/// Target features are commonly enabled by the [`#[target_feature]` attribute][1] to influence code +/// generation for a particular function, and less commonly enabled by compiler options like +/// `-Ctarget-feature` or `-Ctarget-cpu`. Targets themselves automatically enable certain target +/// features by default, for example because the target's ABI specification requires saving specific +/// registers which only exist in an architectural extension. +/// +/// Target features can imply other target features: for example, x86-64 `avx2` implies `avx`, and +/// aarch64 `sve2` implies `sve`, since both of these architectural extensions depend on their +/// predecessors. +/// +/// Target features can be probed at compile time by [`#[cfg(target_feature)]`][2] or `cfg!(…)` +/// conditional compilation to determine whether a target feature is enabled in a particular +/// context. +/// +/// [1]: https://doc.rust-lang.org/stable/reference/attributes/codegen.html#the-target_feature-attribute +/// [2]: https://doc.rust-lang.org/reference/conditional-compilation.html#target_feature +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +pub struct TargetFeature { + /// The name of this target feature. + pub name: String, + /// Other target features which are implied by this target feature, if any. + pub implies_features: Vec, + /// If this target feature is unstable, the name of the associated language feature gate. + pub unstable_feature_gate: Option, + /// Whether this feature is globally enabled for this compilation session. + /// + /// Target features can be globally enabled implicitly as a result of the target's definition. + /// For example, x86-64 hardware floating point ABIs require saving x87 and SSE2 registers, + /// which in turn requires globally enabling the `x87` and `sse2` target features so that the + /// generated machine code conforms to the target's ABI. + /// + /// Target features can also be globally enabled explicitly as a result of compiler flags like + /// [`-Ctarget-feature`][1] or [`-Ctarget-cpu`][2]. + /// + /// [1]: https://doc.rust-lang.org/beta/rustc/codegen-options/index.html#target-feature + /// [2]: https://doc.rust-lang.org/beta/rustc/codegen-options/index.html#target-cpu + pub globally_enabled: bool, +} + +/// Metadata of a crate, either the same crate on which `rustdoc` was invoked, or its dependency. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +pub struct ExternalCrate { + /// The name of the crate. + /// + /// Note: This is the [*crate* name][crate-name], which may not be the same as the + /// [*package* name][package-name]. For example, for , + /// this field will be `regex_syntax` (which uses an `_`, not a `-`). + /// + /// [crate-name]: https://doc.rust-lang.org/stable/cargo/reference/cargo-targets.html#the-name-field + /// [package-name]: https://doc.rust-lang.org/stable/cargo/reference/manifest.html#the-name-field + pub name: String, + /// The root URL at which the crate's documentation lives. + pub html_root_url: Option, + + /// A path from where this crate was loaded. + /// + /// This will typically be a `.rlib` or `.rmeta`. It can be used to determine which crate + /// this was in terms of whatever build-system invoked rustc. + #[rkyv(with = rkyv::with::AsString)] + pub path: PathBuf, +} + +/// Information about an external (not defined in the local crate) [`Item`]. +/// +/// For external items, you don't get the same level of +/// information. This struct should contain enough to generate a link/reference to the item in +/// question, or can be used by a tool that takes the json output of multiple crates to find +/// the actual item definition with all the relevant info. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +pub struct ItemSummary { + /// Can be used to look up the name and html_root_url of the crate this item came from in the + /// `external_crates` map. + pub crate_id: u32, + /// The list of path components for the fully qualified path of this item (e.g. + /// `["std", "io", "lazy", "Lazy"]` for `std::io::lazy::Lazy`). + /// + /// Note that items can appear in multiple paths, and the one chosen is implementation + /// defined. Currently, this is the full path to where the item was defined. Eg + /// [`String`] is currently `["alloc", "string", "String"]` and [`HashMap`][`std::collections::HashMap`] + /// is `["std", "collections", "hash", "map", "HashMap"]`, but this is subject to change. + pub path: Vec, + /// Whether this item is a struct, trait, macro, etc. + pub kind: ItemKind, +} + +/// Anything that can hold documentation - modules, structs, enums, functions, traits, etc. +/// +/// The `Item` data type holds fields that can apply to any of these, +/// and leaves kind-specific details (like function args or enum variants) to the `inner` field. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +pub struct Item { + /// The unique identifier of this item. Can be used to find this item in various mappings. + pub id: Id, + /// This can be used as a key to the `external_crates` map of [`Crate`] to see which crate + /// this item came from. + pub crate_id: u32, + /// Some items such as impls don't have names. + pub name: Option, + /// The source location of this item (absent if it came from a macro expansion or inline + /// assembly). + pub span: Option, + /// By default all documented items are public, but you can tell rustdoc to output private items + /// so this field is needed to differentiate. + pub visibility: Visibility, + /// The full markdown docstring of this item. Absent if there is no documentation at all, + /// Some("") if there is some documentation but it is empty (EG `#[doc = ""]`). + pub docs: Option, + /// This mapping resolves [intra-doc links](https://github.com/rust-lang/rfcs/blob/master/text/1946-intra-rustdoc-links.md) from the docstring to their IDs + pub links: HashMap, + /// Attributes on this item. + /// + /// Does not include `#[deprecated]` attributes: see the [`Self::deprecation`] field instead. + /// + /// Attributes appear in pretty-printed Rust form, regardless of their formatting + /// in the original source code. For example: + /// - `#[non_exhaustive]` and `#[must_use]` are represented as themselves. + /// - `#[no_mangle]` and `#[export_name]` are also represented as themselves. + /// - `#[repr(C)]` and other reprs also appear as themselves, + /// though potentially with a different order: e.g. `repr(i8, C)` may become `repr(C, i8)`. + /// Multiple repr attributes on the same item may be combined into an equivalent single attr. + pub attrs: Vec, + /// Information about the item’s deprecation, if present. + pub deprecation: Option, + /// The type-specific fields describing this item. + pub inner: ItemEnum, +} + +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +#[serde(rename_all = "snake_case")] +/// An attribute, e.g. `#[repr(C)]` +/// +/// This doesn't include: +/// - `#[doc = "Doc Comment"]` or `/// Doc comment`. These are in [`Item::docs`] instead. +/// - `#[deprecated]`. These are in [`Item::deprecation`] instead. +pub enum Attribute { + /// `#[non_exhaustive]` + NonExhaustive, + + /// `#[must_use]` + MustUse { reason: Option }, + + /// `#[macro_export]` + MacroExport, + + /// `#[export_name = "name"]` + ExportName(String), + + /// `#[link_section = "name"]` + LinkSection(String), + + /// `#[automatically_derived]` + AutomaticallyDerived, + + /// `#[repr]` + Repr(AttributeRepr), + + /// `#[no_mangle]` + NoMangle, + + /// #[target_feature(enable = "feature1", enable = "feature2")] + TargetFeature { enable: Vec }, + + /// Something else. + /// + /// Things here are explicitly *not* covered by the [`FORMAT_VERSION`] + /// constant, and may change without bumping the format version. + /// + /// As an implementation detail, this is currently either: + /// 1. A HIR debug printing, like `"#[attr = Optimize(Speed)]"` + /// 2. The attribute as it appears in source form, like + /// `"#[optimize(speed)]"`. + Other(String), +} + +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] + +/// The contents of a `#[repr(...)]` attribute. +/// +/// Used in [`Attribute::Repr`]. +pub struct AttributeRepr { + /// The representation, e.g. `#[repr(C)]`, `#[repr(transparent)]` + pub kind: ReprKind, + + /// Alignment in bytes, if explicitly specified by `#[repr(align(...)]`. + pub align: Option, + /// Alignment in bytes, if explicitly specified by `#[repr(packed(...)]]`. + pub packed: Option, + + /// The integer type for an enum descriminant, if explicitly specified. + /// + /// e.g. `"i32"`, for `#[repr(C, i32)]` + pub int: Option, +} + +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +#[serde(rename_all = "snake_case")] +/// The kind of `#[repr]`. +/// +/// See [AttributeRepr::kind]`. +pub enum ReprKind { + /// `#[repr(Rust)]` + /// + /// Also the default. + Rust, + /// `#[repr(C)]` + C, + /// `#[repr(transparent)] + Transparent, + /// `#[repr(simd)]` + Simd, +} + +/// A range of source code. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +pub struct Span { + /// The path to the source file for this span relative to the path `rustdoc` was invoked with. + #[rkyv(with = rkyv::with::AsString)] + pub filename: PathBuf, + /// One indexed Line and Column of the first character of the `Span`. + pub begin: (usize, usize), + /// One indexed Line and Column of the last character of the `Span`. + pub end: (usize, usize), +} + +/// Information about the deprecation of an [`Item`]. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +pub struct Deprecation { + /// Usually a version number when this [`Item`] first became deprecated. + pub since: Option, + /// The reason for deprecation and/or what alternatives to use. + pub note: Option, +} + +/// Visibility of an [`Item`]. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +#[serde(rename_all = "snake_case")] +pub enum Visibility { + /// Explicitly public visibility set with `pub`. + Public, + /// For the most part items are private by default. The exceptions are associated items of + /// public traits and variants of public enums. + Default, + /// Explicitly crate-wide visibility set with `pub(crate)` + Crate, + /// For `pub(in path)` visibility. + Restricted { + /// ID of the module to which this visibility restricts items. + parent: Id, + /// The path with which [`parent`] was referenced + /// (like `super::super` or `crate::foo::bar`). + /// + /// [`parent`]: Visibility::Restricted::parent + path: String, + }, +} + +/// Dynamic trait object type (`dyn Trait`). +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +pub struct DynTrait { + /// All the traits implemented. One of them is the vtable, and the rest must be auto traits. + pub traits: Vec, + /// The lifetime of the whole dyn object + /// ```text + /// dyn Debug + 'static + /// ^^^^^^^ + /// | + /// this part + /// ``` + pub lifetime: Option, +} + +/// A trait and potential HRTBs +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +pub struct PolyTrait { + /// The path to the trait. + #[serde(rename = "trait")] + pub trait_: Path, + /// Used for Higher-Rank Trait Bounds (HRTBs) + /// ```text + /// dyn for<'a> Fn() -> &'a i32" + /// ^^^^^^^ + /// ``` + pub generic_params: Vec, +} + +/// A set of generic arguments provided to a path segment, e.g. +/// +/// ```text +/// std::option::Option +/// ^^^^^ +/// ``` +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +#[rkyv( + serialize_bounds(__S: rkyv::ser::Writer + rkyv::ser::Allocator, __S::Error: rkyv::rancor::Source), + deserialize_bounds(__D: rkyv::de::Pooling, __D::Error: rkyv::rancor::Source), +)] +#[serde(rename_all = "snake_case")] +pub enum GenericArgs { + /// `<'a, 32, B: Copy, C = u32>` + AngleBracketed { + /// The list of each argument on this type. + /// ```text + /// <'a, 32, B: Copy, C = u32> + /// ^^^^^^ + /// ``` + args: Vec, + /// Associated type or constant bindings (e.g. `Item=i32` or `Item: Clone`) for this type. + constraints: Vec, + }, + /// `Fn(A, B) -> C` + Parenthesized { + /// The input types, enclosed in parentheses. + #[rkyv(omit_bounds)] + inputs: Vec, + /// The output type provided after the `->`, if present. + #[rkyv(omit_bounds)] + output: Option, + }, + /// `T::method(..)` + ReturnTypeNotation, +} + +/// One argument in a list of generic arguments to a path segment. +/// +/// Part of [`GenericArgs`]. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +#[serde(rename_all = "snake_case")] +pub enum GenericArg { + /// A lifetime argument. + /// ```text + /// std::borrow::Cow<'static, str> + /// ^^^^^^^ + /// ``` + Lifetime(String), + /// A type argument. + /// ```text + /// std::borrow::Cow<'static, str> + /// ^^^ + /// ``` + Type(Type), + /// A constant as a generic argument. + /// ```text + /// core::array::IntoIter + /// ^^^^^^^^^^^^^^ + /// ``` + Const(Constant), + /// A generic argument that's explicitly set to be inferred. + /// ```text + /// std::vec::Vec::<_> + /// ^ + /// ``` + Infer, +} + +/// A constant. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +pub struct Constant { + /// The stringified expression of this constant. Note that its mapping to the original + /// source code is unstable and it's not guaranteed that it'll match the source code. + pub expr: String, + /// The value of the evaluated expression for this constant, which is only computed for numeric + /// types. + pub value: Option, + /// Whether this constant is a bool, numeric, string, or char literal. + pub is_literal: bool, +} + +/// Describes a bound applied to an associated type/constant. +/// +/// Example: +/// ```text +/// IntoIterator +/// ^^^^^^^^^^ ^^^^^^^^^^^^^^^ +/// ``` +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +#[rkyv( + serialize_bounds(__S: rkyv::ser::Writer + rkyv::ser::Allocator, __S::Error: rkyv::rancor::Source), + deserialize_bounds(__D: rkyv::de::Pooling, __D::Error: rkyv::rancor::Source), +)] +pub struct AssocItemConstraint { + /// The name of the associated type/constant. + pub name: String, + /// Arguments provided to the associated type/constant. + #[rkyv(omit_bounds)] + pub args: Option>, + /// The kind of bound applied to the associated type/constant. + pub binding: AssocItemConstraintKind, +} + +/// The way in which an associate type/constant is bound. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +#[serde(rename_all = "snake_case")] +pub enum AssocItemConstraintKind { + /// The required value/type is specified exactly. e.g. + /// ```text + /// Iterator + /// ^^^^^^^^^^ + /// ``` + Equality(Term), + /// The type is required to satisfy a set of bounds. + /// ```text + /// Iterator + /// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + /// ``` + Constraint(Vec), +} + +/// An opaque identifier for an item. +/// +/// It can be used to lookup in [`Crate::index`] or [`Crate::paths`] to resolve it +/// to an [`Item`]. +/// +/// Id's are only valid within a single JSON blob. They cannot be used to +/// resolve references between the JSON output's for different crates. +/// +/// Rustdoc makes no guarantees about the inner value of Id's. Applications +/// should treat them as opaque keys to lookup items, and avoid attempting +/// to parse them, or otherwise depend on any implementation details. +#[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + PartialOrd, + Ord, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash))] +// FIXME(aDotInTheVoid): Consider making this non-public in rustdoc-types. +pub struct Id(pub u32); + +/// The fundamental kind of an item. Unlike [`ItemEnum`], this does not carry any additional info. +/// +/// Part of [`ItemSummary`]. +#[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +#[serde(rename_all = "snake_case")] +pub enum ItemKind { + /// A module declaration, e.g. `mod foo;` or `mod foo {}` + Module, + /// A crate imported via the `extern crate` syntax. + ExternCrate, + /// An import of 1 or more items into scope, using the `use` keyword. + Use, + /// A `struct` declaration. + Struct, + /// A field of a struct. + StructField, + /// A `union` declaration. + Union, + /// An `enum` declaration. + Enum, + /// A variant of a enum. + Variant, + /// A function declaration, e.g. `fn f() {}` + Function, + /// A type alias declaration, e.g. `type Pig = std::borrow::Cow<'static, str>;` + TypeAlias, + /// The declaration of a constant, e.g. `const GREETING: &str = "Hi :3";` + Constant, + /// A `trait` declaration. + Trait, + /// A trait alias declaration, e.g. `trait Int = Add + Sub + Mul + Div;` + /// + /// See [the tracking issue](https://github.com/rust-lang/rust/issues/41517) + TraitAlias, + /// An `impl` block. + Impl, + /// A `static` declaration. + Static, + /// `type`s from an `extern` block. + /// + /// See [the tracking issue](https://github.com/rust-lang/rust/issues/43467) + ExternType, + /// A macro declaration. + /// + /// Corresponds to either `ItemEnum::Macro(_)` + /// or `ItemEnum::ProcMacro(ProcMacro { kind: MacroKind::Bang })` + Macro, + /// A procedural macro attribute. + /// + /// Corresponds to `ItemEnum::ProcMacro(ProcMacro { kind: MacroKind::Attr })` + ProcAttribute, + /// A procedural macro usable in the `#[derive()]` attribute. + /// + /// Corresponds to `ItemEnum::ProcMacro(ProcMacro { kind: MacroKind::Derive })` + ProcDerive, + /// An associated constant of a trait or a type. + AssocConst, + /// An associated type of a trait or a type. + AssocType, + /// A primitive type, e.g. `u32`. + /// + /// [`Item`]s of this kind only come from the core library. + Primitive, + /// A keyword declaration. + /// + /// [`Item`]s of this kind only come from the come library and exist solely + /// to carry documentation for the respective keywords. + Keyword, + /// An attribute declaration. + /// + /// [`Item`]s of this kind only come from the core library and exist solely + /// to carry documentation for the respective builtin attributes. + Attribute, +} + +/// Specific fields of an item. +/// +/// Part of [`Item`]. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +#[serde(rename_all = "snake_case")] +pub enum ItemEnum { + /// A module declaration, e.g. `mod foo;` or `mod foo {}` + Module(Module), + /// A crate imported via the `extern crate` syntax. + ExternCrate { + /// The name of the imported crate. + name: String, + /// If the crate is renamed, this is its name in the crate. + rename: Option, + }, + /// An import of 1 or more items into scope, using the `use` keyword. + Use(Use), + + /// A `union` declaration. + Union(Union), + /// A `struct` declaration. + Struct(Struct), + /// A field of a struct. + StructField(Type), + /// An `enum` declaration. + Enum(Enum), + /// A variant of a enum. + Variant(Variant), + + /// A function declaration (including methods and other associated functions) + Function(Function), + + /// A `trait` declaration. + Trait(Trait), + /// A trait alias declaration, e.g. `trait Int = Add + Sub + Mul + Div;` + /// + /// See [the tracking issue](https://github.com/rust-lang/rust/issues/41517) + TraitAlias(TraitAlias), + /// An `impl` block. + Impl(Impl), + + /// A type alias declaration, e.g. `type Pig = std::borrow::Cow<'static, str>;` + TypeAlias(TypeAlias), + /// The declaration of a constant, e.g. `const GREETING: &str = "Hi :3";` + Constant { + /// The type of the constant. + #[serde(rename = "type")] + type_: Type, + /// The declared constant itself. + #[serde(rename = "const")] + const_: Constant, + }, + + /// A declaration of a `static`. + Static(Static), + + /// `type`s from an `extern` block. + /// + /// See [the tracking issue](https://github.com/rust-lang/rust/issues/43467) + ExternType, + + /// A macro_rules! declarative macro. Contains a single string with the source + /// representation of the macro with the patterns stripped. + Macro(String), + /// A procedural macro. + ProcMacro(ProcMacro), + + /// A primitive type, e.g. `u32`. + /// + /// [`Item`]s of this kind only come from the core library. + Primitive(Primitive), + + /// An associated constant of a trait or a type. + AssocConst { + /// The type of the constant. + #[serde(rename = "type")] + type_: Type, + /// Inside a trait declaration, this is the default value for the associated constant, + /// if provided. + /// Inside an `impl` block, this is the value assigned to the associated constant, + /// and will always be present. + /// + /// The representation is implementation-defined and not guaranteed to be representative of + /// either the resulting value or of the source code. + /// + /// ```rust + /// const X: usize = 640 * 1024; + /// // ^^^^^^^^^^ + /// ``` + value: Option, + }, + /// An associated type of a trait or a type. + AssocType { + /// The generic parameters and where clauses on ahis associated type. + generics: Generics, + /// The bounds for this associated type. e.g. + /// ```rust + /// trait IntoIterator { + /// type Item; + /// type IntoIter: Iterator; + /// // ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + /// } + /// ``` + bounds: Vec, + /// Inside a trait declaration, this is the default for the associated type, if provided. + /// Inside an impl block, this is the type assigned to the associated type, and will always + /// be present. + /// + /// ```rust + /// type X = usize; + /// // ^^^^^ + /// ``` + #[serde(rename = "type")] + type_: Option, + }, +} + +/// A module declaration, e.g. `mod foo;` or `mod foo {}`. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +pub struct Module { + /// Whether this is the root item of a crate. + /// + /// This item doesn't correspond to any construction in the source code and is generated by the + /// compiler. + pub is_crate: bool, + /// [`Item`]s declared inside this module. + pub items: Vec, + /// If `true`, this module is not part of the public API, but it contains + /// items that are re-exported as public API. + pub is_stripped: bool, +} + +/// A `union`. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +pub struct Union { + /// The generic parameters and where clauses on this union. + pub generics: Generics, + /// Whether any fields have been removed from the result, due to being private or hidden. + pub has_stripped_fields: bool, + /// The list of fields in the union. + /// + /// All of the corresponding [`Item`]s are of kind [`ItemEnum::StructField`]. + pub fields: Vec, + /// All impls (both of traits and inherent) for this union. + /// + /// All of the corresponding [`Item`]s are of kind [`ItemEnum::Impl`]. + pub impls: Vec, +} + +/// A `struct`. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +pub struct Struct { + /// The kind of the struct (e.g. unit, tuple-like or struct-like) and the data specific to it, + /// i.e. fields. + pub kind: StructKind, + /// The generic parameters and where clauses on this struct. + pub generics: Generics, + /// All impls (both of traits and inherent) for this struct. + /// All of the corresponding [`Item`]s are of kind [`ItemEnum::Impl`]. + pub impls: Vec, +} + +/// The kind of a [`Struct`] and the data specific to it, i.e. fields. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +#[serde(rename_all = "snake_case")] +pub enum StructKind { + /// A struct with no fields and no parentheses. + /// + /// ```rust + /// pub struct Unit; + /// ``` + Unit, + /// A struct with unnamed fields. + /// + /// All [`Id`]'s will point to [`ItemEnum::StructField`]. + /// Unlike most of JSON, private and `#[doc(hidden)]` fields will be given as `None` + /// instead of being omitted, because order matters. + /// + /// ```rust + /// pub struct TupleStruct(i32); + /// pub struct EmptyTupleStruct(); + /// ``` + Tuple(Vec>), + /// A struct with named fields. + /// + /// ```rust + /// pub struct PlainStruct { x: i32 } + /// pub struct EmptyPlainStruct {} + /// ``` + Plain { + /// The list of fields in the struct. + /// + /// All of the corresponding [`Item`]s are of kind [`ItemEnum::StructField`]. + fields: Vec, + /// Whether any fields have been removed from the result, due to being private or hidden. + has_stripped_fields: bool, + }, +} + +/// An `enum`. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +pub struct Enum { + /// Information about the type parameters and `where` clauses of the enum. + pub generics: Generics, + /// Whether any variants have been removed from the result, due to being private or hidden. + pub has_stripped_variants: bool, + /// The list of variants in the enum. + /// + /// All of the corresponding [`Item`]s are of kind [`ItemEnum::Variant`] + pub variants: Vec, + /// `impl`s for the enum. + pub impls: Vec, +} + +/// A variant of an enum. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +pub struct Variant { + /// Whether the variant is plain, a tuple-like, or struct-like. Contains the fields. + pub kind: VariantKind, + /// The discriminant, if explicitly specified. + pub discriminant: Option, +} + +/// The kind of an [`Enum`] [`Variant`] and the data specific to it, i.e. fields. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +#[serde(rename_all = "snake_case")] +pub enum VariantKind { + /// A variant with no parentheses + /// + /// ```rust + /// enum Demo { + /// PlainVariant, + /// PlainWithDiscriminant = 1, + /// } + /// ``` + Plain, + /// A variant with unnamed fields. + /// + /// All [`Id`]'s will point to [`ItemEnum::StructField`]. + /// Unlike most of JSON, `#[doc(hidden)]` fields will be given as `None` + /// instead of being omitted, because order matters. + /// + /// ```rust + /// enum Demo { + /// TupleVariant(i32), + /// EmptyTupleVariant(), + /// } + /// ``` + Tuple(Vec>), + /// A variant with named fields. + /// + /// ```rust + /// enum Demo { + /// StructVariant { x: i32 }, + /// EmptyStructVariant {}, + /// } + /// ``` + Struct { + /// The list of variants in the enum. + /// All of the corresponding [`Item`]s are of kind [`ItemEnum::Variant`]. + fields: Vec, + /// Whether any variants have been removed from the result, due to being private or hidden. + has_stripped_fields: bool, + }, +} + +/// The value that distinguishes a variant in an [`Enum`] from other variants. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +pub struct Discriminant { + /// The expression that produced the discriminant. + /// + /// Unlike `value`, this preserves the original formatting (eg suffixes, + /// hexadecimal, and underscores), making it unsuitable to be machine + /// interpreted. + /// + /// In some cases, when the value is too complex, this may be `"{ _ }"`. + /// When this occurs is unstable, and may change without notice. + pub expr: String, + /// The numerical value of the discriminant. Stored as a string due to + /// JSON's poor support for large integers, and the fact that it would need + /// to store from [`i128::MIN`] to [`u128::MAX`]. + pub value: String, +} + +/// A set of fundamental properties of a function. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +pub struct FunctionHeader { + /// Is this function marked as `const`? + pub is_const: bool, + /// Is this function unsafe? + pub is_unsafe: bool, + /// Is this function async? + pub is_async: bool, + /// The ABI used by the function. + pub abi: Abi, +} + +/// The ABI (Application Binary Interface) used by a function. +/// +/// If a variant has an `unwind` field, this means the ABI that it represents can be specified in 2 +/// ways: `extern "_"` and `extern "_-unwind"`, and a value of `true` for that field signifies the +/// latter variant. +/// +/// See the [Rustonomicon section](https://doc.rust-lang.org/nightly/nomicon/ffi.html#ffi-and-unwinding) +/// on unwinding for more info. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +pub enum Abi { + // We only have a concrete listing here for stable ABI's because there are so many + // See rustc_ast_passes::feature_gate::PostExpansionVisitor::check_abi for the list + /// The default ABI, but that can also be written explicitly with `extern "Rust"`. + Rust, + /// Can be specified as `extern "C"` or, as a shorthand, just `extern`. + C { unwind: bool }, + /// Can be specified as `extern "cdecl"`. + Cdecl { unwind: bool }, + /// Can be specified as `extern "stdcall"`. + Stdcall { unwind: bool }, + /// Can be specified as `extern "fastcall"`. + Fastcall { unwind: bool }, + /// Can be specified as `extern "aapcs"`. + Aapcs { unwind: bool }, + /// Can be specified as `extern "win64"`. + Win64 { unwind: bool }, + /// Can be specified as `extern "sysv64"`. + SysV64 { unwind: bool }, + /// Can be specified as `extern "system"`. + System { unwind: bool }, + /// Any other ABI, including unstable ones. + Other(String), +} + +/// A function declaration (including methods and other associated functions). +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +pub struct Function { + /// Information about the function signature, or declaration. + pub sig: FunctionSignature, + /// Information about the function’s type parameters and `where` clauses. + pub generics: Generics, + /// Information about core properties of the function, e.g. whether it's `const`, its ABI, etc. + pub header: FunctionHeader, + /// Whether the function has a body, i.e. an implementation. + pub has_body: bool, +} + +/// Generic parameters accepted by an item and `where` clauses imposed on it and the parameters. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +pub struct Generics { + /// A list of generic parameter definitions (e.g. ``). + pub params: Vec, + /// A list of where predicates (e.g. `where T: Iterator, T::Item: Copy`). + pub where_predicates: Vec, +} + +/// One generic parameter accepted by an item. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +pub struct GenericParamDef { + /// Name of the parameter. + /// ```rust + /// fn f<'resource, Resource>(x: &'resource Resource) {} + /// // ^^^^^^^^ ^^^^^^^^ + /// ``` + pub name: String, + /// The kind of the parameter and data specific to a particular parameter kind, e.g. type + /// bounds. + pub kind: GenericParamDefKind, +} + +/// The kind of a [`GenericParamDef`]. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +#[rkyv( + serialize_bounds(__S: rkyv::ser::Writer + rkyv::ser::Allocator, __S::Error: rkyv::rancor::Source), + deserialize_bounds(__D: rkyv::de::Pooling, __D::Error: rkyv::rancor::Source), +)] +#[serde(rename_all = "snake_case")] +pub enum GenericParamDefKind { + /// Denotes a lifetime parameter. + Lifetime { + /// Lifetimes that this lifetime parameter is required to outlive. + /// + /// ```rust + /// fn f<'a, 'b, 'resource: 'a + 'b>(a: &'a str, b: &'b str, res: &'resource str) {} + /// // ^^^^^^^ + /// ``` + outlives: Vec, + }, + + /// Denotes a type parameter. + Type { + /// Bounds applied directly to the type. Note that the bounds from `where` clauses + /// that constrain this parameter won't appear here. + /// + /// ```rust + /// fn default2() -> [T; 2] where T: Clone { todo!() } + /// // ^^^^^^^ + /// ``` + #[rkyv(omit_bounds)] + bounds: Vec, + /// The default type for this parameter, if provided, e.g. + /// + /// ```rust + /// trait PartialEq {} + /// // ^^^^ + /// ``` + #[rkyv(omit_bounds)] + default: Option, + /// This is normally `false`, which means that this generic parameter is + /// declared in the Rust source text. + /// + /// If it is `true`, this generic parameter has been introduced by the + /// compiler behind the scenes. + /// + /// # Example + /// + /// Consider + /// + /// ```ignore (pseudo-rust) + /// pub fn f(_: impl Trait) {} + /// ``` + /// + /// The compiler will transform this behind the scenes to + /// + /// ```ignore (pseudo-rust) + /// pub fn f(_: impl Trait) {} + /// ``` + /// + /// In this example, the generic parameter named `impl Trait` (and which + /// is bound by `Trait`) is synthetic, because it was not originally in + /// the Rust source text. + is_synthetic: bool, + }, + + /// Denotes a constant parameter. + Const { + /// The type of the constant as declared. + #[serde(rename = "type")] + #[rkyv(omit_bounds)] + type_: Type, + /// The stringified expression for the default value, if provided. It's not guaranteed that + /// it'll match the actual source code for the default value. + default: Option, + }, +} + +/// One `where` clause. +/// ```rust +/// fn default() -> T where T: Default { T::default() } +/// // ^^^^^^^^^^ +/// ``` +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +#[serde(rename_all = "snake_case")] +pub enum WherePredicate { + /// A type is expected to comply with a set of bounds + BoundPredicate { + /// The type that's being constrained. + /// + /// ```rust + /// fn f(x: T) where for<'a> &'a T: Iterator {} + /// // ^ + /// ``` + #[serde(rename = "type")] + type_: Type, + /// The set of bounds that constrain the type. + /// + /// ```rust + /// fn f(x: T) where for<'a> &'a T: Iterator {} + /// // ^^^^^^^^ + /// ``` + bounds: Vec, + /// Used for Higher-Rank Trait Bounds (HRTBs) + /// ```rust + /// fn f(x: T) where for<'a> &'a T: Iterator {} + /// // ^^^^^^^ + /// ``` + generic_params: Vec, + }, + + /// A lifetime is expected to outlive other lifetimes. + LifetimePredicate { + /// The name of the lifetime. + lifetime: String, + /// The lifetimes that must be encompassed by the lifetime. + outlives: Vec, + }, + + /// A type must exactly equal another type. + EqPredicate { + /// The left side of the equation. + lhs: Type, + /// The right side of the equation. + rhs: Term, + }, +} + +/// Either a trait bound or a lifetime bound. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +#[serde(rename_all = "snake_case")] +pub enum GenericBound { + /// A trait bound. + TraitBound { + /// The full path to the trait. + #[serde(rename = "trait")] + trait_: Path, + /// Used for Higher-Rank Trait Bounds (HRTBs) + /// ```text + /// where F: for<'a, 'b> Fn(&'a u8, &'b u8) + /// ^^^^^^^^^^^ + /// | + /// this part + /// ``` + generic_params: Vec, + /// The context for which a trait is supposed to be used, e.g. `const + modifier: TraitBoundModifier, + }, + /// A lifetime bound, e.g. + /// ```rust + /// fn f<'a, T>(x: &'a str, y: &T) where T: 'a {} + /// // ^^^ + /// ``` + Outlives(String), + /// `use<'a, T>` precise-capturing bound syntax + Use(Vec), +} + +/// A set of modifiers applied to a trait. +#[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +#[serde(rename_all = "snake_case")] +pub enum TraitBoundModifier { + /// Marks the absence of a modifier. + None, + /// Indicates that the trait bound relaxes a trait bound applied to a parameter by default, + /// e.g. `T: Sized?`, the `Sized` trait is required for all generic type parameters by default + /// unless specified otherwise with this modifier. + Maybe, + /// Indicates that the trait bound must be applicable in both a run-time and a compile-time + /// context. + MaybeConst, +} + +/// One precise capturing argument. See [the rust reference](https://doc.rust-lang.org/reference/types/impl-trait.html#precise-capturing). +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +#[serde(rename_all = "snake_case")] +pub enum PreciseCapturingArg { + /// A lifetime. + /// ```rust + /// pub fn hello<'a, T, const N: usize>() -> impl Sized + use<'a, T, N> {} + /// // ^^ + Lifetime(String), + /// A type or constant parameter. + /// ```rust + /// pub fn hello<'a, T, const N: usize>() -> impl Sized + use<'a, T, N> {} + /// // ^ ^ + Param(String), +} + +/// Either a type or a constant, usually stored as the right-hand side of an equation in places like +/// [`AssocItemConstraint`] +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +#[serde(rename_all = "snake_case")] +pub enum Term { + /// A type. + /// + /// ```rust + /// fn f(x: impl IntoIterator) {} + /// // ^^^ + /// ``` + Type(Type), + /// A constant. + /// + /// ```ignore (incomplete feature in the snippet) + /// trait Foo { + /// const BAR: usize; + /// } + /// + /// fn f(x: impl Foo) {} + /// // ^^ + /// ``` + Constant(Constant), +} + +/// A type. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +#[rkyv( + serialize_bounds(__S: rkyv::ser::Writer + rkyv::ser::Allocator, __S::Error: rkyv::rancor::Source), + deserialize_bounds(__D: rkyv::de::Pooling, __D::Error: rkyv::rancor::Source), +)] +#[serde(rename_all = "snake_case")] +pub enum Type { + /// Structs, enums, unions and type aliases, e.g. `std::option::Option` + ResolvedPath(Path), + /// Dynamic trait object type (`dyn Trait`). + DynTrait(DynTrait), + /// Parameterized types. The contained string is the name of the parameter. + Generic(String), + /// Built-in numeric types (e.g. `u32`, `f32`), `bool`, `char`. + Primitive(String), + /// A function pointer type, e.g. `fn(u32) -> u32`, `extern "C" fn() -> *const u8` + FunctionPointer(#[rkyv(omit_bounds)] Box), + /// A tuple type, e.g. `(String, u32, Box)` + Tuple(#[rkyv(omit_bounds)] Vec), + /// An unsized slice type, e.g. `[u32]`. + Slice(#[rkyv(omit_bounds)] Box), + /// An array type, e.g. `[u32; 15]` + Array { + /// The type of the contained element. + #[serde(rename = "type")] + #[rkyv(omit_bounds)] + type_: Box, + /// The stringified expression that is the length of the array. + /// + /// Keep in mind that it's not guaranteed to match the actual source code of the expression. + len: String, + }, + /// A pattern type, e.g. `u32 is 1..` + /// + /// See [the tracking issue](https://github.com/rust-lang/rust/issues/123646) + Pat { + /// The base type, e.g. the `u32` in `u32 is 1..` + #[serde(rename = "type")] + #[rkyv(omit_bounds)] + type_: Box, + #[doc(hidden)] + __pat_unstable_do_not_use: String, + }, + /// An opaque type that satisfies a set of bounds, `impl TraitA + TraitB + ...` + ImplTrait(Vec), + /// A type that's left to be inferred, `_` + Infer, + /// A raw pointer type, e.g. `*mut u32`, `*const u8`, etc. + RawPointer { + /// This is `true` for `*mut _` and `false` for `*const _`. + is_mutable: bool, + /// The type of the pointee. + #[serde(rename = "type")] + #[rkyv(omit_bounds)] + type_: Box, + }, + /// `&'a mut String`, `&str`, etc. + BorrowedRef { + /// The name of the lifetime of the reference, if provided. + lifetime: Option, + /// This is `true` for `&mut i32` and `false` for `&i32` + is_mutable: bool, + /// The type of the pointee, e.g. the `i32` in `&'a mut i32` + #[serde(rename = "type")] + #[rkyv(omit_bounds)] + type_: Box, + }, + /// Associated types like `::Name` and `T::Item` where + /// `T: Iterator` or inherent associated types like `Struct::Name`. + QualifiedPath { + /// The name of the associated type in the parent type. + /// + /// ```ignore (incomplete expression) + /// as Iterator>::Item + /// // ^^^^ + /// ``` + name: String, + /// The generic arguments provided to the associated type. + /// + /// ```ignore (incomplete expression) + /// as BetterIterator>::Item<'static> + /// // ^^^^^^^^^ + /// ``` + #[rkyv(omit_bounds)] + args: Option>, + /// The type with which this type is associated. + /// + /// ```ignore (incomplete expression) + /// as Iterator>::Item + /// // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + /// ``` + #[rkyv(omit_bounds)] + self_type: Box, + /// `None` iff this is an *inherent* associated type. + #[serde(rename = "trait")] + trait_: Option, + }, +} + +/// A type that has a simple path to it. This is the kind of type of structs, unions, enums, etc. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +#[rkyv( + serialize_bounds(__S: rkyv::ser::Writer + rkyv::ser::Allocator, __S::Error: rkyv::rancor::Source), + deserialize_bounds(__D: rkyv::de::Pooling, __D::Error: rkyv::rancor::Source), +)] +pub struct Path { + /// The path of the type. + /// + /// This will be the path that is *used* (not where it is defined), so + /// multiple `Path`s may have different values for this field even if + /// they all refer to the same item. e.g. + /// + /// ```rust + /// pub type Vec1 = std::vec::Vec; // path: "std::vec::Vec" + /// pub type Vec2 = Vec; // path: "Vec" + /// pub type Vec3 = std::prelude::v1::Vec; // path: "std::prelude::v1::Vec" + /// ``` + // + // Example tested in ./tests/rustdoc-json/path_name.rs + pub path: String, + /// The ID of the type. + pub id: Id, + /// Generic arguments to the type. + /// + /// ```ignore (incomplete expression) + /// std::borrow::Cow<'static, str> + /// // ^^^^^^^^^^^^^^ + /// ``` + #[rkyv(omit_bounds)] + pub args: Option>, +} + +/// A type that is a function pointer. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +pub struct FunctionPointer { + /// The signature of the function. + pub sig: FunctionSignature, + /// Used for Higher-Rank Trait Bounds (HRTBs) + /// + /// ```ignore (incomplete expression) + /// for<'c> fn(val: &'c i32) -> i32 + /// // ^^^^^^^ + /// ``` + pub generic_params: Vec, + /// The core properties of the function, such as the ABI it conforms to, whether it's unsafe, etc. + pub header: FunctionHeader, +} + +/// The signature of a function. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +pub struct FunctionSignature { + /// List of argument names and their type. + /// + /// Note that not all names will be valid identifiers, as some of + /// them may be patterns. + pub inputs: Vec<(String, Type)>, + /// The output type, if specified. + pub output: Option, + /// Whether the function accepts an arbitrary amount of trailing arguments the C way. + /// + /// ```ignore (incomplete code) + /// fn printf(fmt: &str, ...); + /// ``` + pub is_c_variadic: bool, +} + +/// A `trait` declaration. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +pub struct Trait { + /// Whether the trait is marked `auto` and is thus implemented automatically + /// for all applicable types. + pub is_auto: bool, + /// Whether the trait is marked as `unsafe`. + pub is_unsafe: bool, + /// Whether the trait is [dyn compatible](https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility)[^1]. + /// + /// [^1]: Formerly known as "object safe". + pub is_dyn_compatible: bool, + /// Associated [`Item`]s that can/must be implemented by the `impl` blocks. + pub items: Vec, + /// Information about the type parameters and `where` clauses of the trait. + pub generics: Generics, + /// Constraints that must be met by the implementor of the trait. + pub bounds: Vec, + /// The implementations of the trait. + pub implementations: Vec, +} + +/// A trait alias declaration, e.g. `trait Int = Add + Sub + Mul + Div;` +/// +/// See [the tracking issue](https://github.com/rust-lang/rust/issues/41517) +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +pub struct TraitAlias { + /// Information about the type parameters and `where` clauses of the alias. + pub generics: Generics, + /// The bounds that are associated with the alias. + pub params: Vec, +} + +/// An `impl` block. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +pub struct Impl { + /// Whether this impl is for an unsafe trait. + pub is_unsafe: bool, + /// Information about the impl’s type parameters and `where` clauses. + pub generics: Generics, + /// The list of the names of all the trait methods that weren't mentioned in this impl but + /// were provided by the trait itself. + /// + /// For example, for this impl of the [`PartialEq`] trait: + /// ```rust + /// struct Foo; + /// + /// impl PartialEq for Foo { + /// fn eq(&self, other: &Self) -> bool { todo!() } + /// } + /// ``` + /// This field will be `["ne"]`, as it has a default implementation defined for it. + pub provided_trait_methods: Vec, + /// The trait being implemented or `None` if the impl is inherent, which means + /// `impl Struct {}` as opposed to `impl Trait for Struct {}`. + #[serde(rename = "trait")] + pub trait_: Option, + /// The type that the impl block is for. + #[serde(rename = "for")] + pub for_: Type, + /// The list of associated items contained in this impl block. + pub items: Vec, + /// Whether this is a negative impl (e.g. `!Sized` or `!Send`). + pub is_negative: bool, + /// Whether this is an impl that’s implied by the compiler + /// (for autotraits, e.g. `Send` or `Sync`). + pub is_synthetic: bool, + // FIXME: document this + pub blanket_impl: Option, +} + +/// A `use` statement. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +#[serde(rename_all = "snake_case")] +pub struct Use { + /// The full path being imported. + pub source: String, + /// May be different from the last segment of `source` when renaming imports: + /// `use source as name;` + pub name: String, + /// The ID of the item being imported. Will be `None` in case of re-exports of primitives: + /// ```rust + /// pub use i32 as my_i32; + /// ``` + pub id: Option, + /// Whether this statement is a wildcard `use`, e.g. `use source::*;` + pub is_glob: bool, +} + +/// A procedural macro. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +pub struct ProcMacro { + /// How this macro is supposed to be called: `foo!()`, `#[foo]` or `#[derive(foo)]` + pub kind: MacroKind, + /// Helper attributes defined by a macro to be used inside it. + /// + /// Defined only for derive macros. + /// + /// E.g. the [`Default`] derive macro defines a `#[default]` helper attribute so that one can + /// do: + /// + /// ```rust + /// #[derive(Default)] + /// enum Option { + /// #[default] + /// None, + /// Some(T), + /// } + /// ``` + pub helpers: Vec, +} + +/// The way a [`ProcMacro`] is declared to be used. +#[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +#[serde(rename_all = "snake_case")] +pub enum MacroKind { + /// A bang macro `foo!()`. + Bang, + /// An attribute macro `#[foo]`. + Attr, + /// A derive macro `#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]` + Derive, +} + +/// A type alias declaration, e.g. `type Pig = std::borrow::Cow<'static, str>;` +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +pub struct TypeAlias { + /// The type referred to by this alias. + #[serde(rename = "type")] + pub type_: Type, + /// Information about the type parameters and `where` clauses of the alias. + pub generics: Generics, +} + +/// A `static` declaration. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +pub struct Static { + /// The type of the static. + #[serde(rename = "type")] + pub type_: Type, + /// This is `true` for mutable statics, declared as `static mut X: T = f();` + pub is_mutable: bool, + /// The stringified expression for the initial value. + /// + /// It's not guaranteed that it'll match the actual source code for the initial value. + pub expr: String, + + /// Is the static `unsafe`? + /// + /// This is only true if it's in an `extern` block, and not explicitly marked + /// as `safe`. + /// + /// ```rust + /// unsafe extern { + /// static A: i32; // unsafe + /// safe static B: i32; // safe + /// } + /// + /// static C: i32 = 0; // safe + /// static mut D: i32 = 0; // safe + /// ``` + pub is_unsafe: bool, +} + +/// A primitive type declaration. Declarations of this kind can only come from the core library. +#[derive( + Clone, + Debug, + PartialEq, + Eq, + Hash, + Serialize, + Deserialize, + Encode, + Decode, + rkyv::Archive, + rkyv::Serialize, + rkyv::Deserialize, +)] +#[rkyv(derive(Debug))] +pub struct Primitive { + /// The name of the type. + pub name: String, + /// The implementations, inherent and of traits, on the primitive type. + pub impls: Vec, +} diff --git a/compiler/pavex_test_runner/Cargo.toml b/compiler/pavex_test_runner/Cargo.toml index f89d9a120..3afd911e3 100644 --- a/compiler/pavex_test_runner/Cargo.toml +++ b/compiler/pavex_test_runner/Cargo.toml @@ -16,6 +16,7 @@ anyhow = { workspace = true } ahash = { workspace = true } console = { workspace = true } cargo_metadata = { workspace = true } +cargo-like-utils = { workspace = true } fs-err = { workspace = true } libtest-mimic = { workspace = true } serde = { workspace = true, features = ["derive"] } @@ -32,6 +33,7 @@ object-pool = { workspace = true } num_cpus = { workspace = true } globwalk = { workspace = true } tracing-subscriber = { workspace = true, features = ["env-filter", "fmt"] } +pavex_cli_shell = { workspace = true } regex = { workspace = true } once_cell = { workspace = true } pavexc = { workspace = true } diff --git a/compiler/pavex_test_runner/src/lib.rs b/compiler/pavex_test_runner/src/lib.rs index c461598e5..d8d159a03 100644 --- a/compiler/pavex_test_runner/src/lib.rs +++ b/compiler/pavex_test_runner/src/lib.rs @@ -6,11 +6,13 @@ use std::process::{Command, Output}; use ahash::HashSet; use anyhow::Context; +use cargo_like_utils::shell::Shell; use cargo_metadata::diagnostic::DiagnosticLevel; use console::style; use guppy::graph::PackageGraph; use itertools::Itertools; use libtest_mimic::{Arguments, Conclusion, Failed, Trial}; +use pavex_cli_shell::try_init_shell; use pavexc::rustdoc::CrateCollection; use pavexc::{DEFAULT_DOCS_TOOLCHAIN, DiagnosticSink}; use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; @@ -47,6 +49,14 @@ pub fn get_test_name(tests_parent_folder: &Path, test_folder: &Path) -> String { .join("::") } +/// All `cargo` commands in the test runner use this helper function to +/// compose command invocations. +/// Whenever you want to set a particular `cargo` flag across all invocations +/// (e.g. `-Zbuild-analysis`), do it here. +fn cargo_cmd() -> std::process::Command { + Command::new("cargo") +} + /// Create a test case for each folder in `definition_directory`. /// /// Each test will get a separate runtime environment—a sub-folder of `runtime_directory`. The @@ -92,23 +102,8 @@ pub fn run_tests( if !arguments.list { warm_up_target_dir(&tests_directory, &test_name2test_data)?; - let metadata = guppy::MetadataCommand::new() - .current_dir(&tests_directory) - .exec() - .context("Failed to invoke `cargo metadata`")?; - let metadata_path = tests_directory.join("metadata.json"); - - { - use std::io::Write as _; - - let mut file = BufWriter::new(fs_err::File::create(&metadata_path)?); - metadata - .serialize(&mut file) - .context("Failed to serialize Cargo's metadata to disk")?; - file.flush() - .context("Failed to serialize Cargo's metadata to disk")?; - } + let metadata = precompute_cargo_metadata(&tests_directory, &metadata_path)?; let package_graph = metadata .build_graph() @@ -119,6 +114,7 @@ pub fn run_tests( // acquire the global target directory lock. If multiple tests end up // doing this at the same time, their execution will be serialized, // which would have a major impact on the overall test suite runtime. + try_init_shell(Shell::new()); warm_up_rustdoc_cache(&package_graph, &test_name2test_data)?; // First battery of UI tests. @@ -234,6 +230,37 @@ fn increase_open_file_descriptor_limit() -> std::io::Result<()> { Ok(()) } +/// Invoke `cargo metadata` once and cache the result on disk, thus avoiding needless +/// recomputations in every single code generation task performed by UI tests. +fn precompute_cargo_metadata( + tests_directory: &Path, + metadata_path: &Path, +) -> Result { + let timer = std::time::Instant::now(); + println!("Precomputing `cargo` metadata"); + let metadata = guppy::MetadataCommand::new() + .current_dir(tests_directory) + .exec() + .context("Failed to invoke `cargo metadata`")?; + + { + use std::io::Write as _; + + let mut file = BufWriter::new(fs_err::File::create(metadata_path)?); + metadata + .serialize(&mut file) + .context("Failed to serialize Cargo's metadata to disk")?; + file.flush() + .context("Failed to serialize Cargo's metadata to disk")?; + } + println!( + "Precomputed `cargo metadata` in {} seconds", + timer.elapsed().as_secs() + ); + + Ok(metadata) +} + fn compile_generated_apps( runtime_directory: &Path, test_name2test_data: BTreeMap, @@ -247,7 +274,7 @@ fn compile_generated_apps( return Ok((Vec::new(), BTreeMap::new())); } println!("Compiling {} generated crates", generated_crate_names.len()); - let mut cmd = Command::new("cargo"); + let mut cmd = cargo_cmd(); cmd.arg("check").arg("--message-format").arg("json"); for name in &generated_crate_names { cmd.arg("-p").arg(name); @@ -371,7 +398,7 @@ fn warm_up_target_dir( let timer = std::time::Instant::now(); println!("Warming up the target directory"); - let mut cmd = Command::new("cargo"); + let mut cmd = cargo_cmd(); cmd.arg("build"); for data in test_name2test_data.values() { cmd.arg("-p").arg(data.blueprint_crate_name()); @@ -402,7 +429,6 @@ fn warm_up_rustdoc_cache( // We want to ensure that all invocations of `pavexc generate` hit the cache // thus avoiding the need to invoke `rustdoc` and acquire a contentious // lock over the target directory. - println!("Pre-computing JSON documentation for relevant crates"); let crate_collection = CrateCollection::new( DEFAULT_DOCS_TOOLCHAIN.to_owned(), package_graph.clone(), @@ -419,14 +445,20 @@ fn warm_up_rustdoc_cache( .workspace() .iter() .filter(|p| { - !(p.name().starts_with("application_") + !( + // Avoid computing JOSN docs for: + // - Generated code + p.name().starts_with("application_") + // - Integration test crates || p.name().starts_with("integration_") + // - The workspace hack package || p.name() == "workspace_hack" - || (p.name().starts_with("app_") && !app_names.contains(p.name()))) + // - Tests that have been filtered out of this run + || (p.name().starts_with("app_") && !app_names.contains(p.name())) + ) }) .map(|p| p.name().to_owned()) .collect(); - crates.remove("workspace_hack"); // Toolchain docs crates.insert("core".into()); crates.insert("alloc".into()); @@ -447,16 +479,19 @@ fn warm_up_rustdoc_cache( crates.insert("yansi".into()); crates.insert("serde".into()); crates.insert("zerocopy".into()); - let package_ids = crate_collection + let package_ids: Vec<_> = crate_collection .package_graph() .packages() .filter(|p| crates.contains(p.name())) - .map(|p| p.id().to_owned()); + .map(|p| p.id().to_owned()) + .collect(); + let n_packages = package_ids.len(); + println!("Pre-computing JSON documentation for {n_packages} crates",); crate_collection - .batch_compute_crates(package_ids) + .batch_compute_crates(package_ids.into_iter()) .context("Failed to warm rustdoc JSON cache")?; println!( - "Pre-computed JSON documentation in {} seconds", + "Pre-computed JSON documentation for {n_packages} crates in {} seconds", timer.elapsed().as_secs() ); @@ -685,7 +720,7 @@ impl TestData { fs_err::create_dir_all(&application_src_dir).context( "Failed to create the runtime directory for the generated application when setting up the test runtime environment", )?; - persist_if_changed(&application_src_dir.join("lib.rs"), b"")?; + create_file_if_missing(&application_src_dir.join("lib.rs"), b"")?; let mut cargo_toml = toml! { [package] @@ -700,8 +735,8 @@ impl TestData { cargo_toml["package"]["name"] = format!("application_{}", self.name_hash).into(); cargo_toml["package"]["metadata"]["px"]["generate"]["generator_name"] = format!("app_{}", self.name_hash).into(); - persist_if_changed( - &application_dir.join("Cargo.toml"), + create_file_if_missing( + &application_src_dir.join("Cargo.toml"), toml::to_string(&cargo_toml)?.as_bytes(), )?; } @@ -950,7 +985,7 @@ fn build_integration_tests(test_dir: &Path, test_name2test_data: &BTreeMap Result<(), anyhow::Error> { - let output = std::process::Command::new("cargo") + let output = cargo_cmd() // .env("RUSTFLAGS", "-Awarnings") .arg("t") .arg("-p") @@ -1024,3 +1059,16 @@ fn enrich_failure_message(config: &TestConfig, error: impl AsRef) -> String style("What went wrong:").red().bold(), ) } + +fn create_file_if_missing(path: &Path, content: &[u8]) -> Result<(), anyhow::Error> { + if !path.exists() { + if let Some(parent) = path.parent() { + fs_err::create_dir_all(parent).with_context(|| { + format!("Failed to create parent directories for {}", path.display()) + })?; + } + fs_err::write(path, content) + .with_context(|| format!("Failed to create file at {}", path.display()))?; + } + Ok(()) +} diff --git a/compiler/pavexc/Cargo.toml b/compiler/pavexc/Cargo.toml index 903982d7f..82e003855 100644 --- a/compiler/pavexc/Cargo.toml +++ b/compiler/pavexc/Cargo.toml @@ -66,6 +66,7 @@ camino = { workspace = true } xxhash-rust = { workspace = true, features = ["xxh64"] } rustc-hash = { workspace = true } globwalk = { workspace = true } +rkyv = { workspace = true } # Sqlite cache xdg-home = { workspace = true } diff --git a/compiler/pavexc/src/compiler/app.rs b/compiler/pavexc/src/compiler/app.rs index 2727ae189..6756d5dc9 100644 --- a/compiler/pavexc/src/compiler/app.rs +++ b/compiler/pavexc/src/compiler/app.rs @@ -1,5 +1,5 @@ use std::collections::BTreeSet; -use std::io::{BufWriter, Write}; +use std::io::Write; use std::path::Path; use ahash::{HashMap, HashMapExt}; @@ -7,6 +7,7 @@ use guppy::graph::PackageGraph; use indexmap::IndexMap; use pavex_bp_schema::Blueprint; +use persist_if_changed::persist_if_changed; use crate::compiler::analyses::application_config::ApplicationConfig; use crate::compiler::analyses::application_state::ApplicationState; @@ -291,22 +292,17 @@ pub struct AppDiagnostics { impl AppDiagnostics { /// Save all diagnostics in a single file. pub fn persist_flat(&self, filepath: &Path) -> Result<(), anyhow::Error> { - let file = fs_err::OpenOptions::new() - .create(true) - .write(true) - .truncate(true) - .open(filepath)?; - let mut file = BufWriter::new(file); - + let mut buffer = Vec::new(); for handler_graphs in &self.handlers { for handler_graph in handler_graphs { - file.write_all(handler_graph.as_bytes())?; + buffer.write_all(handler_graph.as_bytes())?; // Add a newline between graphs for readability - file.write_all("\n".as_bytes())?; + buffer.write_all("\n".as_bytes())?; } } - file.write_all(self.application_state.as_bytes())?; - file.flush()?; + buffer.write_all(self.application_state.as_bytes())?; + + persist_if_changed(filepath, &buffer)?; Ok(()) } } @@ -344,7 +340,7 @@ fn codegen_deps(package_graph: &PackageGraph) -> HashMap, annotation_id2item_id: BTreeMap, @@ -56,7 +58,7 @@ pub struct IdConflict { } /// An item decorated with a Pavex annotation. -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, bincode::Encode, bincode::Decode)] pub struct AnnotatedItem { /// The identifier of the annotated item. pub id: rustdoc_types::Id, @@ -67,7 +69,7 @@ pub struct AnnotatedItem { } /// Information about the `impl` block the item belongs to, if any. -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, bincode::Encode, bincode::Decode)] pub struct ImplInfo { /// The `id` of the item this `impl` block was attached to. /// For inherent methods, that's the `Self` type. diff --git a/compiler/pavexc/src/rustdoc/compute/cache.rs b/compiler/pavexc/src/rustdoc/compute/cache.rs index fd2e7f452..09f5b3fb7 100644 --- a/compiler/pavexc/src/rustdoc/compute/cache.rs +++ b/compiler/pavexc/src/rustdoc/compute/cache.rs @@ -1,7 +1,7 @@ use std::{borrow::Cow, collections::BTreeSet}; -use ahash::{HashMap, HashMapExt}; use anyhow::Context; +use bincode::{Decode, Encode}; use camino::Utf8Path; use guppy::{ PackageId, @@ -9,7 +9,8 @@ use guppy::{ }; use itertools::Itertools; use r2d2_sqlite::SqliteConnectionManager; -use rusqlite::params; +use rkyv::util::AlignedVec; +use rusqlite::{ToSql, params, types::ToSqlOutput}; use tracing::instrument; use tracing_log_error::log_error; @@ -99,13 +100,14 @@ impl RustdocGlobalFsCache { pub(crate) fn new( toolchain_name: &str, cache_workspace_package_docs: bool, + package_graph: &PackageGraph, ) -> Result { let cargo_fingerprint = cargo_fingerprint(toolchain_name)?; let pool = Self::setup_database()?; let connection = pool.get()?; let third_party_cache = - ThirdPartyCrateCache::new(&connection, cache_workspace_package_docs)?; + ThirdPartyCrateCache::new(&connection, cache_workspace_package_docs, package_graph)?; let toolchain_cache = ToolchainCache::new(&connection)?; Ok(Self { cargo_fingerprint, @@ -136,8 +138,9 @@ impl RustdocGlobalFsCache { } } - /// Store the JSON documentation generated by `rustdoc` in the cache. - pub(crate) fn insert( + /// Convert the JSON documentation generated by `rustdoc` into the format used by our cache, + /// then store it. + pub(crate) fn convert_and_insert( &self, cache_key: &RustdocCacheKey, krate: &crate::rustdoc::Crate, @@ -146,17 +149,53 @@ impl RustdocGlobalFsCache { ) -> Result<(), anyhow::Error> { let connection = self.connection_pool.get()?; match cache_key { - RustdocCacheKey::ThirdPartyCrate(metadata) => self.third_party_cache.insert( - metadata, + RustdocCacheKey::ThirdPartyCrate(metadata) => { + self.third_party_cache.convert_and_insert( + metadata, + krate, + &self.cargo_fingerprint, + &connection, + cache_indexes, + package_graph, + ) + } + RustdocCacheKey::ToolchainCrate(name) => self.toolchain_cache.convert_and_insert( + name, krate, &self.cargo_fingerprint, &connection, - cache_indexes, - package_graph, ), + } + } + + /// Store the JSON documentation for a crate, which has already been converted to the expected + /// format for caching. + /// + /// This method should be preferred to [`Self::insert`] whenever multi-threading is involved, + /// since [`RustdocGlobalFsCache`] isn't thread-safe, but the conversion into the caching format + /// doesn't require its internals and can therefore be offloaded to another thread without issues. + pub(crate) fn insert( + &self, + cache_key: &RustdocCacheKey, + cache_entry: CacheEntry, + package_graph: &PackageGraph, + ) -> Result<(), anyhow::Error> { + let connection = self.connection_pool.get()?; + match cache_key { + RustdocCacheKey::ThirdPartyCrate(metadata) => { + let Some(cache_key) = self.third_party_cache.cache_key( + metadata, + &self.cargo_fingerprint, + package_graph, + ) else { + return Ok(()); + }; + self.third_party_cache + .insert(cache_key, &connection, cache_entry) + } RustdocCacheKey::ToolchainCrate(name) => { self.toolchain_cache - .insert(name, krate, &self.cargo_fingerprint, &connection) + .insert(name, cache_entry, &self.cargo_fingerprint, &connection) } } } @@ -235,13 +274,31 @@ impl RustdocGlobalFsCache { // We can improve this in the future, if needed. let cache_path = cache_dir.join(format!("{pavex_fingerprint}.db")); - let manager = SqliteConnectionManager::file(cache_dir.join(cache_path)); + #[derive(Debug)] + struct SqlitePragmas; + + impl r2d2::CustomizeConnection for SqlitePragmas { + fn on_acquire(&self, conn: &mut rusqlite::Connection) -> Result<(), rusqlite::Error> { + conn.execute_batch( + // 250MB memory-mapped, more than enough. + "PRAGMA mmap_size=262144000;", + )?; + Ok(()) + } + } + + let manager = SqliteConnectionManager::file(cache_path); let pool = r2d2::Pool::builder() .max_size(num_cpus::get() as u32) + .connection_customizer(Box::new(SqlitePragmas)) .build(manager) .context("Failed to open/create a SQLite database to store the contents of pavex's rustdoc cache")?; let connection = pool.get()?; + connection.execute_batch( + "PRAGMA journal_mode=WAL; + PRAGMA synchronous=NORMAL;", + )?; connection.execute( "CREATE TABLE IF NOT EXISTS project2package_id_access_log ( project_fingerprint TEXT NOT NULL, @@ -285,7 +342,6 @@ impl ToolchainCache { paths, format_version, items, - item_id2delimiters, import_index, import_path2id, re_exports @@ -306,23 +362,18 @@ impl ToolchainCache { let paths = row.get_ref_unwrap(2).as_bytes()?; let format_version = row.get_ref_unwrap(3).as_i64()?; - let span = tracing::trace_span!("Copy items bytes buffer"); - let guard = span.enter(); - let items: Vec = row.get_unwrap(4); - drop(guard); + let items = row.get_ref_unwrap(4).as_bytes()?; - let item_id2delimiters = row.get_ref_unwrap(5).as_bytes()?; - let import_index = row.get_ref_unwrap(6).as_bytes()?; - let import_path2id = row.get_ref_unwrap(7).as_bytes()?; - let re_exports = row.get_ref_unwrap(8).as_bytes()?; + let import_index = row.get_ref_unwrap(5).as_bytes()?; + let import_path2id = row.get_ref_unwrap(6).as_bytes()?; + let re_exports = row.get_ref_unwrap(7).as_bytes()?; - let krate = CachedData { + let krate = CacheEntry { root_item_id, external_crates: Cow::Borrowed(external_crates), paths: Cow::Borrowed(paths), format_version, - items: Cow::Owned(items), - item_id2delimiters: Cow::Borrowed(item_id2delimiters), + items: CachedItems::Borrowed(items), secondary_indexes: Some(SecondaryIndexes { import_index: Cow::Borrowed(import_index), // Standard library crates don't have Pavex annotations. @@ -338,14 +389,26 @@ impl ToolchainCache { /// Store the JSON documentation for a toolchain crate in the cache. #[instrument(name = "Cache rustdoc output on disk", skip_all, level=tracing::Level::DEBUG, fields(crate.name = name))] - fn insert( + fn convert_and_insert( &self, name: &str, krate: &crate::rustdoc::Crate, cargo_fingerprint: &str, connection: &rusqlite::Connection, ) -> Result<(), anyhow::Error> { - let cached_data = CachedData::new(krate).context("Failed to serialize docs")?; + let cache_entry = CacheEntry::new(krate).context("Failed to serialize docs")?; + self.insert(name, cache_entry, cargo_fingerprint, connection) + } + + /// Store the JSON documentation for a toolchain crate in the cache. + #[instrument(name = "Cache rustdoc output on disk", skip_all, level=tracing::Level::DEBUG, fields(crate.name = name))] + fn insert( + &self, + name: &str, + cache_entry: CacheEntry<'_>, + cargo_fingerprint: &str, + connection: &rusqlite::Connection, + ) -> Result<(), anyhow::Error> { let mut stmt = connection.prepare_cached( "INSERT INTO rustdoc_toolchain_crates_cache ( name, @@ -355,32 +418,30 @@ impl ToolchainCache { paths, format_version, items, - item_id2delimiters, import_index, import_path2id, re_exports - ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", )?; stmt.execute(params![ name, cargo_fingerprint, - cached_data.root_item_id, - cached_data.external_crates, - cached_data.paths, - cached_data.format_version, - cached_data.items, - cached_data.item_id2delimiters, - cached_data + cache_entry.root_item_id, + cache_entry.external_crates, + cache_entry.paths, + cache_entry.format_version, + cache_entry.items, + cache_entry .secondary_indexes .as_ref() .expect("Indexing never fails for toolchain crates") .import_index, - cached_data + cache_entry .secondary_indexes .as_ref() .expect("Indexing never fails for toolchain crates") .import_path2id, - cached_data + cache_entry .secondary_indexes .as_ref() .expect("Indexing never fails for toolchain crates") @@ -399,7 +460,6 @@ impl ToolchainCache { paths BLOB NOT NULL, format_version INTEGER NOT NULL, items BLOB NOT NULL, - item_id2delimiters BLOB NOT NULL, import_index BLOB NOT NULL, import_path2id BLOB NOT NULL, re_exports BLOB NOT NULL, @@ -421,8 +481,12 @@ impl ThirdPartyCrateCache { fn new( connection: &rusqlite::Connection, cache_workspace_packages: bool, + package_graph: &PackageGraph, ) -> Result { Self::setup_table(connection)?; + // Force the creation of the feature graph ahead of our queries. + // It'll be cached internally by the `package_graph`. + let _ = package_graph.feature_graph(); Ok(Self { cache_workspace_packages, }) @@ -465,7 +529,6 @@ impl ThirdPartyCrateCache { paths, format_version, items, - item_id2delimiters, import_index, import_path2id, re_exports, @@ -504,17 +567,11 @@ impl ThirdPartyCrateCache { let external_crates = row.get_ref_unwrap(1).as_bytes()?; let paths = row.get_ref_unwrap(2).as_bytes()?; let format_version = row.get_ref_unwrap(3).as_i64()?; - - let span = tracing::trace_span!("Copy items bytes buffer"); - let guard = span.enter(); - let items: Vec = row.get_unwrap(4); - drop(guard); - - let item_id2delimiters = row.get_ref_unwrap(5).as_bytes()?; - let import_index = row.get_ref_unwrap(6).as_bytes_or_null()?; - let import_path2id = row.get_ref_unwrap(7).as_bytes_or_null()?; - let re_exports = row.get_ref_unwrap(8).as_bytes_or_null()?; - let annotated_items = row.get_ref_unwrap(9).as_bytes_or_null()?; + let items = row.get_ref_unwrap(4).as_bytes()?; + let import_index = row.get_ref_unwrap(5).as_bytes_or_null()?; + let import_path2id = row.get_ref_unwrap(6).as_bytes_or_null()?; + let re_exports = row.get_ref_unwrap(7).as_bytes_or_null()?; + let annotated_items = row.get_ref_unwrap(8).as_bytes_or_null()?; let secondary_indexes = match (import_index, import_path2id, re_exports, annotated_items) { @@ -532,13 +589,12 @@ impl ThirdPartyCrateCache { _ => None, }; - let krate = CachedData { + let krate = CacheEntry { root_item_id, external_crates: Cow::Borrowed(external_crates), paths: Cow::Borrowed(paths), format_version, - items: Cow::Owned(items), - item_id2delimiters: Cow::Borrowed(item_id2delimiters), + items: CachedItems::Borrowed(items), secondary_indexes, } .hydrate(package_metadata.id().to_owned()) @@ -565,14 +621,30 @@ impl ThirdPartyCrateCache { outcome } - /// Store the JSON documentation generated by `rustdoc` in the cache. + /// Compute the cache key for a given package. + fn cache_key<'a>( + &self, + package_metadata: &'a PackageMetadata, + cargo_fingerprint: &'a str, + package_graph: &PackageGraph, + ) -> Option> { + ThirdPartyCrateCacheKey::build( + package_graph, + package_metadata, + cargo_fingerprint, + self.cache_workspace_packages, + ) + } + + /// Convert the JSON documentation generated by `rustdoc` to the format used by our cache, + /// then store it. #[instrument( - name = "Cache third-party crate docs to disk", + name = "Convert and cache docs for a third-party crate to disk", skip_all, level=tracing::Level::DEBUG, fields(crate.id = %package_metadata.id(), cache_key = tracing::field::Empty)) ] - fn insert( + fn convert_and_insert( &self, package_metadata: &PackageMetadata, krate: &crate::rustdoc::Crate, @@ -591,11 +663,29 @@ impl ThirdPartyCrateCache { }; tracing::Span::current().record("cache_key", tracing::field::debug(&cache_key)); let cached_data = if cache_indexes { - CachedData::new(krate) + CacheEntry::new(krate) } else { - CachedData::raw(krate) + CacheEntry::raw(krate) } .context("Failed to serialize docs")?; + self.insert(cache_key, connection, cached_data) + } + + /// Store the JSON documentation generated by `rustdoc` in the cache, + /// without having to perform the conversion towards the caching format. + #[instrument( + name = "Stored cache data for third-party crate docs to disk", + skip_all, + level=tracing::Level::DEBUG, + fields(cache_key = tracing::field::Empty)) + ] + fn insert( + &self, + cache_key: ThirdPartyCrateCacheKey<'_>, + connection: &rusqlite::Connection, + cached_data: CacheEntry<'_>, + ) -> Result<(), anyhow::Error> { + tracing::Span::current().record("cache_key", tracing::field::debug(&cache_key)); let mut stmt = connection.prepare_cached( "INSERT INTO rustdoc_3d_party_crates_cache ( crate_name, @@ -611,12 +701,11 @@ impl ThirdPartyCrateCache { paths, format_version, items, - item_id2delimiters, import_index, import_path2id, re_exports, annotated_items - ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", )?; stmt.execute(params![ cache_key.crate_name, @@ -635,7 +724,6 @@ impl ThirdPartyCrateCache { cached_data.paths, cached_data.format_version, cached_data.items, - cached_data.item_id2delimiters, cached_data .secondary_indexes .as_ref() @@ -672,7 +760,6 @@ impl ThirdPartyCrateCache { paths BLOB NOT NULL, format_version INTEGER NOT NULL, items BLOB NOT NULL, - item_id2delimiters BLOB NOT NULL, annotated_items BLOB, import_index BLOB, import_path2id BLOB, @@ -687,30 +774,58 @@ impl ThirdPartyCrateCache { #[derive(Debug)] /// The serialized form of a crate's documentation, as stored in the cache. -pub(super) struct CachedData<'a> { +pub(in crate::rustdoc) struct CacheEntry<'a> { root_item_id: u32, external_crates: Cow<'a, [u8]>, paths: Cow<'a, [u8]>, format_version: i64, - items: Cow<'a, [u8]>, - item_id2delimiters: Cow<'a, [u8]>, + items: CachedItems<'a>, secondary_indexes: Option>, } #[derive(Debug)] +/// `rkyv`-serialized `HashMap`. +pub(in crate::rustdoc) enum CachedItems<'a> { + Borrowed(&'a [u8]), + Owned(AlignedVec), +} + +impl ToSql for CachedItems<'_> { + fn to_sql(&self) -> rusqlite::Result> { + let s = match self { + CachedItems::Borrowed(items) => items, + CachedItems::Owned(s) => s.as_slice(), + }; + Ok(ToSqlOutput::Borrowed(rusqlite::types::ValueRef::Blob(s))) + } +} + +impl<'a> CachedItems<'a> { + pub fn into_owned(self) -> AlignedVec { + match self { + CachedItems::Borrowed(items) => { + let mut v = AlignedVec::with_capacity(items.len()); + v.extend_from_slice(items); + v + } + CachedItems::Owned(aligned_vec) => aligned_vec, + } + } +} + +#[derive(Debug, Encode, Decode)] /// Data that can be computed starting from the raw JSON documentation for a crate, /// without having to re-invoke `rustdoc`. -pub(super) struct SecondaryIndexes<'a> { +pub(in crate::rustdoc) struct SecondaryIndexes<'a> { import_index: Cow<'a, [u8]>, annotated_items: Option>, import_path2id: Cow<'a, [u8]>, re_exports: Cow<'a, [u8]>, } -impl<'a> CachedData<'a> { - pub(super) fn new(krate: &'a crate::rustdoc::Crate) -> Result, anyhow::Error> { +impl<'a> CacheEntry<'a> { + pub fn new(krate: &'a crate::rustdoc::Crate) -> Result, anyhow::Error> { let mut cached = Self::raw(krate)?; - let import_index = bincode::serde::encode_to_vec(&krate.import_index, BINCODE_CONFIG)?; let annotated_items = bincode::serde::encode_to_vec(&krate.annotated_items, BINCODE_CONFIG)?; @@ -727,7 +842,7 @@ impl<'a> CachedData<'a> { } /// Cache only `rustdoc`'s output, no secondary indexes. - pub(super) fn raw(krate: &'a crate::rustdoc::Crate) -> Result, anyhow::Error> { + pub fn raw(krate: &'a crate::rustdoc::Crate) -> Result, anyhow::Error> { let crate_data = &krate.core.krate; let CrateItemIndex::Eager(index) = &crate_data.index else { anyhow::bail!( @@ -735,28 +850,21 @@ impl<'a> CachedData<'a> { the same crate twice? This is a bug." ); }; - let mut items = Vec::new(); - let mut item_id2delimiters = HashMap::new(); - for (item_id, item) in &index.index { - let start = items.len(); - serde_json::to_writer(&mut items, item)?; - let end = items.len(); - item_id2delimiters.insert(item_id.0, (start, end)); - } + + // Serialize the items HashMap using rkyv for zero-copy deserialization later. + let items = rkyv::to_bytes::(&index.index) + .map_err(|e| anyhow::anyhow!("Failed to serialize items with rkyv: {e}"))?; + let external_crates = bincode::serde::encode_to_vec(&crate_data.external_crates, BINCODE_CONFIG)?; let paths = bincode::serde::encode_to_vec(&crate_data.paths, BINCODE_CONFIG)?; - Ok(CachedData { + Ok(CacheEntry { root_item_id: crate_data.root_item_id.0, external_crates: Cow::Owned(external_crates), paths: Cow::Owned(paths), format_version: crate_data.format_version as i64, - items: Cow::Owned(items), - item_id2delimiters: Cow::Owned(bincode::serde::encode_to_vec( - &item_id2delimiters, - BINCODE_CONFIG, - )?), + items: CachedItems::Owned(items), secondary_indexes: None, }) } @@ -765,35 +873,22 @@ impl<'a> CachedData<'a> { /// /// We hydrate all mappings eagerly, but we avoid re-hydrating the item index eagerly, /// since it can be quite large and deserialization can be slow for large crates. + /// The item index is stored as rkyv-serialized bytes for zero-copy access. pub(super) fn hydrate(self, package_id: PackageId) -> Result { - let span = tracing::trace_span!("Deserialize delimiters"); - let _guard = span.enter(); - let item_id2delimiters = - bincode::serde::decode_from_slice(&self.item_id2delimiters, BINCODE_CONFIG) - .context("Failed to deserialize item_id2delimiters")? - .0; - drop(_guard); - - let span = tracing::trace_span!("Deserialize paths"); - let _guard = span.enter(); - let paths = bincode::serde::decode_from_slice(&self.paths, BINCODE_CONFIG) + let paths = tracing::trace_span!("Deserialize paths") + .in_scope(|| bincode::decode_from_slice(&self.paths, BINCODE_CONFIG)) .context("Failed to deserialize paths")? .0; - drop(_guard); let crate_data = CrateData { root_item_id: rustdoc_types::Id(self.root_item_id.to_owned()), - external_crates: bincode::serde::decode_from_slice( - &self.external_crates, - BINCODE_CONFIG, - ) - .context("Failed to deserialize external_crates")? - .0, + external_crates: bincode::decode_from_slice(&self.external_crates, BINCODE_CONFIG) + .context("Failed to deserialize external_crates")? + .0, paths, format_version: self.format_version.try_into()?, index: CrateItemIndex::Lazy(LazyCrateItemIndex { - items: self.items.into_owned(), - item_id2delimiters, + bytes: self.items.into_owned(), }), }; let Some(secondary_indexes) = self.secondary_indexes else { @@ -805,26 +900,24 @@ impl<'a> CachedData<'a> { krate: crate_data, }; - let span = tracing::trace_span!("Deserialize import_path2id"); - let _guard = span.enter(); - let import_path2id = - bincode::serde::decode_from_slice(&secondary_indexes.import_path2id, BINCODE_CONFIG) - .context("Failed to deserialize import_path2id")? - .0; - drop(_guard); - - let re_exports = - bincode::serde::decode_from_slice(&secondary_indexes.re_exports, BINCODE_CONFIG) - .context("Failed to deserialize re-exports")? - .0; + let import_path2id = tracing::trace_span!("Deserialize import_path2id") + .in_scope(|| { + bincode::decode_from_slice(&secondary_indexes.import_path2id, BINCODE_CONFIG) + }) + .context("Failed to deserialize import_path2id")? + .0; let import_index = - bincode::serde::decode_from_slice(&secondary_indexes.import_index, BINCODE_CONFIG) + bincode::decode_from_slice(&secondary_indexes.import_index, BINCODE_CONFIG) .context("Failed to deserialize import_index")? .0; + let re_exports = bincode::decode_from_slice(&secondary_indexes.re_exports, BINCODE_CONFIG) + .context("Failed to deserialize re-exports")? + .0; + let annotated_items = if let Some(data) = secondary_indexes.annotated_items { - bincode::serde::decode_from_slice(&data, BINCODE_CONFIG) + bincode::decode_from_slice(&data, BINCODE_CONFIG) .context("Failed to deserialize annotated_items")? .0 } else { @@ -837,6 +930,7 @@ impl<'a> CachedData<'a> { import_path2id, external_re_exports: re_exports, import_index, + crate_id2package_id: Default::default(), }; Ok(RustdocCacheEntry::Processed(krate)) } @@ -923,10 +1017,13 @@ impl<'a> ThirdPartyCrateCacheKey<'a> { } else { None }; - let features = package_metadata - .to_feature_set(StandardFeatures::Default) + let feature_graph = package_graph.feature_graph(); + let feature_set = feature_graph + .query_workspace(StandardFeatures::Default) + .resolve(); + let features = feature_set .features_for(package_metadata.id()) - .unwrap(); + .expect("Failed to determine cargo features"); let (default_feature_is_enabled, mut active_named_features) = match features { Some(f) => (f.has_base(), f.named_features().collect()), None => (false, vec![]), @@ -940,7 +1037,7 @@ impl<'a> ThirdPartyCrateCacheKey<'a> { cargo_fingerprint, default_feature_is_enabled, // SQLite doesn't support arrays, so we have to serialize these two collections as strings. - // This is well defined, since the order is well-defined. + // This is well defined, since we sorted features and the order of options is well-defined. rustdoc_options: rustdoc_options().join(" "), active_named_features: active_named_features.join(" "), }; diff --git a/compiler/pavexc/src/rustdoc/compute/mod.rs b/compiler/pavexc/src/rustdoc/compute/mod.rs index edf4ff237..333d4433d 100644 --- a/compiler/pavexc/src/rustdoc/compute/mod.rs +++ b/compiler/pavexc/src/rustdoc/compute/mod.rs @@ -8,6 +8,7 @@ mod format; mod toolchain; use ahash::{HashMap, HashMapExt}; +pub(super) use cache::CacheEntry; pub(crate) use cache::{RustdocCacheKey, RustdocGlobalFsCache}; use anyhow::Context; diff --git a/compiler/pavexc/src/rustdoc/queries.rs b/compiler/pavexc/src/rustdoc/queries.rs index c7599c755..e574c0efa 100644 --- a/compiler/pavexc/src/rustdoc/queries.rs +++ b/compiler/pavexc/src/rustdoc/queries.rs @@ -3,20 +3,27 @@ use std::cmp::Ordering; use std::collections::BTreeSet; use std::sync::Arc; -use ahash::HashMap; +use ahash::{HashMap, HashSet, HashSetExt}; use anyhow::{Context, anyhow}; use elsa::FrozenMap; use guppy::graph::PackageGraph; use guppy::{PackageId, Version}; use indexmap::IndexSet; +use rayon::iter::IntoParallelRefIterator; +use rkyv::collections::swiss_table::ArchivedHashMap; +use rkyv::rancor::Panic; +use rkyv::util::AlignedVec; use rustc_hash::FxHashMap; -use rustdoc_types::{ExternalCrate, Item, ItemEnum, ItemKind, ItemSummary, Visibility}; +use rustdoc_types::{ + ArchivedId, ArchivedItem, ExternalCrate, Item, ItemEnum, ItemKind, ItemSummary, Visibility, +}; use tracing::Span; use tracing_log_error::log_error; use crate::compiler::resolvers::{GenericBindings, resolve_type}; use crate::diagnostic::DiagnosticSink; use crate::language::{FQGenericArgument, FQPathType, UnknownCrate, krate2package_id}; +use crate::rustdoc::compute::CacheEntry; use crate::rustdoc::version_matcher::VersionMatcher; use crate::rustdoc::{ALLOC_PACKAGE_ID, CORE_PACKAGE_ID, STD_PACKAGE_ID}; use crate::rustdoc::{CannotGetCrateData, TOOLCHAIN_CRATES, utils}; @@ -89,7 +96,11 @@ impl CrateCollection { cache_workspace_package_docs: bool, diagnostic_sink: DiagnosticSink, ) -> Result { - let disk_cache = RustdocGlobalFsCache::new(&toolchain_name, cache_workspace_package_docs)?; + let disk_cache = RustdocGlobalFsCache::new( + &toolchain_name, + cache_workspace_package_docs, + &package_graph, + )?; Ok(Self { package_id2krate: FrozenMap::new(), package_graph, @@ -162,8 +173,8 @@ impl CrateCollection { { fn get_if_cached( package_id: PackageId, - package_graph: PackageGraph, - cache: RustdocGlobalFsCache, + package_graph: &PackageGraph, + cache: &RustdocGlobalFsCache, diagnostic_sink: &DiagnosticSink, ) -> (PackageId, Option) { let cache_key = RustdocCacheKey::new(&package_id, &package_graph); @@ -192,14 +203,12 @@ impl CrateCollection { // It can take a while to deserialize the JSON docs for a crate from the cache, // so we parallelize the operation. - let package_graph = self.package_graph.clone(); - let cache = self.disk_cache.clone(); - let sink = self.diagnostic_sink.clone(); + let package_graph = &self.package_graph; + let cache = &self.disk_cache; + let sink = &self.diagnostic_sink; let tracing_span = Span::current(); - let map_op = move |id| { - tracing_span - .in_scope(|| get_if_cached(id, package_graph.clone(), cache.clone(), &sink.clone())) - }; + let map_op = + move |id| tracing_span.in_scope(|| get_if_cached(id, &package_graph, cache, &sink)); let mut to_be_computed = vec![]; @@ -220,17 +229,63 @@ impl CrateCollection { self.package_graph.workspace().root().as_std_path(), )?; - for (package_id, krate) in results { - let n_diagnostics = self.diagnostic_sink.len(); - let krate = Crate::index_raw(krate, package_id.to_owned(), &self.diagnostic_sink); - - // No issues arose in the indexing phase. - // Let's make sure to store them in the on-disk cache for next time. - let cache_indexes = n_diagnostics == self.diagnostic_sink.len(); - let cache_key = RustdocCacheKey::new(&package_id, &self.package_graph); - if let Err(e) = - self.disk_cache - .insert(&cache_key, &krate, cache_indexes, &self.package_graph) + // We then have to perform two more expensive operations: indexing of all the items in each + // crate and conversion of the "raw" JSON format into our optimised cache entry format. + // We perform both in parallel, since they're CPU-intensive. + // + // First indexing: + let package_graph = self.package_graph(); + let diagnostic_sink = &self.diagnostic_sink; + let indexed_krates = results + .into_par_iter() + .map(move |(package_id, krate)| { + let n_diagnostics = diagnostic_sink.len(); + let krate = Crate::index_raw(krate, package_id.to_owned(), diagnostic_sink); + + // No issues arose in the indexing phase. + // Let's make sure to store them in the on-disk cache for next time. + // + // TODO: Since we're indexing in parallel, the counter may have been incremented + // by a different thread, signaling an issue with indexes for another crate. + // It'd be enough to keep a thread-local counter to get an accurate yes/no, + // but since we don't get false negatives it isn't a big deal. + let cache_indexes = n_diagnostics == diagnostic_sink.len(); + (package_id, krate, cache_indexes) + }) + .collect::>(); + // Then conversion to the desired cache format: + let mut cache_entries: HashMap<_, _> = indexed_krates + .par_iter() + .filter_map(|(package_id, krate, cache_indexes)| { + let data = if *cache_indexes { + CacheEntry::new(&krate) + } else { + CacheEntry::raw(&krate) + }; + let cache_key = RustdocCacheKey::new(&package_id, package_graph); + match data { + Ok(v) => Some((package_id, (cache_key, v))), + Err(e) => { + log_error!( + *e, + level: tracing::Level::WARN, + package_id = package_id.repr(), + "Failed to convert the computed JSON docs into the format used by the on-disk cache", + ); + None + } + } + }) + .collect(); + + let mut to_be_inserted = HashSet::with_capacity(indexed_krates.len()); + for (package_id, _, _) in &indexed_krates { + let Some((cache_key, cache_data)) = cache_entries.remove(&package_id) else { + continue; + }; + if let Err(e) = self + .disk_cache + .insert(&cache_key, cache_data, package_graph) { log_error!( *e, @@ -239,11 +294,18 @@ impl CrateCollection { "Failed to store the computed JSON docs in the on-disk cache", ); } - - self.package_id2krate - .insert(package_id.to_owned(), Box::new(krate)); + // If we tried to insert into the in-memory cache directly, we'd get a borrow-checker + // error since `cache_data` borrows from `krate`. + // We keep track of what needs to be inserted and do it later once the on-disk + // cache has been taken care of. + to_be_inserted.insert(package_id.to_owned()); } + for (package_id, krate, _) in indexed_krates { + if to_be_inserted.contains(&package_id) { + self.package_id2krate.insert(package_id, Box::new(krate)); + } + } Ok(()) } @@ -296,10 +358,12 @@ impl CrateCollection { // No issues arose in the indexing phase. // Let's make sure to store them in the on-disk cache for next time. let cache_indexes = n_diagnostics == self.diagnostic_sink.len(); - if let Err(e) = - self.disk_cache - .insert(&cache_key, &krate, cache_indexes, &self.package_graph) - { + if let Err(e) = self.disk_cache.convert_and_insert( + &cache_key, + &krate, + cache_indexes, + &self.package_graph, + ) { log_error!( *e, level: tracing::Level::WARN, @@ -589,9 +653,16 @@ pub struct Crate { /// It can be used to retrieve all publicly visible items as well as computing a "canonical path" /// for each of them. pub(crate) import_index: ImportIndex, + /// An internal cache to avoid traversing the package graph every time we need to + /// translate a crate id into a package id via [`Self::compute_package_id_for_crate_id`] + /// or [`Self::compute_package_id_for_crate_id_with_hint`]. + pub(super) crate_id2package_id: + Arc), PackageId>>>, } -#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)] +#[derive( + Debug, Clone, Default, serde::Serialize, serde::Deserialize, bincode::Encode, bincode::Decode, +)] /// Track re-exports of types (or entire modules!) from other crates. pub struct ExternalReExports { /// Key: the path of the re-exported type in the current crate. @@ -686,7 +757,7 @@ impl ExternalReExports { } } -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, bincode::Encode, bincode::Decode)] /// Information about a type (or module) re-exported from another crate. pub struct ExternalReExport { /// The path of the re-exported type in the crate it was re-exported from. @@ -699,7 +770,9 @@ pub struct ExternalReExport { external_crate_id: u32, } -#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)] +#[derive( + Debug, Clone, Default, serde::Serialize, serde::Deserialize, bincode::Encode, bincode::Decode, +)] pub struct ImportIndex { /// A mapping that keeps track of all modules defined in the current crate. /// @@ -715,7 +788,9 @@ pub struct ImportIndex { } /// An entry in [`ImportIndex`]. -#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)] +#[derive( + Debug, Clone, Default, serde::Serialize, serde::Deserialize, bincode::Encode, bincode::Decode, +)] pub struct ImportIndexEntry { /// All the public paths that can be used to import the item. pub public_paths: BTreeSet, @@ -802,7 +877,16 @@ impl ImportIndexEntry { } } -#[derive(Debug, Clone, Eq, PartialEq, serde::Serialize, serde::Deserialize)] +#[derive( + Debug, + Clone, + Eq, + PartialEq, + serde::Serialize, + serde::Deserialize, + bincode::Encode, + bincode::Decode, +)] #[serde(transparent)] pub struct SortablePath(pub Vec); @@ -872,11 +956,7 @@ impl CrateItemIndex { match self { Self::Eager(index) => index.index.get(id).map(Cow::Borrowed), Self::Lazy(index) => { - let (start, end) = index.item_id2delimiters.get(id)?; - let bytes = index.items[*start..*end].to_vec(); - let item = serde_json::from_slice(&bytes).expect( - "Failed to deserialize an item from a lazy `rustdoc` index. This is a bug.", - ); + let item = index.get_deserialized(id)?; Some(Cow::Owned(item)) } } @@ -890,11 +970,34 @@ pub(crate) struct EagerCrateItemIndex { pub index: FxHashMap, } -#[derive(Debug, Clone)] /// See [`CrateItemIndex`] for more information. +/// +/// Stores rkyv-serialized bytes of a `HashMap` and provides zero-copy access. +#[derive(Debug, Clone)] pub(crate) struct LazyCrateItemIndex { - pub(super) items: Vec, - pub(super) item_id2delimiters: HashMap, + /// The rkyv-serialized bytes containing a `HashMap`. + pub(super) bytes: AlignedVec, +} + +impl LazyCrateItemIndex { + /// Get zero-copy access to the archived HashMap. + #[inline] + fn archived(&self) -> &ArchivedHashMap { + // SAFETY: The bytes were serialized by rkyv from a valid HashMap. + // We trust the cache to contain valid data. + unsafe { rkyv::access_unchecked::>(&self.bytes) } + } + + /// Get an item by its ID, returning a reference to the archived item. + pub fn get(&self, id: &rustdoc_types::Id) -> Option<&ArchivedItem> { + self.archived().get(&ArchivedId(id.0.into())) + } + + /// Deserialize an item by its ID. + pub fn get_deserialized(&self, id: &rustdoc_types::Id) -> Option { + let archived = self.get(id)?; + Some(rkyv::deserialize::(archived).unwrap()) + } } impl CrateCore { @@ -1004,6 +1107,7 @@ impl Crate { import_index, external_re_exports, annotated_items: AnnotatedItems::default(), + crate_id2package_id: Default::default(), }; let annotated_items = annotations::process_queue(annotation_queue, &self_, diagnostics); @@ -1038,8 +1142,7 @@ impl Crate { crate_id: u32, collection: &CrateCollection, ) -> Result { - self.core - .compute_package_id_for_crate_id(crate_id, collection, None) + self.compute_package_id_for_crate_id_with_hint(crate_id, collection, None) } /// Given a crate id, return the corresponding [`PackageId`]. @@ -1063,8 +1166,31 @@ impl Crate { collection: &CrateCollection, maybe_dependent_crate_name: Option<&str>, ) -> Result { - self.core - .compute_package_id_for_crate_id(crate_id, collection, maybe_dependent_crate_name) + // Check the cache first. + if let Some(package_id) = self + .crate_id2package_id + .read() + .unwrap() + .get(&(crate_id, maybe_dependent_crate_name.map(|s| s.to_owned()))) + { + return Ok(package_id.to_owned()); + } + + // If we don't have a cached entry, perform the graph traversal. + let outcome = self.core.compute_package_id_for_crate_id( + crate_id, + collection, + maybe_dependent_crate_name, + ); + + // If successful, cache the outcome. + if let Ok(outcome) = &outcome { + self.crate_id2package_id.write().unwrap().insert( + (crate_id, maybe_dependent_crate_name.map(|s| s.to_owned())), + outcome.to_owned(), + ); + } + outcome } pub fn get_item_id_by_path( diff --git a/compiler/pavexc_attr_parser/Cargo.toml b/compiler/pavexc_attr_parser/Cargo.toml index 655a7ce57..5c28fb63d 100644 --- a/compiler/pavexc_attr_parser/Cargo.toml +++ b/compiler/pavexc_attr_parser/Cargo.toml @@ -18,6 +18,7 @@ itertools = { workspace = true } thiserror = { workspace = true } darling = { workspace = true } px_workspace_hack = { version = "0.1", path = "../../px_workspace_hack" } +bincode = { workspace = true } [dev-dependencies] insta = { workspace = true } diff --git a/compiler/pavexc_attr_parser/src/lib.rs b/compiler/pavexc_attr_parser/src/lib.rs index 0faf8d6b5..dcd05adda 100644 --- a/compiler/pavexc_attr_parser/src/lib.rs +++ b/compiler/pavexc_attr_parser/src/lib.rs @@ -42,7 +42,16 @@ where Ok(component) } -#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +#[derive( + Debug, + Clone, + PartialEq, + Eq, + serde::Serialize, + serde::Deserialize, + bincode::Encode, + bincode::Decode, +)] pub enum AnnotationProperties { Constructor { id: String, diff --git a/compiler/ui_tests/annotations/annotated_constructor_works/generated_app/Cargo.toml b/compiler/ui_tests/annotations/annotated_constructor_works/generated_app/Cargo.toml new file mode 100644 index 000000000..7c54272f2 --- /dev/null +++ b/compiler/ui_tests/annotations/annotated_constructor_works/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_9d63a47c" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_9d63a47c" + +[dependencies] +app_9d63a47c = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/annotations/annotated_constructor_works/generated_app/src/Cargo.toml b/compiler/ui_tests/annotations/annotated_constructor_works/generated_app/src/Cargo.toml new file mode 100644 index 000000000..c34f2bfa5 --- /dev/null +++ b/compiler/ui_tests/annotations/annotated_constructor_works/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_9d63a47c" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_9d63a47c" diff --git a/compiler/ui_tests/annotations/annotated_constructor_works/generated_app/src/lib.rs b/compiler/ui_tests/annotations/annotated_constructor_works/generated_app/src/lib.rs new file mode 100644 index 000000000..cca94dee4 --- /dev/null +++ b/compiler/ui_tests/annotations/annotated_constructor_works/generated_app/src/lib.rs @@ -0,0 +1,196 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState { + pub a: app_9d63a47c::A, +} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + let v0 = app_9d63a47c::a(); + crate::ApplicationState { a: v0 } + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/handler", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => { + route_1::entrypoint(state.a.clone()).await + } + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint(s_0: app_9d63a47c::A) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1(s_0: app_9d63a47c::A) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: app_9d63a47c::A) -> pavex::Response { + let v1 = crate::route_1::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: app_9d63a47c::A) -> pavex::Response { + let v1 = ::clone(&v0); + let v2 = app_9d63a47c::b(v1); + let v3 = app_9d63a47c::c(&v2); + let v4 = match v3 { + Ok(ok) => ok, + Err(v4) => { + return { + let v5 = app_9d63a47c::default_error_handler(&v4); + ::into_response(v5) + }; + } + }; + let v5 = app_9d63a47c::H::with_e(); + let v6 = app_9d63a47c::H::with_a(); + let v7 = ::clone(&v0); + let v8 = app_9d63a47c::G::new(v7); + let v9 = app_9d63a47c::E::new(); + let v10 = app_9d63a47c::F::new(&v9); + let v11 = app_9d63a47c::d(&v4, &v0); + let v12 = app_9d63a47c::handler(&v0, &v2, &v11, &v9, &v10, &v8, &v6, &v5); + ::into_response(v12) + } + struct Next0 + where + T: std::future::Future, + { + s_0: app_9d63a47c::A, + next: fn(app_9d63a47c::A) -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} diff --git a/compiler/ui_tests/annotations/non_existing_dependency/generated_app/Cargo.toml b/compiler/ui_tests/annotations/non_existing_dependency/generated_app/Cargo.toml new file mode 100644 index 000000000..63e747fa0 --- /dev/null +++ b/compiler/ui_tests/annotations/non_existing_dependency/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_3da24ac8" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_3da24ac8" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../workspace_hack" } diff --git a/compiler/ui_tests/annotations/non_existing_dependency/generated_app/src/Cargo.toml b/compiler/ui_tests/annotations/non_existing_dependency/generated_app/src/Cargo.toml new file mode 100644 index 000000000..3889839bc --- /dev/null +++ b/compiler/ui_tests/annotations/non_existing_dependency/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_3da24ac8" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_3da24ac8" diff --git a/compiler/ui_tests/annotations/non_existing_dependency/generated_app/src/lib.rs b/compiler/ui_tests/annotations/non_existing_dependency/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/annotations/non_existing_module/generated_app/Cargo.toml b/compiler/ui_tests/annotations/non_existing_module/generated_app/Cargo.toml new file mode 100644 index 000000000..59e99ba8c --- /dev/null +++ b/compiler/ui_tests/annotations/non_existing_module/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_8055d222" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_8055d222" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../workspace_hack" } diff --git a/compiler/ui_tests/annotations/non_existing_module/generated_app/src/Cargo.toml b/compiler/ui_tests/annotations/non_existing_module/generated_app/src/Cargo.toml new file mode 100644 index 000000000..23fb83825 --- /dev/null +++ b/compiler/ui_tests/annotations/non_existing_module/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_8055d222" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_8055d222" diff --git a/compiler/ui_tests/annotations/non_existing_module/generated_app/src/lib.rs b/compiler/ui_tests/annotations/non_existing_module/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/annotations/trait_methods_are_supported/generated_app/Cargo.toml b/compiler/ui_tests/annotations/trait_methods_are_supported/generated_app/Cargo.toml new file mode 100644 index 000000000..9014569b1 --- /dev/null +++ b/compiler/ui_tests/annotations/trait_methods_are_supported/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_8bb73ba6" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_8bb73ba6" + +[dependencies] +app_8bb73ba6 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/annotations/trait_methods_are_supported/generated_app/src/Cargo.toml b/compiler/ui_tests/annotations/trait_methods_are_supported/generated_app/src/Cargo.toml new file mode 100644 index 000000000..b6d37d8ad --- /dev/null +++ b/compiler/ui_tests/annotations/trait_methods_are_supported/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_8bb73ba6" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_8bb73ba6" diff --git a/compiler/ui_tests/annotations/trait_methods_are_supported/generated_app/src/lib.rs b/compiler/ui_tests/annotations/trait_methods_are_supported/generated_app/src/lib.rs new file mode 100644 index 000000000..545b4d608 --- /dev/null +++ b/compiler/ui_tests/annotations/trait_methods_are_supported/generated_app/src/lib.rs @@ -0,0 +1,186 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = <&str as app_8bb73ba6::LocalTrait>::new(); + let v1 = <[u32] as app_8bb73ba6::LocalTraitWithLifetime<'_>>::new(v0); + let v2 = <&str as app_8bb73ba6::LocalTrait>::new(); + let v3 = <[u8] as app_8bb73ba6::LocalTraitWithLifetime<'_>>::new(v2); + let v4 = as app_8bb73ba6::LocalTrait>::new(); + let v5 = as app_8bb73ba6::LocalTrait>::new(); + let v6 = <&str as app_8bb73ba6::LocalTrait>::new(); + let v7 = as app_8bb73ba6::LocalGenericTrait>>::t(); + let v8 = as core::default::Default>::default(); + let v9 = ::default(); + let v10 = >::t(); + let v11 = app_8bb73ba6::handler(&v10, &v9, &v8, &v7, v6, v5, v4, v3, v1); + ::into_response(v11) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/app_builder/generated_app/Cargo.toml b/compiler/ui_tests/app_builder/generated_app/Cargo.toml new file mode 100644 index 000000000..f51da3da5 --- /dev/null +++ b/compiler/ui_tests/app_builder/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_f10df8fa" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_f10df8fa" + +[dependencies] +app_f10df8fa = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/app_builder/generated_app/src/Cargo.toml b/compiler/ui_tests/app_builder/generated_app/src/Cargo.toml new file mode 100644 index 000000000..8b41dfb4d --- /dev/null +++ b/compiler/ui_tests/app_builder/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_f10df8fa" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_f10df8fa" diff --git a/compiler/ui_tests/app_builder/generated_app/src/lib.rs b/compiler/ui_tests/app_builder/generated_app/src/lib.rs new file mode 100644 index 000000000..89fe429c6 --- /dev/null +++ b/compiler/ui_tests/app_builder/generated_app/src/lib.rs @@ -0,0 +1,207 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState { + pub http_client: app_f10df8fa::HttpClient, +} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + v0: app_f10df8fa::Config, + ) -> Result { + Ok(Self::_new(v0).await) + } + async fn _new(v0: app_f10df8fa::Config) -> crate::ApplicationState { + let v1 = app_f10df8fa::http_client(v0); + crate::ApplicationState { + http_client: v1, + } + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/home", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => { + route_1::entrypoint(state.http_client.clone(), request_head) + .await + } + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint( + s_0: app_f10df8fa::HttpClient, + s_1: pavex::request::RequestHead, + ) -> pavex::Response { + let response = wrapping_0(s_0, s_1).await; + response + } + async fn stage_1( + s_0: pavex::request::RequestHead, + s_1: app_f10df8fa::HttpClient, + ) -> pavex::Response { + let response = handler(s_0, s_1).await; + response + } + async fn wrapping_0( + v0: app_f10df8fa::HttpClient, + v1: pavex::request::RequestHead, + ) -> pavex::Response { + let v2 = crate::route_1::Next0 { + s_0: v1, + s_1: v0, + next: stage_1, + }; + let v3 = pavex::middleware::Next::new(v2); + let v4 = pavex::middleware::wrap_noop(v3).await; + ::into_response(v4) + } + async fn handler( + v0: pavex::request::RequestHead, + v1: app_f10df8fa::HttpClient, + ) -> pavex::Response { + let v2 = app_f10df8fa::extract_path(v0).await; + let v3 = match v2 { + Ok(ok) => ok, + Err(v3) => { + return { + let v4 = app_f10df8fa::logger(); + let v5 = app_f10df8fa::handle_extract_path_error(&v3, v4); + ::into_response(v5) + }; + } + }; + let v4 = app_f10df8fa::logger(); + let v5 = app_f10df8fa::stream_file(v3, v4, v1); + ::into_response(v5) + } + struct Next0 + where + T: std::future::Future, + { + s_0: pavex::request::RequestHead, + s_1: app_f10df8fa::HttpClient, + next: fn(pavex::request::RequestHead, app_f10df8fa::HttpClient) -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0, self.s_1) + } + } +} diff --git a/compiler/ui_tests/blueprint/common/async_callable_are_supported/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/common/async_callable_are_supported/generated_app/Cargo.toml new file mode 100644 index 000000000..7fc5f62bb --- /dev/null +++ b/compiler/ui_tests/blueprint/common/async_callable_are_supported/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_c62eca9e" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_c62eca9e" + +[dependencies] +app_c62eca9e = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/blueprint/common/async_callable_are_supported/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/common/async_callable_are_supported/generated_app/src/Cargo.toml new file mode 100644 index 000000000..763068a06 --- /dev/null +++ b/compiler/ui_tests/blueprint/common/async_callable_are_supported/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_c62eca9e" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_c62eca9e" diff --git a/compiler/ui_tests/blueprint/common/async_callable_are_supported/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/common/async_callable_are_supported/generated_app/src/lib.rs new file mode 100644 index 000000000..8b1e7aeaa --- /dev/null +++ b/compiler/ui_tests/blueprint/common/async_callable_are_supported/generated_app/src/lib.rs @@ -0,0 +1,196 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState { + pub http_client: app_c62eca9e::HttpClient, +} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + v0: app_c62eca9e::Config, + ) -> Result { + Ok(Self::_new(v0).await) + } + async fn _new(v0: app_c62eca9e::Config) -> crate::ApplicationState { + let v1 = app_c62eca9e::http_client(v0).await; + crate::ApplicationState { + http_client: v1, + } + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/home", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => { + route_1::entrypoint(request_head, &state.http_client).await + } + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint<'a>( + s_0: pavex::request::RequestHead, + s_1: &'a app_c62eca9e::HttpClient, + ) -> pavex::Response { + let response = wrapping_0(s_0, s_1).await; + response + } + async fn stage_1<'a>( + s_0: pavex::request::RequestHead, + s_1: &'a app_c62eca9e::HttpClient, + ) -> pavex::Response { + let response = handler(s_0, s_1).await; + response + } + async fn wrapping_0( + v0: pavex::request::RequestHead, + v1: &app_c62eca9e::HttpClient, + ) -> pavex::Response { + let v2 = crate::route_1::Next0 { + s_0: v0, + s_1: v1, + next: stage_1, + }; + let v3 = pavex::middleware::Next::new(v2); + let v4 = pavex::middleware::wrap_noop(v3).await; + ::into_response(v4) + } + async fn handler( + v0: pavex::request::RequestHead, + v1: &app_c62eca9e::HttpClient, + ) -> pavex::Response { + let v2 = app_c62eca9e::logger().await; + let v3 = app_c62eca9e::extract_path(v0).await; + let v4 = app_c62eca9e::stream_file(v3, v2, v1).await; + ::into_response(v4) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: pavex::request::RequestHead, + s_1: &'a app_c62eca9e::HttpClient, + next: fn(pavex::request::RequestHead, &'a app_c62eca9e::HttpClient) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0, self.s_1) + } + } +} diff --git a/compiler/ui_tests/blueprint/common/cannot_return_the_unit_type/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/common/cannot_return_the_unit_type/generated_app/Cargo.toml new file mode 100644 index 000000000..4d037a0ff --- /dev/null +++ b/compiler/ui_tests/blueprint/common/cannot_return_the_unit_type/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_56692d2c" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_56692d2c" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/common/cannot_return_the_unit_type/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/common/cannot_return_the_unit_type/generated_app/src/Cargo.toml new file mode 100644 index 000000000..10be96338 --- /dev/null +++ b/compiler/ui_tests/blueprint/common/cannot_return_the_unit_type/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_56692d2c" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_56692d2c" diff --git a/compiler/ui_tests/blueprint/common/cannot_return_the_unit_type/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/common/cannot_return_the_unit_type/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/common/cannot_take_mutable_references_as_input/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/common/cannot_take_mutable_references_as_input/generated_app/Cargo.toml new file mode 100644 index 000000000..69298c257 --- /dev/null +++ b/compiler/ui_tests/blueprint/common/cannot_take_mutable_references_as_input/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_d24e80c4" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_d24e80c4" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/common/cannot_take_mutable_references_as_input/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/common/cannot_take_mutable_references_as_input/generated_app/src/Cargo.toml new file mode 100644 index 000000000..347b53ffe --- /dev/null +++ b/compiler/ui_tests/blueprint/common/cannot_take_mutable_references_as_input/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_d24e80c4" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_d24e80c4" diff --git a/compiler/ui_tests/blueprint/common/cannot_take_mutable_references_as_input/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/common/cannot_take_mutable_references_as_input/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/common/cloning_if_necessary_requires_clone/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/common/cloning_if_necessary_requires_clone/generated_app/Cargo.toml new file mode 100644 index 000000000..1fac51aa0 --- /dev/null +++ b/compiler/ui_tests/blueprint/common/cloning_if_necessary_requires_clone/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_46ab7f5d" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_46ab7f5d" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/common/cloning_if_necessary_requires_clone/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/common/cloning_if_necessary_requires_clone/generated_app/src/Cargo.toml new file mode 100644 index 000000000..c2e657d92 --- /dev/null +++ b/compiler/ui_tests/blueprint/common/cloning_if_necessary_requires_clone/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_46ab7f5d" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_46ab7f5d" diff --git a/compiler/ui_tests/blueprint/common/cloning_if_necessary_requires_clone/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/common/cloning_if_necessary_requires_clone/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/common/cloning_strategy_is_observed_for_singletons_and_state_inputs/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/common/cloning_strategy_is_observed_for_singletons_and_state_inputs/generated_app/Cargo.toml new file mode 100644 index 000000000..27fb41454 --- /dev/null +++ b/compiler/ui_tests/blueprint/common/cloning_strategy_is_observed_for_singletons_and_state_inputs/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_b02b0728" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_b02b0728" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/common/cloning_strategy_is_observed_for_singletons_and_state_inputs/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/common/cloning_strategy_is_observed_for_singletons_and_state_inputs/generated_app/src/Cargo.toml new file mode 100644 index 000000000..6c56fa6b1 --- /dev/null +++ b/compiler/ui_tests/blueprint/common/cloning_strategy_is_observed_for_singletons_and_state_inputs/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_b02b0728" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_b02b0728" diff --git a/compiler/ui_tests/blueprint/common/cloning_strategy_is_observed_for_singletons_and_state_inputs/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/common/cloning_strategy_is_observed_for_singletons_and_state_inputs/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/common/components_can_fail/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/common/components_can_fail/generated_app/Cargo.toml new file mode 100644 index 000000000..20fa46b65 --- /dev/null +++ b/compiler/ui_tests/blueprint/common/components_can_fail/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_e501823b" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_e501823b" + +[dependencies] +app_e501823b = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/blueprint/common/components_can_fail/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/common/components_can_fail/generated_app/src/Cargo.toml new file mode 100644 index 000000000..7f4f54b31 --- /dev/null +++ b/compiler/ui_tests/blueprint/common/components_can_fail/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_e501823b" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_e501823b" diff --git a/compiler/ui_tests/blueprint/common/components_can_fail/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/common/components_can_fail/generated_app/src/lib.rs new file mode 100644 index 000000000..9212d88c9 --- /dev/null +++ b/compiler/ui_tests/blueprint/common/components_can_fail/generated_app/src/lib.rs @@ -0,0 +1,211 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState { + pub singleton: app_e501823b::Singleton, +} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Self::_new().await + } + async fn _new() -> Result { + let v0 = app_e501823b::singleton(); + let v1 = match v0 { + Ok(ok) => ok, + Err(v1) => { + return { + let v2 = crate::ApplicationStateError::Singleton(v1); + core::result::Result::Err(v2) + }; + } + }; + let v2 = crate::ApplicationState { + singleton: v1, + }; + core::result::Result::Ok(v2) + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError { + #[error(transparent)] + Singleton(app_e501823b::SingletonError), +} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => { + route_1::entrypoint(&state.singleton).await + } + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint<'a>(s_0: &'a app_e501823b::Singleton) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a app_e501823b::Singleton) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &app_e501823b::Singleton) -> pavex::Response { + let v1 = crate::route_1::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &app_e501823b::Singleton) -> pavex::Response { + let v1 = app_e501823b::b(); + let v2 = match v1 { + Ok(ok) => ok, + Err(v2) => { + return { + let v3 = app_e501823b::ErrorB::into_response(&v2); + ::into_response(v3) + }; + } + }; + let v3 = app_e501823b::handler(&v2, v0); + let v4 = match v3 { + Ok(ok) => ok, + Err(v4) => { + return { + let v5 = app_e501823b::CustomError::into_response(&v4); + ::into_response(v5) + }; + } + }; + ::into_response(v4) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a app_e501823b::Singleton, + next: fn(&'a app_e501823b::Singleton) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} diff --git a/compiler/ui_tests/blueprint/common/errors_fallback_on_the_fallback_error_handler/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/common/errors_fallback_on_the_fallback_error_handler/generated_app/Cargo.toml new file mode 100644 index 000000000..802ccb5eb --- /dev/null +++ b/compiler/ui_tests/blueprint/common/errors_fallback_on_the_fallback_error_handler/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_1e65444f" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_1e65444f" + +[dependencies] +app_1e65444f = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/blueprint/common/errors_fallback_on_the_fallback_error_handler/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/common/errors_fallback_on_the_fallback_error_handler/generated_app/src/Cargo.toml new file mode 100644 index 000000000..afcff70e9 --- /dev/null +++ b/compiler/ui_tests/blueprint/common/errors_fallback_on_the_fallback_error_handler/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_1e65444f" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_1e65444f" diff --git a/compiler/ui_tests/blueprint/common/errors_fallback_on_the_fallback_error_handler/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/common/errors_fallback_on_the_fallback_error_handler/generated_app/src/lib.rs new file mode 100644 index 000000000..5f660d357 --- /dev/null +++ b/compiler/ui_tests/blueprint/common/errors_fallback_on_the_fallback_error_handler/generated_app/src/lib.rs @@ -0,0 +1,232 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = 'incoming: { + if let Some(response) = pre_processing_0().await.into_response() { + break 'incoming response; + } + handler(s_0).await + }; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn pre_processing_0() -> pavex::middleware::Processing { + let v0 = app_1e65444f::pre(); + let v1 = match v0 { + Ok(ok) => ok, + Err(v1) => { + return { + let v2 = pavex::Error::new(v1); + let v3 = pavex::Error::to_response(&v2); + let v4 = ::into_response(v3); + pavex::middleware::Processing::EarlyReturn(v4) + }; + } + }; + v1 + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = 'incoming: { + if let Some(response) = pre_processing_0().await.into_response() { + break 'incoming response; + } + handler().await + }; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn pre_processing_0() -> pavex::middleware::Processing { + let v0 = app_1e65444f::pre(); + let v1 = match v0 { + Ok(ok) => ok, + Err(v1) => { + return { + let v2 = pavex::Error::new(v1); + let v3 = pavex::Error::to_response(&v2); + let v4 = ::into_response(v3); + pavex::middleware::Processing::EarlyReturn(v4) + }; + } + }; + v1 + } + async fn handler() -> pavex::Response { + let v0 = app_1e65444f::Dep::new(); + let v1 = match v0 { + Ok(ok) => ok, + Err(v1) => { + return { + let v2 = pavex::Error::new(v1); + let v3 = pavex::Error::to_response(&v2); + ::into_response(v3) + }; + } + }; + let v2 = app_1e65444f::handler(v1); + let v3 = match v2 { + Ok(ok) => ok, + Err(v3) => { + return { + let v4 = pavex::Error::new(v3); + let v5 = pavex::Error::to_response(&v4); + ::into_response(v5) + }; + } + }; + ::into_response(v3) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/blueprint/common/output_type_must_implement_into_response/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/common/output_type_must_implement_into_response/generated_app/Cargo.toml new file mode 100644 index 000000000..d9d5cff8f --- /dev/null +++ b/compiler/ui_tests/blueprint/common/output_type_must_implement_into_response/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_11354b55" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_11354b55" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/common/output_type_must_implement_into_response/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/common/output_type_must_implement_into_response/generated_app/src/Cargo.toml new file mode 100644 index 000000000..7754eafca --- /dev/null +++ b/compiler/ui_tests/blueprint/common/output_type_must_implement_into_response/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_11354b55" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_11354b55" diff --git a/compiler/ui_tests/blueprint/common/output_type_must_implement_into_response/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/common/output_type_must_implement_into_response/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/config/config_blueprint_overrides/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/config/config_blueprint_overrides/generated_app/Cargo.toml new file mode 100644 index 000000000..1bb8e841c --- /dev/null +++ b/compiler/ui_tests/blueprint/config/config_blueprint_overrides/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_dd1270fd" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_dd1270fd" + +[dependencies] +app_dd1270fd = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/blueprint/config/config_blueprint_overrides/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/config/config_blueprint_overrides/generated_app/src/Cargo.toml new file mode 100644 index 000000000..61962cb30 --- /dev/null +++ b/compiler/ui_tests/blueprint/config/config_blueprint_overrides/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_dd1270fd" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_dd1270fd" diff --git a/compiler/ui_tests/blueprint/config/config_blueprint_overrides/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/config/config_blueprint_overrides/generated_app/src/lib.rs new file mode 100644 index 000000000..d41bbc8bb --- /dev/null +++ b/compiler/ui_tests/blueprint/config/config_blueprint_overrides/generated_app/src/lib.rs @@ -0,0 +1,174 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig { + #[serde(default)] + pub a: app_dd1270fd::A, +} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_dd1270fd::handler(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/blueprint/config/config_conflicts/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/config/config_conflicts/generated_app/Cargo.toml new file mode 100644 index 000000000..c82ccc6d2 --- /dev/null +++ b/compiler/ui_tests/blueprint/config/config_conflicts/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_0c484c9e" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_0c484c9e" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/config/config_conflicts/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/config/config_conflicts/generated_app/src/Cargo.toml new file mode 100644 index 000000000..fbec64f95 --- /dev/null +++ b/compiler/ui_tests/blueprint/config/config_conflicts/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_0c484c9e" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_0c484c9e" diff --git a/compiler/ui_tests/blueprint/config/config_conflicts/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/config/config_conflicts/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/config/config_does_not_need_to_be_send_and_sync_if_only_used_at_build_time/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/config/config_does_not_need_to_be_send_and_sync_if_only_used_at_build_time/generated_app/Cargo.toml new file mode 100644 index 000000000..f591cbd20 --- /dev/null +++ b/compiler/ui_tests/blueprint/config/config_does_not_need_to_be_send_and_sync_if_only_used_at_build_time/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_4587d126" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_4587d126" + +[dependencies] +app_4587d126 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/blueprint/config/config_does_not_need_to_be_send_and_sync_if_only_used_at_build_time/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/config/config_does_not_need_to_be_send_and_sync_if_only_used_at_build_time/generated_app/src/Cargo.toml new file mode 100644 index 000000000..c0d436ae4 --- /dev/null +++ b/compiler/ui_tests/blueprint/config/config_does_not_need_to_be_send_and_sync_if_only_used_at_build_time/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_4587d126" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_4587d126" diff --git a/compiler/ui_tests/blueprint/config/config_does_not_need_to_be_send_and_sync_if_only_used_at_build_time/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/config/config_does_not_need_to_be_send_and_sync_if_only_used_at_build_time/generated_app/src/lib.rs new file mode 100644 index 000000000..05915ffe4 --- /dev/null +++ b/compiler/ui_tests/blueprint/config/config_does_not_need_to_be_send_and_sync_if_only_used_at_build_time/generated_app/src/lib.rs @@ -0,0 +1,177 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig { + pub a: app_4587d126::A, +} +pub struct ApplicationState { + pub b: app_4587d126::B, +} +impl ApplicationState { + pub async fn new( + app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new(&app_config.a).await) + } + async fn _new(v0: &app_4587d126::A) -> crate::ApplicationState { + let v1 = app_4587d126::b(v0); + crate::ApplicationState { b: v1 } + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint(&state.b).await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint<'a>(s_0: &'a app_4587d126::B) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a app_4587d126::B) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &app_4587d126::B) -> pavex::Response { + let v1 = crate::route_1::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &app_4587d126::B) -> pavex::Response { + let v1 = app_4587d126::handler(v0); + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a app_4587d126::B, + next: fn(&'a app_4587d126::B) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} diff --git a/compiler/ui_tests/blueprint/config/config_must_be_clone/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/config/config_must_be_clone/generated_app/Cargo.toml new file mode 100644 index 000000000..a5f7df354 --- /dev/null +++ b/compiler/ui_tests/blueprint/config/config_must_be_clone/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_b4cae0d5" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_b4cae0d5" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/config/config_must_be_clone/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/config/config_must_be_clone/generated_app/src/Cargo.toml new file mode 100644 index 000000000..7cba19d6f --- /dev/null +++ b/compiler/ui_tests/blueprint/config/config_must_be_clone/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_b4cae0d5" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_b4cae0d5" diff --git a/compiler/ui_tests/blueprint/config/config_must_be_clone/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/config/config_must_be_clone/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/config/config_works/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/config/config_works/generated_app/Cargo.toml new file mode 100644 index 000000000..1a395368c --- /dev/null +++ b/compiler/ui_tests/blueprint/config/config_works/generated_app/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "application_b5d21f5b" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_b5d21f5b" + +[dependencies] +app_b5d21f5b = { version = "0.1", path = "..", default-features = false } +dep_29415e2f = { version = "0.1", path = "../ephemeral_deps/dep", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/blueprint/config/config_works/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/config/config_works/generated_app/src/Cargo.toml new file mode 100644 index 000000000..4b7114988 --- /dev/null +++ b/compiler/ui_tests/blueprint/config/config_works/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_b5d21f5b" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_b5d21f5b" diff --git a/compiler/ui_tests/blueprint/config/config_works/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/config/config_works/generated_app/src/lib.rs new file mode 100644 index 000000000..af04e3c6d --- /dev/null +++ b/compiler/ui_tests/blueprint/config/config_works/generated_app/src/lib.rs @@ -0,0 +1,267 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig { + pub a: app_b5d21f5b::A, + #[serde(default)] + pub b: app_b5d21f5b::B, + pub c: app_b5d21f5b::C, + pub e: app_b5d21f5b::E, + pub f: dep_29415e2f::F, + pub g: dep_29415e2f::Z, +} +pub struct ApplicationState { + pub a: app_b5d21f5b::A, + pub b: app_b5d21f5b::B, + pub c: app_b5d21f5b::C, + pub e: app_b5d21f5b::E, + pub f: dep_29415e2f::F, + pub z: dep_29415e2f::Z, +} +impl ApplicationState { + pub async fn new( + app_config: crate::ApplicationConfig, + ) -> Result { + Ok( + Self::_new( + app_config.g, + app_config.f, + app_config.e, + app_config.c, + app_config.b, + app_config.a, + ) + .await, + ) + } + async fn _new( + v0: dep_29415e2f::Z, + v1: dep_29415e2f::F, + v2: app_b5d21f5b::E, + v3: app_b5d21f5b::C, + v4: app_b5d21f5b::B, + v5: app_b5d21f5b::A, + ) -> crate::ApplicationState { + crate::ApplicationState { + a: v5, + b: v4, + c: v3, + e: v2, + f: v1, + z: v0, + } + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => { + route_1::entrypoint( + &state.a, + &state.b, + &state.c, + &state.e, + &state.f, + &state.z, + ) + .await + } + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint<'a, 'b, 'c, 'd, 'e, 'f>( + s_0: &'a app_b5d21f5b::A, + s_1: &'b app_b5d21f5b::B, + s_2: &'c app_b5d21f5b::C, + s_3: &'d app_b5d21f5b::E, + s_4: &'e dep_29415e2f::F, + s_5: &'f dep_29415e2f::Z, + ) -> pavex::Response { + let response = wrapping_0(s_0, s_1, s_2, s_3, s_4, s_5).await; + response + } + async fn stage_1<'a, 'b, 'c, 'd, 'e, 'f>( + s_0: &'a app_b5d21f5b::A, + s_1: &'b app_b5d21f5b::B, + s_2: &'c app_b5d21f5b::C, + s_3: &'d app_b5d21f5b::E, + s_4: &'e dep_29415e2f::F, + s_5: &'f dep_29415e2f::Z, + ) -> pavex::Response { + let response = handler(s_0, s_1, s_2, s_3, s_4, s_5).await; + response + } + async fn wrapping_0( + v0: &app_b5d21f5b::A, + v1: &app_b5d21f5b::B, + v2: &app_b5d21f5b::C, + v3: &app_b5d21f5b::E, + v4: &dep_29415e2f::F, + v5: &dep_29415e2f::Z, + ) -> pavex::Response { + let v6 = crate::route_1::Next0 { + s_0: v0, + s_1: v1, + s_2: v2, + s_3: v3, + s_4: v4, + s_5: v5, + next: stage_1, + }; + let v7 = pavex::middleware::Next::new(v6); + let v8 = pavex::middleware::wrap_noop(v7).await; + ::into_response(v8) + } + async fn handler( + v0: &app_b5d21f5b::A, + v1: &app_b5d21f5b::B, + v2: &app_b5d21f5b::C, + v3: &app_b5d21f5b::E, + v4: &dep_29415e2f::F, + v5: &dep_29415e2f::Z, + ) -> pavex::Response { + let v6 = app_b5d21f5b::handler(v0, v1, v2, v3, v4, v5); + ::into_response(v6) + } + struct Next0<'a, 'b, 'c, 'd, 'e, 'f, T> + where + T: std::future::Future, + { + s_0: &'a app_b5d21f5b::A, + s_1: &'b app_b5d21f5b::B, + s_2: &'c app_b5d21f5b::C, + s_3: &'d app_b5d21f5b::E, + s_4: &'e dep_29415e2f::F, + s_5: &'f dep_29415e2f::Z, + next: fn( + &'a app_b5d21f5b::A, + &'b app_b5d21f5b::B, + &'c app_b5d21f5b::C, + &'d app_b5d21f5b::E, + &'e dep_29415e2f::F, + &'f dep_29415e2f::Z, + ) -> T, + } + impl<'a, 'b, 'c, 'd, 'e, 'f, T> std::future::IntoFuture + for Next0<'a, 'b, 'c, 'd, 'e, 'f, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0, self.s_1, self.s_2, self.s_3, self.s_4, self.s_5) + } + } +} diff --git a/compiler/ui_tests/blueprint/config/invalid_config_attribute/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/config/invalid_config_attribute/generated_app/Cargo.toml new file mode 100644 index 000000000..2c512dbc4 --- /dev/null +++ b/compiler/ui_tests/blueprint/config/invalid_config_attribute/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_6a904879" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_6a904879" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/config/invalid_config_attribute/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/config/invalid_config_attribute/generated_app/src/Cargo.toml new file mode 100644 index 000000000..92d8e5c33 --- /dev/null +++ b/compiler/ui_tests/blueprint/config/invalid_config_attribute/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_6a904879" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_6a904879" diff --git a/compiler/ui_tests/blueprint/config/invalid_config_attribute/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/config/invalid_config_attribute/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/config/invalid_config_keys/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/config/invalid_config_keys/generated_app/Cargo.toml new file mode 100644 index 000000000..347d695b5 --- /dev/null +++ b/compiler/ui_tests/blueprint/config/invalid_config_keys/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_a0acb8a7" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_a0acb8a7" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/config/invalid_config_keys/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/config/invalid_config_keys/generated_app/src/Cargo.toml new file mode 100644 index 000000000..e72a53b6b --- /dev/null +++ b/compiler/ui_tests/blueprint/config/invalid_config_keys/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_a0acb8a7" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_a0acb8a7" diff --git a/compiler/ui_tests/blueprint/config/invalid_config_keys/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/config/invalid_config_keys/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/config/unused_config/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/config/unused_config/generated_app/Cargo.toml new file mode 100644 index 000000000..b5f5d5761 --- /dev/null +++ b/compiler/ui_tests/blueprint/config/unused_config/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_d96899ec" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_d96899ec" + +[dependencies] +app_d96899ec = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/blueprint/config/unused_config/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/config/unused_config/generated_app/src/Cargo.toml new file mode 100644 index 000000000..942924b6a --- /dev/null +++ b/compiler/ui_tests/blueprint/config/unused_config/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_d96899ec" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_d96899ec" diff --git a/compiler/ui_tests/blueprint/config/unused_config/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/config/unused_config/generated_app/src/lib.rs new file mode 100644 index 000000000..ba0acf164 --- /dev/null +++ b/compiler/ui_tests/blueprint/config/unused_config/generated_app/src/lib.rs @@ -0,0 +1,173 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig { + pub b: app_d96899ec::B, +} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_d96899ec::handler(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/blueprint/constructors/a_warning_is_emitted_for_unused_constructors/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/constructors/a_warning_is_emitted_for_unused_constructors/generated_app/Cargo.toml new file mode 100644 index 000000000..8948da8ab --- /dev/null +++ b/compiler/ui_tests/blueprint/constructors/a_warning_is_emitted_for_unused_constructors/generated_app/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "application_30248169" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_30248169" + +[dependencies] +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/blueprint/constructors/a_warning_is_emitted_for_unused_constructors/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/constructors/a_warning_is_emitted_for_unused_constructors/generated_app/src/Cargo.toml new file mode 100644 index 000000000..156f3dbe6 --- /dev/null +++ b/compiler/ui_tests/blueprint/constructors/a_warning_is_emitted_for_unused_constructors/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_30248169" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_30248169" diff --git a/compiler/ui_tests/blueprint/constructors/a_warning_is_emitted_for_unused_constructors/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/constructors/a_warning_is_emitted_for_unused_constructors/generated_app/src/lib.rs new file mode 100644 index 000000000..37117e8fc --- /dev/null +++ b/compiler/ui_tests/blueprint/constructors/a_warning_is_emitted_for_unused_constructors/generated_app/src/lib.rs @@ -0,0 +1,120 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let router = matchit::Router::new(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} diff --git a/compiler/ui_tests/blueprint/constructors/constructors_input_parameters_cannot_be_generic/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/constructors/constructors_input_parameters_cannot_be_generic/generated_app/Cargo.toml new file mode 100644 index 000000000..5766a7dcc --- /dev/null +++ b/compiler/ui_tests/blueprint/constructors/constructors_input_parameters_cannot_be_generic/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_ebc534c7" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_ebc534c7" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/constructors/constructors_input_parameters_cannot_be_generic/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/constructors/constructors_input_parameters_cannot_be_generic/generated_app/src/Cargo.toml new file mode 100644 index 000000000..d6df216f3 --- /dev/null +++ b/compiler/ui_tests/blueprint/constructors/constructors_input_parameters_cannot_be_generic/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_ebc534c7" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_ebc534c7" diff --git a/compiler/ui_tests/blueprint/constructors/constructors_input_parameters_cannot_be_generic/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/constructors/constructors_input_parameters_cannot_be_generic/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/constructors/output_type_of_constructors_can_contain_generic_parameters/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/constructors/output_type_of_constructors_can_contain_generic_parameters/generated_app/Cargo.toml new file mode 100644 index 000000000..985467d73 --- /dev/null +++ b/compiler/ui_tests/blueprint/constructors/output_type_of_constructors_can_contain_generic_parameters/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_ea979460" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_ea979460" + +[dependencies] +app_ea979460 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/blueprint/constructors/output_type_of_constructors_can_contain_generic_parameters/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/constructors/output_type_of_constructors_can_contain_generic_parameters/generated_app/src/Cargo.toml new file mode 100644 index 000000000..d4f9079ca --- /dev/null +++ b/compiler/ui_tests/blueprint/constructors/output_type_of_constructors_can_contain_generic_parameters/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_ea979460" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_ea979460" diff --git a/compiler/ui_tests/blueprint/constructors/output_type_of_constructors_can_contain_generic_parameters/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/constructors/output_type_of_constructors_can_contain_generic_parameters/generated_app/src/lib.rs new file mode 100644 index 000000000..b8e309ff0 --- /dev/null +++ b/compiler/ui_tests/blueprint/constructors/output_type_of_constructors_can_contain_generic_parameters/generated_app/src/lib.rs @@ -0,0 +1,215 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/home", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_ea979460::fallible(); + let v1 = match v0 { + Ok(ok) => ok, + Err(v1) => { + return { + let v2 = app_ea979460::error_handler(&v1); + ::into_response(v2) + }; + } + }; + let v2 = app_ea979460::fallible_with_generic_error(); + let v3 = match v2 { + Ok(ok) => ok, + Err(v3) => { + return { + let v4 = app_ea979460::generic_error_handler(&v3); + ::into_response(v4) + }; + } + }; + let v4 = app_ea979460::fallible_with_generic_error(); + let v5 = match v4 { + Ok(ok) => ok, + Err(v5) => { + return { + let v6 = app_ea979460::generic_error_handler(&v5); + ::into_response(v6) + }; + } + }; + let v6 = app_ea979460::fallible_with_generic_error2(); + let v7 = match v6 { + Ok(ok) => ok, + Err(v7) => { + return { + let v8 = app_ea979460::json(); + let v9 = app_ea979460::doubly_generic_error_handler(&v7, &v8); + ::into_response(v9) + }; + } + }; + let v8 = app_ea979460::json(); + let v9 = app_ea979460::json(); + let v10 = app_ea979460::json(); + let v11 = app_ea979460::handler(v8, v10, &v9, v1, v3, &v5, &v7); + ::into_response(v11) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/blueprint/constructors/output_type_of_constructors_cannot_be_a_naked_generic/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/constructors/output_type_of_constructors_cannot_be_a_naked_generic/generated_app/Cargo.toml new file mode 100644 index 000000000..8a276abd4 --- /dev/null +++ b/compiler/ui_tests/blueprint/constructors/output_type_of_constructors_cannot_be_a_naked_generic/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_6c44cec0" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_6c44cec0" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/constructors/output_type_of_constructors_cannot_be_a_naked_generic/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/constructors/output_type_of_constructors_cannot_be_a_naked_generic/generated_app/src/Cargo.toml new file mode 100644 index 000000000..078fe650d --- /dev/null +++ b/compiler/ui_tests/blueprint/constructors/output_type_of_constructors_cannot_be_a_naked_generic/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_6c44cec0" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_6c44cec0" diff --git a/compiler/ui_tests/blueprint/constructors/output_type_of_constructors_cannot_be_a_naked_generic/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/constructors/output_type_of_constructors_cannot_be_a_naked_generic/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/constructors/singleton_naming/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/constructors/singleton_naming/generated_app/Cargo.toml new file mode 100644 index 000000000..6dbbc61ab --- /dev/null +++ b/compiler/ui_tests/blueprint/constructors/singleton_naming/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_255f0769" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_255f0769" + +[dependencies] +app_255f0769 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/blueprint/constructors/singleton_naming/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/constructors/singleton_naming/generated_app/src/Cargo.toml new file mode 100644 index 000000000..48ba6207f --- /dev/null +++ b/compiler/ui_tests/blueprint/constructors/singleton_naming/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_255f0769" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_255f0769" diff --git a/compiler/ui_tests/blueprint/constructors/singleton_naming/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/constructors/singleton_naming/generated_app/src/lib.rs new file mode 100644 index 000000000..b4780384d --- /dev/null +++ b/compiler/ui_tests/blueprint/constructors/singleton_naming/generated_app/src/lib.rs @@ -0,0 +1,236 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState { + pub app_255_f_0769_a_singleton: app_255f0769::a::Singleton, + pub app_255_f_0769_singleton: app_255f0769::Singleton, + pub generic_string: app_255f0769::Generic, + pub generic_u64_: app_255f0769::Generic, + pub type_: app_255f0769::Type, +} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + let v0 = app_255f0769::Type::new(); + let v1 = app_255f0769::Generic::new(); + let v2 = app_255f0769::Generic::new(); + let v3 = app_255f0769::Singleton::new(); + let v4 = app_255f0769::a::Singleton::new(); + crate::ApplicationState { + app_255_f_0769_a_singleton: v4, + app_255_f_0769_singleton: v3, + generic_string: v2, + generic_u64_: v1, + type_: v0, + } + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => { + route_1::entrypoint( + &state.type_, + &state.generic_string, + &state.generic_u64_, + &state.app_255_f_0769_singleton, + &state.app_255_f_0769_a_singleton, + ) + .await + } + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint<'a, 'b, 'c, 'd, 'e>( + s_0: &'a app_255f0769::Type, + s_1: &'b app_255f0769::Generic, + s_2: &'c app_255f0769::Generic, + s_3: &'d app_255f0769::Singleton, + s_4: &'e app_255f0769::a::Singleton, + ) -> pavex::Response { + let response = wrapping_0(s_0, s_1, s_2, s_3, s_4).await; + response + } + async fn stage_1<'a, 'b, 'c, 'd, 'e>( + s_0: &'a app_255f0769::Type, + s_1: &'b app_255f0769::Generic, + s_2: &'c app_255f0769::Generic, + s_3: &'d app_255f0769::Singleton, + s_4: &'e app_255f0769::a::Singleton, + ) -> pavex::Response { + let response = handler(s_0, s_1, s_2, s_3, s_4).await; + response + } + async fn wrapping_0( + v0: &app_255f0769::Type, + v1: &app_255f0769::Generic, + v2: &app_255f0769::Generic, + v3: &app_255f0769::Singleton, + v4: &app_255f0769::a::Singleton, + ) -> pavex::Response { + let v5 = crate::route_1::Next0 { + s_0: v0, + s_1: v1, + s_2: v2, + s_3: v3, + s_4: v4, + next: stage_1, + }; + let v6 = pavex::middleware::Next::new(v5); + let v7 = pavex::middleware::wrap_noop(v6).await; + ::into_response(v7) + } + async fn handler( + v0: &app_255f0769::Type, + v1: &app_255f0769::Generic, + v2: &app_255f0769::Generic, + v3: &app_255f0769::Singleton, + v4: &app_255f0769::a::Singleton, + ) -> pavex::Response { + let v5 = app_255f0769::handler(v0, v1, v2, v3, v4); + ::into_response(v5) + } + struct Next0<'a, 'b, 'c, 'd, 'e, T> + where + T: std::future::Future, + { + s_0: &'a app_255f0769::Type, + s_1: &'b app_255f0769::Generic, + s_2: &'c app_255f0769::Generic, + s_3: &'d app_255f0769::Singleton, + s_4: &'e app_255f0769::a::Singleton, + next: fn( + &'a app_255f0769::Type, + &'b app_255f0769::Generic, + &'c app_255f0769::Generic, + &'d app_255f0769::Singleton, + &'e app_255f0769::a::Singleton, + ) -> T, + } + impl<'a, 'b, 'c, 'd, 'e, T> std::future::IntoFuture for Next0<'a, 'b, 'c, 'd, 'e, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0, self.s_1, self.s_2, self.s_3, self.s_4) + } + } +} diff --git a/compiler/ui_tests/blueprint/constructors/static_references_are_valid_singletons/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/constructors/static_references_are_valid_singletons/generated_app/Cargo.toml new file mode 100644 index 000000000..738c18611 --- /dev/null +++ b/compiler/ui_tests/blueprint/constructors/static_references_are_valid_singletons/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_d0f81bc0" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_d0f81bc0" + +[dependencies] +app_d0f81bc0 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/blueprint/constructors/static_references_are_valid_singletons/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/constructors/static_references_are_valid_singletons/generated_app/src/Cargo.toml new file mode 100644 index 000000000..f4a94a957 --- /dev/null +++ b/compiler/ui_tests/blueprint/constructors/static_references_are_valid_singletons/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_d0f81bc0" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_d0f81bc0" diff --git a/compiler/ui_tests/blueprint/constructors/static_references_are_valid_singletons/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/constructors/static_references_are_valid_singletons/generated_app/src/lib.rs new file mode 100644 index 000000000..36565f4cc --- /dev/null +++ b/compiler/ui_tests/blueprint/constructors/static_references_are_valid_singletons/generated_app/src/lib.rs @@ -0,0 +1,184 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState { + pub str_: &'static str, + pub u8_: &'static u8, +} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + let v0 = app_d0f81bc0::static_u8(); + let v1 = app_d0f81bc0::static_str(); + crate::ApplicationState { + str_: v1, + u8_: v0, + } + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => { + route_1::entrypoint(state.str_, state.u8_).await + } + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint(s_0: &'static str, s_1: &'static u8) -> pavex::Response { + let response = wrapping_0(s_0, s_1).await; + response + } + async fn stage_1(s_0: &'static u8, s_1: &'static str) -> pavex::Response { + let response = handler(s_0, s_1).await; + response + } + async fn wrapping_0(v0: &'static str, v1: &'static u8) -> pavex::Response { + let v2 = crate::route_1::Next0 { + s_0: v1, + s_1: v0, + next: stage_1, + }; + let v3 = pavex::middleware::Next::new(v2); + let v4 = pavex::middleware::wrap_noop(v3).await; + ::into_response(v4) + } + async fn handler(v0: &'static u8, v1: &'static str) -> pavex::Response { + let v2 = app_d0f81bc0::handler(v1, v0); + ::into_response(v2) + } + struct Next0 + where + T: std::future::Future, + { + s_0: &'static u8, + s_1: &'static str, + next: fn(&'static u8, &'static str) -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0, self.s_1) + } + } +} diff --git a/compiler/ui_tests/blueprint/constructors/the_latest_registered_constructor_takes_precedence/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/constructors/the_latest_registered_constructor_takes_precedence/generated_app/Cargo.toml new file mode 100644 index 000000000..06deb4214 --- /dev/null +++ b/compiler/ui_tests/blueprint/constructors/the_latest_registered_constructor_takes_precedence/generated_app/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "application_55dca802" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_55dca802" + +[dependencies] +app_55dca802 = { version = "0.1", path = "..", default-features = false } +dep_55dca802 = { version = "0.1", path = "../ephemeral_deps/dep", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/blueprint/constructors/the_latest_registered_constructor_takes_precedence/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/constructors/the_latest_registered_constructor_takes_precedence/generated_app/src/Cargo.toml new file mode 100644 index 000000000..a7e5c5828 --- /dev/null +++ b/compiler/ui_tests/blueprint/constructors/the_latest_registered_constructor_takes_precedence/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_55dca802" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_55dca802" diff --git a/compiler/ui_tests/blueprint/constructors/the_latest_registered_constructor_takes_precedence/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/constructors/the_latest_registered_constructor_takes_precedence/generated_app/src/lib.rs new file mode 100644 index 000000000..8ec4c9b14 --- /dev/null +++ b/compiler/ui_tests/blueprint/constructors/the_latest_registered_constructor_takes_precedence/generated_app/src/lib.rs @@ -0,0 +1,172 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/home", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_55dca802::alternative_logger(); + let v1 = app_55dca802::Streamer::stream_file(v0); + ::into_response(v1) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/blueprint/constructors/the_same_constructor_can_be_registered_multiple_times_using_the_same_lifecycle/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/constructors/the_same_constructor_can_be_registered_multiple_times_using_the_same_lifecycle/generated_app/Cargo.toml new file mode 100644 index 000000000..27a8e3a16 --- /dev/null +++ b/compiler/ui_tests/blueprint/constructors/the_same_constructor_can_be_registered_multiple_times_using_the_same_lifecycle/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_621e9d53" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_621e9d53" + +[dependencies] +app_621e9d53 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/blueprint/constructors/the_same_constructor_can_be_registered_multiple_times_using_the_same_lifecycle/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/constructors/the_same_constructor_can_be_registered_multiple_times_using_the_same_lifecycle/generated_app/src/Cargo.toml new file mode 100644 index 000000000..851756087 --- /dev/null +++ b/compiler/ui_tests/blueprint/constructors/the_same_constructor_can_be_registered_multiple_times_using_the_same_lifecycle/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_621e9d53" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_621e9d53" diff --git a/compiler/ui_tests/blueprint/constructors/the_same_constructor_can_be_registered_multiple_times_using_the_same_lifecycle/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/constructors/the_same_constructor_can_be_registered_multiple_times_using_the_same_lifecycle/generated_app/src/lib.rs new file mode 100644 index 000000000..0fda3f55f --- /dev/null +++ b/compiler/ui_tests/blueprint/constructors/the_same_constructor_can_be_registered_multiple_times_using_the_same_lifecycle/generated_app/src/lib.rs @@ -0,0 +1,172 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/home", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_621e9d53::new_logger(); + let v1 = app_621e9d53::Streamer::stream_file(v0); + ::into_response(v1) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/blueprint/constructors/trait_constraints_on_runtime_singletons/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/constructors/trait_constraints_on_runtime_singletons/generated_app/Cargo.toml new file mode 100644 index 000000000..dc5c685ad --- /dev/null +++ b/compiler/ui_tests/blueprint/constructors/trait_constraints_on_runtime_singletons/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_c5885cdb" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_c5885cdb" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/constructors/trait_constraints_on_runtime_singletons/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/constructors/trait_constraints_on_runtime_singletons/generated_app/src/Cargo.toml new file mode 100644 index 000000000..99dcba434 --- /dev/null +++ b/compiler/ui_tests/blueprint/constructors/trait_constraints_on_runtime_singletons/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_c5885cdb" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_c5885cdb" diff --git a/compiler/ui_tests/blueprint/constructors/trait_constraints_on_runtime_singletons/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/constructors/trait_constraints_on_runtime_singletons/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/constructors/unused_constructor_warning_can_be_ignored/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/constructors/unused_constructor_warning_can_be_ignored/generated_app/Cargo.toml new file mode 100644 index 000000000..331c8fe1c --- /dev/null +++ b/compiler/ui_tests/blueprint/constructors/unused_constructor_warning_can_be_ignored/generated_app/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "application_46e3d1f1" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_46e3d1f1" + +[dependencies] +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/blueprint/constructors/unused_constructor_warning_can_be_ignored/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/constructors/unused_constructor_warning_can_be_ignored/generated_app/src/Cargo.toml new file mode 100644 index 000000000..8faedafc7 --- /dev/null +++ b/compiler/ui_tests/blueprint/constructors/unused_constructor_warning_can_be_ignored/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_46e3d1f1" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_46e3d1f1" diff --git a/compiler/ui_tests/blueprint/constructors/unused_constructor_warning_can_be_ignored/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/constructors/unused_constructor_warning_can_be_ignored/generated_app/src/lib.rs new file mode 100644 index 000000000..37117e8fc --- /dev/null +++ b/compiler/ui_tests/blueprint/constructors/unused_constructor_warning_can_be_ignored/generated_app/src/lib.rs @@ -0,0 +1,120 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let router = matchit::Router::new(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} diff --git a/compiler/ui_tests/blueprint/error_handlers/cannot_register_an_error_handler_for_a_sync_infallible_constructor/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/error_handlers/cannot_register_an_error_handler_for_a_sync_infallible_constructor/generated_app/Cargo.toml new file mode 100644 index 000000000..73431eaef --- /dev/null +++ b/compiler/ui_tests/blueprint/error_handlers/cannot_register_an_error_handler_for_a_sync_infallible_constructor/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_8e8ba674" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_8e8ba674" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/error_handlers/cannot_register_an_error_handler_for_a_sync_infallible_constructor/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/error_handlers/cannot_register_an_error_handler_for_a_sync_infallible_constructor/generated_app/src/Cargo.toml new file mode 100644 index 000000000..93ab93051 --- /dev/null +++ b/compiler/ui_tests/blueprint/error_handlers/cannot_register_an_error_handler_for_a_sync_infallible_constructor/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_8e8ba674" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_8e8ba674" diff --git a/compiler/ui_tests/blueprint/error_handlers/cannot_register_an_error_handler_for_a_sync_infallible_constructor/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/error_handlers/cannot_register_an_error_handler_for_a_sync_infallible_constructor/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/error_handlers/cannot_register_an_error_handler_for_an_async_infallible_constructor/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/error_handlers/cannot_register_an_error_handler_for_an_async_infallible_constructor/generated_app/Cargo.toml new file mode 100644 index 000000000..e465a0079 --- /dev/null +++ b/compiler/ui_tests/blueprint/error_handlers/cannot_register_an_error_handler_for_an_async_infallible_constructor/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_c3c254cf" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_c3c254cf" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/error_handlers/cannot_register_an_error_handler_for_an_async_infallible_constructor/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/error_handlers/cannot_register_an_error_handler_for_an_async_infallible_constructor/generated_app/src/Cargo.toml new file mode 100644 index 000000000..0f9567e61 --- /dev/null +++ b/compiler/ui_tests/blueprint/error_handlers/cannot_register_an_error_handler_for_an_async_infallible_constructor/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_c3c254cf" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_c3c254cf" diff --git a/compiler/ui_tests/blueprint/error_handlers/cannot_register_an_error_handler_for_an_async_infallible_constructor/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/error_handlers/cannot_register_an_error_handler_for_an_async_infallible_constructor/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/error_handlers/error_handlers_can_take_pavex_error_rather_than_specific_error_type/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/error_handlers/error_handlers_can_take_pavex_error_rather_than_specific_error_type/generated_app/Cargo.toml new file mode 100644 index 000000000..b9be56ae5 --- /dev/null +++ b/compiler/ui_tests/blueprint/error_handlers/error_handlers_can_take_pavex_error_rather_than_specific_error_type/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_40a0f751" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_40a0f751" + +[dependencies] +app_40a0f751 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/blueprint/error_handlers/error_handlers_can_take_pavex_error_rather_than_specific_error_type/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/error_handlers/error_handlers_can_take_pavex_error_rather_than_specific_error_type/generated_app/src/Cargo.toml new file mode 100644 index 000000000..89428c017 --- /dev/null +++ b/compiler/ui_tests/blueprint/error_handlers/error_handlers_can_take_pavex_error_rather_than_specific_error_type/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_40a0f751" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_40a0f751" diff --git a/compiler/ui_tests/blueprint/error_handlers/error_handlers_can_take_pavex_error_rather_than_specific_error_type/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/error_handlers/error_handlers_can_take_pavex_error_rather_than_specific_error_type/generated_app/src/lib.rs new file mode 100644 index 000000000..bf3049dc9 --- /dev/null +++ b/compiler/ui_tests/blueprint/error_handlers/error_handlers_can_take_pavex_error_rather_than_specific_error_type/generated_app/src/lib.rs @@ -0,0 +1,268 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/with_observer", 0u32).unwrap(); + router.insert("/without_observer", 1u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_1::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_2::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_1::entrypoint(&allowed_methods).await + } + } + } + 1u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_0::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_1::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_0::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_40a0f751::fallible_constructor(); + let v1 = match v0 { + Ok(ok) => ok, + Err(v1) => { + return { + let v2 = pavex::Error::new(v1); + let v3 = app_40a0f751::error_handler(&v2); + ::into_response(v3) + }; + } + }; + let v2 = app_40a0f751::generic_fallible_constructor(); + let v3 = match v2 { + Ok(ok) => ok, + Err(v3) => { + return { + let v4 = pavex::Error::new(v3); + let v5 = app_40a0f751::error_handler(&v4); + ::into_response(v5) + }; + } + }; + let v4 = app_40a0f751::without_observer(v1, v3); + ::into_response(v4) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} +pub mod route_1 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_1::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_2 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_2::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_40a0f751::fallible_constructor(); + let v1 = match v0 { + Ok(ok) => ok, + Err(v1) => { + return { + let v2 = pavex::Error::new(v1); + let v3 = app_40a0f751::error_handler(&v2); + app_40a0f751::error_observer(&v2); + ::into_response(v3) + }; + } + }; + let v2 = app_40a0f751::generic_fallible_constructor(); + let v3 = match v2 { + Ok(ok) => ok, + Err(v3) => { + return { + let v4 = pavex::Error::new(v3); + let v5 = app_40a0f751::error_handler(&v4); + app_40a0f751::error_observer(&v4); + ::into_response(v5) + }; + } + }; + let v4 = app_40a0f751::with_observer(v1, v3); + ::into_response(v4) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/blueprint/error_handlers/error_handlers_cannot_be_fallible/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/error_handlers/error_handlers_cannot_be_fallible/generated_app/Cargo.toml new file mode 100644 index 000000000..e16d3736c --- /dev/null +++ b/compiler/ui_tests/blueprint/error_handlers/error_handlers_cannot_be_fallible/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_6e40e01f" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_6e40e01f" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/error_handlers/error_handlers_cannot_be_fallible/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/error_handlers/error_handlers_cannot_be_fallible/generated_app/src/Cargo.toml new file mode 100644 index 000000000..4fe022917 --- /dev/null +++ b/compiler/ui_tests/blueprint/error_handlers/error_handlers_cannot_be_fallible/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_6e40e01f" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_6e40e01f" diff --git a/compiler/ui_tests/blueprint/error_handlers/error_handlers_cannot_be_fallible/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/error_handlers/error_handlers_cannot_be_fallible/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/error_handlers/generics_in_error_handlers_must_be_tied_to_the_error/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/error_handlers/generics_in_error_handlers_must_be_tied_to_the_error/generated_app/Cargo.toml new file mode 100644 index 000000000..8724e457e --- /dev/null +++ b/compiler/ui_tests/blueprint/error_handlers/generics_in_error_handlers_must_be_tied_to_the_error/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_51ea2925" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_51ea2925" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/error_handlers/generics_in_error_handlers_must_be_tied_to_the_error/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/error_handlers/generics_in_error_handlers_must_be_tied_to_the_error/generated_app/src/Cargo.toml new file mode 100644 index 000000000..557fc2620 --- /dev/null +++ b/compiler/ui_tests/blueprint/error_handlers/generics_in_error_handlers_must_be_tied_to_the_error/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_51ea2925" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_51ea2925" diff --git a/compiler/ui_tests/blueprint/error_handlers/generics_in_error_handlers_must_be_tied_to_the_error/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/error_handlers/generics_in_error_handlers_must_be_tied_to_the_error/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/error_observers/error_observers_input_parameters_cannot_be_generic/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/error_observers/error_observers_input_parameters_cannot_be_generic/generated_app/Cargo.toml new file mode 100644 index 000000000..0b64e2917 --- /dev/null +++ b/compiler/ui_tests/blueprint/error_observers/error_observers_input_parameters_cannot_be_generic/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_a0da5eb4" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_a0da5eb4" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/error_observers/error_observers_input_parameters_cannot_be_generic/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/error_observers/error_observers_input_parameters_cannot_be_generic/generated_app/src/Cargo.toml new file mode 100644 index 000000000..47d2b3690 --- /dev/null +++ b/compiler/ui_tests/blueprint/error_observers/error_observers_input_parameters_cannot_be_generic/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_a0da5eb4" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_a0da5eb4" diff --git a/compiler/ui_tests/blueprint/error_observers/error_observers_input_parameters_cannot_be_generic/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/error_observers/error_observers_input_parameters_cannot_be_generic/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/error_observers/error_observers_must_return_the_unit_type/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/error_observers/error_observers_must_return_the_unit_type/generated_app/Cargo.toml new file mode 100644 index 000000000..47362da7d --- /dev/null +++ b/compiler/ui_tests/blueprint/error_observers/error_observers_must_return_the_unit_type/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_e31b3bf3" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_e31b3bf3" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/error_observers/error_observers_must_return_the_unit_type/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/error_observers/error_observers_must_return_the_unit_type/generated_app/src/Cargo.toml new file mode 100644 index 000000000..3a758b9c7 --- /dev/null +++ b/compiler/ui_tests/blueprint/error_observers/error_observers_must_return_the_unit_type/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_e31b3bf3" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_e31b3bf3" diff --git a/compiler/ui_tests/blueprint/error_observers/error_observers_must_return_the_unit_type/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/error_observers/error_observers_must_return_the_unit_type/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/error_observers/error_observers_must_take_pavex_error_as_ref/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/error_observers/error_observers_must_take_pavex_error_as_ref/generated_app/Cargo.toml new file mode 100644 index 000000000..b693da638 --- /dev/null +++ b/compiler/ui_tests/blueprint/error_observers/error_observers_must_take_pavex_error_as_ref/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_8b77b4be" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_8b77b4be" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/error_observers/error_observers_must_take_pavex_error_as_ref/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/error_observers/error_observers_must_take_pavex_error_as_ref/generated_app/src/Cargo.toml new file mode 100644 index 000000000..0e78a9d24 --- /dev/null +++ b/compiler/ui_tests/blueprint/error_observers/error_observers_must_take_pavex_error_as_ref/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_8b77b4be" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_8b77b4be" diff --git a/compiler/ui_tests/blueprint/error_observers/error_observers_must_take_pavex_error_as_ref/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/error_observers/error_observers_must_take_pavex_error_as_ref/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/nesting/application_state_should_include_runtime_singletons_from_all_scopes/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/nesting/application_state_should_include_runtime_singletons_from_all_scopes/generated_app/Cargo.toml new file mode 100644 index 000000000..e7576910c --- /dev/null +++ b/compiler/ui_tests/blueprint/nesting/application_state_should_include_runtime_singletons_from_all_scopes/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_ea86e18a" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_ea86e18a" + +[dependencies] +app_ea86e18a = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/blueprint/nesting/application_state_should_include_runtime_singletons_from_all_scopes/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/nesting/application_state_should_include_runtime_singletons_from_all_scopes/generated_app/src/Cargo.toml new file mode 100644 index 000000000..0557bd004 --- /dev/null +++ b/compiler/ui_tests/blueprint/nesting/application_state_should_include_runtime_singletons_from_all_scopes/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_ea86e18a" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_ea86e18a" diff --git a/compiler/ui_tests/blueprint/nesting/application_state_should_include_runtime_singletons_from_all_scopes/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/nesting/application_state_should_include_runtime_singletons_from_all_scopes/generated_app/src/lib.rs new file mode 100644 index 000000000..741ab1a20 --- /dev/null +++ b/compiler/ui_tests/blueprint/nesting/application_state_should_include_runtime_singletons_from_all_scopes/generated_app/src/lib.rs @@ -0,0 +1,238 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState { + pub u32_: u32, + pub u64_: u64, +} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + let v0 = app_ea86e18a::parent_singleton(); + let v1 = app_ea86e18a::singleton_dep(); + let v2 = app_ea86e18a::nested_singleton(v1); + crate::ApplicationState { + u32_: v2, + u64_: v0, + } + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/child", 0u32).unwrap(); + router.insert("/parent", 1u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_1::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => { + route_2::entrypoint(state.u32_.clone()).await + } + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_1::entrypoint(&allowed_methods).await + } + } + } + 1u32 => { + match &request_head.method { + &pavex::http::Method::GET => { + route_0::entrypoint(state.u64_.clone()).await + } + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_1::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint(s_0: u64) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1(s_0: u64) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: u64) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: u64) -> pavex::Response { + let v1 = app_ea86e18a::parent_handler(v0); + ::into_response(v1) + } + struct Next0 + where + T: std::future::Future, + { + s_0: u64, + next: fn(u64) -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_1::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_2 { + pub async fn entrypoint(s_0: u32) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1(s_0: u32) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: u32) -> pavex::Response { + let v1 = crate::route_2::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: u32) -> pavex::Response { + let v1 = app_ea86e18a::child_handler(v0); + ::into_response(v1) + } + struct Next0 + where + T: std::future::Future, + { + s_0: u32, + next: fn(u32) -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} diff --git a/compiler/ui_tests/blueprint/nesting/multiple_levels_of_nesting_are_supported/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/nesting/multiple_levels_of_nesting_are_supported/generated_app/Cargo.toml new file mode 100644 index 000000000..030699292 --- /dev/null +++ b/compiler/ui_tests/blueprint/nesting/multiple_levels_of_nesting_are_supported/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_91e1ac20" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_91e1ac20" + +[dependencies] +app_91e1ac20 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/blueprint/nesting/multiple_levels_of_nesting_are_supported/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/nesting/multiple_levels_of_nesting_are_supported/generated_app/src/Cargo.toml new file mode 100644 index 000000000..b40fa42f4 --- /dev/null +++ b/compiler/ui_tests/blueprint/nesting/multiple_levels_of_nesting_are_supported/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_91e1ac20" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_91e1ac20" diff --git a/compiler/ui_tests/blueprint/nesting/multiple_levels_of_nesting_are_supported/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/nesting/multiple_levels_of_nesting_are_supported/generated_app/src/lib.rs new file mode 100644 index 000000000..288ec5a08 --- /dev/null +++ b/compiler/ui_tests/blueprint/nesting/multiple_levels_of_nesting_are_supported/generated_app/src/lib.rs @@ -0,0 +1,174 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/first/second/third/home", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_91e1ac20::first(); + let v1 = app_91e1ac20::second(v0); + let v2 = app_91e1ac20::third(v1); + let v3 = app_91e1ac20::handler(v2); + ::into_response(v3) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/blueprint/nesting/nesting_fails_if_parent_singleton_is_overridden/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/nesting/nesting_fails_if_parent_singleton_is_overridden/generated_app/Cargo.toml new file mode 100644 index 000000000..770c41237 --- /dev/null +++ b/compiler/ui_tests/blueprint/nesting/nesting_fails_if_parent_singleton_is_overridden/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_309371bf" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_309371bf" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/nesting/nesting_fails_if_parent_singleton_is_overridden/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/nesting/nesting_fails_if_parent_singleton_is_overridden/generated_app/src/Cargo.toml new file mode 100644 index 000000000..4a730352d --- /dev/null +++ b/compiler/ui_tests/blueprint/nesting/nesting_fails_if_parent_singleton_is_overridden/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_309371bf" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_309371bf" diff --git a/compiler/ui_tests/blueprint/nesting/nesting_fails_if_parent_singleton_is_overridden/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/nesting/nesting_fails_if_parent_singleton_is_overridden/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/nesting/nesting_fails_if_the_same_singleton_constructor_is_registered_in_different_scopes/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/nesting/nesting_fails_if_the_same_singleton_constructor_is_registered_in_different_scopes/generated_app/Cargo.toml new file mode 100644 index 000000000..e3f579842 --- /dev/null +++ b/compiler/ui_tests/blueprint/nesting/nesting_fails_if_the_same_singleton_constructor_is_registered_in_different_scopes/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_de592621" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_de592621" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/nesting/nesting_fails_if_the_same_singleton_constructor_is_registered_in_different_scopes/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/nesting/nesting_fails_if_the_same_singleton_constructor_is_registered_in_different_scopes/generated_app/src/Cargo.toml new file mode 100644 index 000000000..020a0db1f --- /dev/null +++ b/compiler/ui_tests/blueprint/nesting/nesting_fails_if_the_same_singleton_constructor_is_registered_in_different_scopes/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_de592621" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_de592621" diff --git a/compiler/ui_tests/blueprint/nesting/nesting_fails_if_the_same_singleton_constructor_is_registered_in_different_scopes/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/nesting/nesting_fails_if_the_same_singleton_constructor_is_registered_in_different_scopes/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/nesting/nesting_hides_constructors_of_the_nested_bp_to_the_parent_bp/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/nesting/nesting_hides_constructors_of_the_nested_bp_to_the_parent_bp/generated_app/Cargo.toml new file mode 100644 index 000000000..6bc48103c --- /dev/null +++ b/compiler/ui_tests/blueprint/nesting/nesting_hides_constructors_of_the_nested_bp_to_the_parent_bp/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_ae32f1c9" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_ae32f1c9" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/nesting/nesting_hides_constructors_of_the_nested_bp_to_the_parent_bp/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/nesting/nesting_hides_constructors_of_the_nested_bp_to_the_parent_bp/generated_app/src/Cargo.toml new file mode 100644 index 000000000..0e519b519 --- /dev/null +++ b/compiler/ui_tests/blueprint/nesting/nesting_hides_constructors_of_the_nested_bp_to_the_parent_bp/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_ae32f1c9" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_ae32f1c9" diff --git a/compiler/ui_tests/blueprint/nesting/nesting_hides_constructors_of_the_nested_bp_to_the_parent_bp/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/nesting/nesting_hides_constructors_of_the_nested_bp_to_the_parent_bp/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/post_processing_middlewares/cannot_have_multiple_response_inputs/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/post_processing_middlewares/cannot_have_multiple_response_inputs/generated_app/Cargo.toml new file mode 100644 index 000000000..20e1c89cc --- /dev/null +++ b/compiler/ui_tests/blueprint/post_processing_middlewares/cannot_have_multiple_response_inputs/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_466ed127" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_466ed127" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/post_processing_middlewares/cannot_have_multiple_response_inputs/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/post_processing_middlewares/cannot_have_multiple_response_inputs/generated_app/src/Cargo.toml new file mode 100644 index 000000000..0ecb4dcdc --- /dev/null +++ b/compiler/ui_tests/blueprint/post_processing_middlewares/cannot_have_multiple_response_inputs/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_466ed127" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_466ed127" diff --git a/compiler/ui_tests/blueprint/post_processing_middlewares/cannot_have_multiple_response_inputs/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/post_processing_middlewares/cannot_have_multiple_response_inputs/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/post_processing_middlewares/finalizer_pattern/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/post_processing_middlewares/finalizer_pattern/generated_app/Cargo.toml new file mode 100644 index 000000000..befb27e10 --- /dev/null +++ b/compiler/ui_tests/blueprint/post_processing_middlewares/finalizer_pattern/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_41064ffa" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_41064ffa" + +[dependencies] +app_41064ffa = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/blueprint/post_processing_middlewares/finalizer_pattern/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/post_processing_middlewares/finalizer_pattern/generated_app/src/Cargo.toml new file mode 100644 index 000000000..d94f5951d --- /dev/null +++ b/compiler/ui_tests/blueprint/post_processing_middlewares/finalizer_pattern/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_41064ffa" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_41064ffa" diff --git a/compiler/ui_tests/blueprint/post_processing_middlewares/finalizer_pattern/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/post_processing_middlewares/finalizer_pattern/generated_app/src/lib.rs new file mode 100644 index 000000000..8765e60db --- /dev/null +++ b/compiler/ui_tests/blueprint/post_processing_middlewares/finalizer_pattern/generated_app/src/lib.rs @@ -0,0 +1,228 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>( + mut s_0: app_41064ffa::A, + s_1: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = handler(s_1).await; + let response = post_processing_0(response, &mut s_0).await; + let response = post_processing_1(response, &mut s_0).await; + let response = post_processing_2(response, s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = app_41064ffa::a(); + let v2 = crate::route_0::Next0 { + s_0: v1, + s_1: v0, + next: stage_1, + }; + let v3 = pavex::middleware::Next::new(v2); + let v4 = pavex::middleware::wrap_noop(v3).await; + ::into_response(v4) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + async fn post_processing_0( + v0: pavex::Response, + v1: &mut app_41064ffa::A, + ) -> pavex::Response { + let v2 = app_41064ffa::first(v0, v1); + ::into_response(v2) + } + async fn post_processing_1( + v0: pavex::Response, + v1: &mut app_41064ffa::A, + ) -> pavex::Response { + let v2 = app_41064ffa::second(v0, v1); + ::into_response(v2) + } + async fn post_processing_2( + v0: pavex::Response, + v1: app_41064ffa::A, + ) -> pavex::Response { + let v2 = app_41064ffa::third(v0, v1); + ::into_response(v2) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: app_41064ffa::A, + s_1: &'a pavex::router::AllowedMethods, + next: fn(app_41064ffa::A, &'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0, self.s_1) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1(mut s_0: app_41064ffa::A) -> pavex::Response { + let response = handler(&mut s_0).await; + let response = post_processing_0(response, &mut s_0).await; + let response = post_processing_1(response, &mut s_0).await; + let response = post_processing_2(response, s_0).await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = app_41064ffa::a(); + let v1 = crate::route_1::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &mut app_41064ffa::A) -> pavex::Response { + let v1 = app_41064ffa::handler(v0); + ::into_response(v1) + } + async fn post_processing_0( + v0: pavex::Response, + v1: &mut app_41064ffa::A, + ) -> pavex::Response { + let v2 = app_41064ffa::first(v0, v1); + ::into_response(v2) + } + async fn post_processing_1( + v0: pavex::Response, + v1: &mut app_41064ffa::A, + ) -> pavex::Response { + let v2 = app_41064ffa::second(v0, v1); + ::into_response(v2) + } + async fn post_processing_2( + v0: pavex::Response, + v1: app_41064ffa::A, + ) -> pavex::Response { + let v2 = app_41064ffa::third(v0, v1); + ::into_response(v2) + } + struct Next0 + where + T: std::future::Future, + { + s_0: app_41064ffa::A, + next: fn(app_41064ffa::A) -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} diff --git a/compiler/ui_tests/blueprint/post_processing_middlewares/must_take_response_as_input/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/post_processing_middlewares/must_take_response_as_input/generated_app/Cargo.toml new file mode 100644 index 000000000..5660473e5 --- /dev/null +++ b/compiler/ui_tests/blueprint/post_processing_middlewares/must_take_response_as_input/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_4a62f10c" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_4a62f10c" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/post_processing_middlewares/must_take_response_as_input/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/post_processing_middlewares/must_take_response_as_input/generated_app/src/Cargo.toml new file mode 100644 index 000000000..3654cd586 --- /dev/null +++ b/compiler/ui_tests/blueprint/post_processing_middlewares/must_take_response_as_input/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_4a62f10c" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_4a62f10c" diff --git a/compiler/ui_tests/blueprint/post_processing_middlewares/must_take_response_as_input/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/post_processing_middlewares/must_take_response_as_input/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/post_processing_middlewares/post_process_without_wrapping/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/post_processing_middlewares/post_process_without_wrapping/generated_app/Cargo.toml new file mode 100644 index 000000000..9dce99dd6 --- /dev/null +++ b/compiler/ui_tests/blueprint/post_processing_middlewares/post_process_without_wrapping/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_c8000fe9" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_c8000fe9" + +[dependencies] +app_c8000fe9 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/blueprint/post_processing_middlewares/post_process_without_wrapping/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/post_processing_middlewares/post_process_without_wrapping/generated_app/src/Cargo.toml new file mode 100644 index 000000000..f9e38cacc --- /dev/null +++ b/compiler/ui_tests/blueprint/post_processing_middlewares/post_process_without_wrapping/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_c8000fe9" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_c8000fe9" diff --git a/compiler/ui_tests/blueprint/post_processing_middlewares/post_process_without_wrapping/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/post_processing_middlewares/post_process_without_wrapping/generated_app/src/lib.rs new file mode 100644 index 000000000..ac4a74063 --- /dev/null +++ b/compiler/ui_tests/blueprint/post_processing_middlewares/post_process_without_wrapping/generated_app/src/lib.rs @@ -0,0 +1,181 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + let response = post_processing_0(response).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + async fn post_processing_0(v0: pavex::Response) -> pavex::Response { + let v1 = app_c8000fe9::mw(v0); + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + let response = post_processing_0(response).await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_c8000fe9::handler(); + ::into_response(v0) + } + async fn post_processing_0(v0: pavex::Response) -> pavex::Response { + let v1 = app_c8000fe9::mw(v0); + ::into_response(v1) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/blueprint/post_processing_middlewares/post_processing_can_fail/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/post_processing_middlewares/post_processing_can_fail/generated_app/Cargo.toml new file mode 100644 index 000000000..578ba4ce4 --- /dev/null +++ b/compiler/ui_tests/blueprint/post_processing_middlewares/post_processing_can_fail/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_e0af8622" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_e0af8622" + +[dependencies] +app_e0af8622 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/blueprint/post_processing_middlewares/post_processing_can_fail/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/post_processing_middlewares/post_processing_can_fail/generated_app/src/Cargo.toml new file mode 100644 index 000000000..38d605a19 --- /dev/null +++ b/compiler/ui_tests/blueprint/post_processing_middlewares/post_processing_can_fail/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_e0af8622" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_e0af8622" diff --git a/compiler/ui_tests/blueprint/post_processing_middlewares/post_processing_can_fail/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/post_processing_middlewares/post_processing_can_fail/generated_app/src/lib.rs new file mode 100644 index 000000000..141631958 --- /dev/null +++ b/compiler/ui_tests/blueprint/post_processing_middlewares/post_processing_can_fail/generated_app/src/lib.rs @@ -0,0 +1,227 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + let response = post_processing_0(response).await; + let response = post_processing_1(response).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + async fn post_processing_0(v0: pavex::Response) -> pavex::Response { + let v1 = app_e0af8622::via_attribute(v0); + let v2 = match v1 { + Ok(ok) => ok, + Err(v2) => { + return { + let v3 = app_e0af8622::CustomError::into_response(&v2); + ::into_response(v3) + }; + } + }; + ::into_response(v2) + } + async fn post_processing_1(v0: pavex::Response) -> pavex::Response { + let v1 = app_e0af8622::override_in_blueprint(v0); + let v2 = match v1 { + Ok(ok) => ok, + Err(v2) => { + return { + let v3 = app_e0af8622::CustomError::into_response_override(&v2); + ::into_response(v3) + }; + } + }; + ::into_response(v2) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + let response = post_processing_0(response).await; + let response = post_processing_1(response).await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_e0af8622::handler(); + ::into_response(v0) + } + async fn post_processing_0(v0: pavex::Response) -> pavex::Response { + let v1 = app_e0af8622::via_attribute(v0); + let v2 = match v1 { + Ok(ok) => ok, + Err(v2) => { + return { + let v3 = app_e0af8622::CustomError::into_response(&v2); + ::into_response(v3) + }; + } + }; + ::into_response(v2) + } + async fn post_processing_1(v0: pavex::Response) -> pavex::Response { + let v1 = app_e0af8622::override_in_blueprint(v0); + let v2 = match v1 { + Ok(ok) => ok, + Err(v2) => { + return { + let v3 = app_e0af8622::CustomError::into_response_override(&v2); + ::into_response(v3) + }; + } + }; + ::into_response(v2) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/blueprint/post_processing_middlewares/post_processing_middlewares_input_parameters_cannot_be_generic/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/post_processing_middlewares/post_processing_middlewares_input_parameters_cannot_be_generic/generated_app/Cargo.toml new file mode 100644 index 000000000..dfc7f4c43 --- /dev/null +++ b/compiler/ui_tests/blueprint/post_processing_middlewares/post_processing_middlewares_input_parameters_cannot_be_generic/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_59d05850" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_59d05850" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/post_processing_middlewares/post_processing_middlewares_input_parameters_cannot_be_generic/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/post_processing_middlewares/post_processing_middlewares_input_parameters_cannot_be_generic/generated_app/src/Cargo.toml new file mode 100644 index 000000000..cc6861449 --- /dev/null +++ b/compiler/ui_tests/blueprint/post_processing_middlewares/post_processing_middlewares_input_parameters_cannot_be_generic/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_59d05850" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_59d05850" diff --git a/compiler/ui_tests/blueprint/post_processing_middlewares/post_processing_middlewares_input_parameters_cannot_be_generic/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/post_processing_middlewares/post_processing_middlewares_input_parameters_cannot_be_generic/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/pre_processing_middlewares/pre_process_without_wrapping/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/pre_processing_middlewares/pre_process_without_wrapping/generated_app/Cargo.toml new file mode 100644 index 000000000..3cfe11224 --- /dev/null +++ b/compiler/ui_tests/blueprint/pre_processing_middlewares/pre_process_without_wrapping/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_8ac65a81" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_8ac65a81" + +[dependencies] +app_8ac65a81 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/blueprint/pre_processing_middlewares/pre_process_without_wrapping/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/pre_processing_middlewares/pre_process_without_wrapping/generated_app/src/Cargo.toml new file mode 100644 index 000000000..13ff6bce3 --- /dev/null +++ b/compiler/ui_tests/blueprint/pre_processing_middlewares/pre_process_without_wrapping/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_8ac65a81" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_8ac65a81" diff --git a/compiler/ui_tests/blueprint/pre_processing_middlewares/pre_process_without_wrapping/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/pre_processing_middlewares/pre_process_without_wrapping/generated_app/src/lib.rs new file mode 100644 index 000000000..48567d418 --- /dev/null +++ b/compiler/ui_tests/blueprint/pre_processing_middlewares/pre_process_without_wrapping/generated_app/src/lib.rs @@ -0,0 +1,187 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/home", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = 'incoming: { + if let Some(response) = pre_processing_0().await.into_response() { + break 'incoming response; + } + handler(s_0).await + }; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn pre_processing_0() -> pavex::middleware::Processing { + app_8ac65a81::pre() + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = 'incoming: { + if let Some(response) = pre_processing_0().await.into_response() { + break 'incoming response; + } + handler().await + }; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn pre_processing_0() -> pavex::middleware::Processing { + app_8ac65a81::pre() + } + async fn handler() -> pavex::Response { + let v0 = app_8ac65a81::handler(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/blueprint/pre_processing_middlewares/pre_processing_can_fail/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/pre_processing_middlewares/pre_processing_can_fail/generated_app/Cargo.toml new file mode 100644 index 000000000..b9eadce7c --- /dev/null +++ b/compiler/ui_tests/blueprint/pre_processing_middlewares/pre_processing_can_fail/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_35634115" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_35634115" + +[dependencies] +app_35634115 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/blueprint/pre_processing_middlewares/pre_processing_can_fail/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/pre_processing_middlewares/pre_processing_can_fail/generated_app/src/Cargo.toml new file mode 100644 index 000000000..c23a1b614 --- /dev/null +++ b/compiler/ui_tests/blueprint/pre_processing_middlewares/pre_processing_can_fail/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_35634115" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_35634115" diff --git a/compiler/ui_tests/blueprint/pre_processing_middlewares/pre_processing_can_fail/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/pre_processing_middlewares/pre_processing_can_fail/generated_app/src/lib.rs new file mode 100644 index 000000000..b6d1329f1 --- /dev/null +++ b/compiler/ui_tests/blueprint/pre_processing_middlewares/pre_processing_can_fail/generated_app/src/lib.rs @@ -0,0 +1,243 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = 'incoming: { + if let Some(response) = pre_processing_0().await.into_response() { + break 'incoming response; + } + if let Some(response) = pre_processing_1().await.into_response() { + break 'incoming response; + } + handler(s_0).await + }; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn pre_processing_0() -> pavex::middleware::Processing { + let v0 = app_35634115::via_attribute(); + let v1 = match v0 { + Ok(ok) => ok, + Err(v1) => { + return { + let v2 = app_35634115::CustomError::into_response(&v1); + let v3 = ::into_response(v2); + pavex::middleware::Processing::EarlyReturn(v3) + }; + } + }; + v1 + } + async fn pre_processing_1() -> pavex::middleware::Processing { + let v0 = app_35634115::override_in_blueprint(); + let v1 = match v0 { + Ok(ok) => ok, + Err(v1) => { + return { + let v2 = app_35634115::CustomError::into_response_override(&v1); + let v3 = ::into_response(v2); + pavex::middleware::Processing::EarlyReturn(v3) + }; + } + }; + v1 + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = 'incoming: { + if let Some(response) = pre_processing_0().await.into_response() { + break 'incoming response; + } + if let Some(response) = pre_processing_1().await.into_response() { + break 'incoming response; + } + handler().await + }; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn pre_processing_0() -> pavex::middleware::Processing { + let v0 = app_35634115::via_attribute(); + let v1 = match v0 { + Ok(ok) => ok, + Err(v1) => { + return { + let v2 = app_35634115::CustomError::into_response(&v1); + let v3 = ::into_response(v2); + pavex::middleware::Processing::EarlyReturn(v3) + }; + } + }; + v1 + } + async fn pre_processing_1() -> pavex::middleware::Processing { + let v0 = app_35634115::override_in_blueprint(); + let v1 = match v0 { + Ok(ok) => ok, + Err(v1) => { + return { + let v2 = app_35634115::CustomError::into_response_override(&v1); + let v3 = ::into_response(v2); + pavex::middleware::Processing::EarlyReturn(v3) + }; + } + }; + v1 + } + async fn handler() -> pavex::Response { + let v0 = app_35634115::handler(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/blueprint/pre_processing_middlewares/pre_processing_middlewares_input_parameters_cannot_be_generic/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/pre_processing_middlewares/pre_processing_middlewares_input_parameters_cannot_be_generic/generated_app/Cargo.toml new file mode 100644 index 000000000..cd433dd52 --- /dev/null +++ b/compiler/ui_tests/blueprint/pre_processing_middlewares/pre_processing_middlewares_input_parameters_cannot_be_generic/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_b3516518" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_b3516518" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/pre_processing_middlewares/pre_processing_middlewares_input_parameters_cannot_be_generic/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/pre_processing_middlewares/pre_processing_middlewares_input_parameters_cannot_be_generic/generated_app/src/Cargo.toml new file mode 100644 index 000000000..3f2caee34 --- /dev/null +++ b/compiler/ui_tests/blueprint/pre_processing_middlewares/pre_processing_middlewares_input_parameters_cannot_be_generic/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_b3516518" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_b3516518" diff --git a/compiler/ui_tests/blueprint/pre_processing_middlewares/pre_processing_middlewares_input_parameters_cannot_be_generic/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/pre_processing_middlewares/pre_processing_middlewares_input_parameters_cannot_be_generic/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/prebuilts/invalid_prebuilt/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/prebuilts/invalid_prebuilt/generated_app/Cargo.toml new file mode 100644 index 000000000..b5a8ad276 --- /dev/null +++ b/compiler/ui_tests/blueprint/prebuilts/invalid_prebuilt/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_9d0a5748" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_9d0a5748" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/prebuilts/invalid_prebuilt/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/prebuilts/invalid_prebuilt/generated_app/src/Cargo.toml new file mode 100644 index 000000000..ea4661f13 --- /dev/null +++ b/compiler/ui_tests/blueprint/prebuilts/invalid_prebuilt/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_9d0a5748" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_9d0a5748" diff --git a/compiler/ui_tests/blueprint/prebuilts/invalid_prebuilt/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/prebuilts/invalid_prebuilt/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/prebuilts/prebuilt_does_not_need_to_be_send_and_sync_if_only_used_at_build_time/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/prebuilts/prebuilt_does_not_need_to_be_send_and_sync_if_only_used_at_build_time/generated_app/Cargo.toml new file mode 100644 index 000000000..c1ba33650 --- /dev/null +++ b/compiler/ui_tests/blueprint/prebuilts/prebuilt_does_not_need_to_be_send_and_sync_if_only_used_at_build_time/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_776ff188" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_776ff188" + +[dependencies] +app_776ff188 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/blueprint/prebuilts/prebuilt_does_not_need_to_be_send_and_sync_if_only_used_at_build_time/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/prebuilts/prebuilt_does_not_need_to_be_send_and_sync_if_only_used_at_build_time/generated_app/src/Cargo.toml new file mode 100644 index 000000000..e57bdf4b3 --- /dev/null +++ b/compiler/ui_tests/blueprint/prebuilts/prebuilt_does_not_need_to_be_send_and_sync_if_only_used_at_build_time/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_776ff188" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_776ff188" diff --git a/compiler/ui_tests/blueprint/prebuilts/prebuilt_does_not_need_to_be_send_and_sync_if_only_used_at_build_time/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/prebuilts/prebuilt_does_not_need_to_be_send_and_sync_if_only_used_at_build_time/generated_app/src/lib.rs new file mode 100644 index 000000000..820acc4e4 --- /dev/null +++ b/compiler/ui_tests/blueprint/prebuilts/prebuilt_does_not_need_to_be_send_and_sync_if_only_used_at_build_time/generated_app/src/lib.rs @@ -0,0 +1,176 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState { + pub b: app_776ff188::B, +} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + v0: app_776ff188::A, + ) -> Result { + Ok(Self::_new(v0).await) + } + async fn _new(v0: app_776ff188::A) -> crate::ApplicationState { + let v1 = app_776ff188::b(v0); + crate::ApplicationState { b: v1 } + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint(&state.b).await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint<'a>(s_0: &'a app_776ff188::B) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a app_776ff188::B) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &app_776ff188::B) -> pavex::Response { + let v1 = crate::route_1::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &app_776ff188::B) -> pavex::Response { + let v1 = app_776ff188::handler(v0); + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a app_776ff188::B, + next: fn(&'a app_776ff188::B) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} diff --git a/compiler/ui_tests/blueprint/prebuilts/prebuilt_works/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/prebuilts/prebuilt_works/generated_app/Cargo.toml new file mode 100644 index 000000000..d5209abc0 --- /dev/null +++ b/compiler/ui_tests/blueprint/prebuilts/prebuilt_works/generated_app/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "application_e4a8214b" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_e4a8214b" + +[dependencies] +app_e4a8214b = { version = "0.1", path = "..", default-features = false } +dep_29415e1g = { version = "0.1", path = "../ephemeral_deps/dep", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/blueprint/prebuilts/prebuilt_works/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/prebuilts/prebuilt_works/generated_app/src/Cargo.toml new file mode 100644 index 000000000..3e3ad2bfa --- /dev/null +++ b/compiler/ui_tests/blueprint/prebuilts/prebuilt_works/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_e4a8214b" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_e4a8214b" diff --git a/compiler/ui_tests/blueprint/prebuilts/prebuilt_works/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/prebuilts/prebuilt_works/generated_app/src/lib.rs new file mode 100644 index 000000000..b48466f6e --- /dev/null +++ b/compiler/ui_tests/blueprint/prebuilts/prebuilt_works/generated_app/src/lib.rs @@ -0,0 +1,242 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState { + pub a: app_e4a8214b::A, + pub c: app_e4a8214b::C, + pub e: app_e4a8214b::E, + pub f: dep_29415e1g::F, + pub z: dep_29415e1g::Z, +} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + v0: dep_29415e1g::Z, + v1: dep_29415e1g::F, + v2: app_e4a8214b::E, + v3: app_e4a8214b::C, + v4: app_e4a8214b::A, + ) -> Result { + Ok(Self::_new(v0, v1, v2, v3, v4).await) + } + async fn _new( + v0: dep_29415e1g::Z, + v1: dep_29415e1g::F, + v2: app_e4a8214b::E, + v3: app_e4a8214b::C, + v4: app_e4a8214b::A, + ) -> crate::ApplicationState { + crate::ApplicationState { + a: v4, + c: v3, + e: v2, + f: v1, + z: v0, + } + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => { + route_1::entrypoint( + &state.a, + &state.c, + &state.e, + &state.f, + &state.z, + ) + .await + } + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint<'a, 'b, 'c, 'd, 'e>( + s_0: &'a app_e4a8214b::A, + s_1: &'b app_e4a8214b::C, + s_2: &'c app_e4a8214b::E, + s_3: &'d dep_29415e1g::F, + s_4: &'e dep_29415e1g::Z, + ) -> pavex::Response { + let response = wrapping_0(s_0, s_1, s_2, s_3, s_4).await; + response + } + async fn stage_1<'a, 'b, 'c, 'd, 'e>( + s_0: &'a app_e4a8214b::A, + s_1: &'b app_e4a8214b::C, + s_2: &'c app_e4a8214b::E, + s_3: &'d dep_29415e1g::F, + s_4: &'e dep_29415e1g::Z, + ) -> pavex::Response { + let response = handler(s_0, s_1, s_2, s_3, s_4).await; + response + } + async fn wrapping_0( + v0: &app_e4a8214b::A, + v1: &app_e4a8214b::C, + v2: &app_e4a8214b::E, + v3: &dep_29415e1g::F, + v4: &dep_29415e1g::Z, + ) -> pavex::Response { + let v5 = crate::route_1::Next0 { + s_0: v0, + s_1: v1, + s_2: v2, + s_3: v3, + s_4: v4, + next: stage_1, + }; + let v6 = pavex::middleware::Next::new(v5); + let v7 = pavex::middleware::wrap_noop(v6).await; + ::into_response(v7) + } + async fn handler( + v0: &app_e4a8214b::A, + v1: &app_e4a8214b::C, + v2: &app_e4a8214b::E, + v3: &dep_29415e1g::F, + v4: &dep_29415e1g::Z, + ) -> pavex::Response { + let v5 = app_e4a8214b::handler(v0, v1, v2, v3, v4); + ::into_response(v5) + } + struct Next0<'a, 'b, 'c, 'd, 'e, T> + where + T: std::future::Future, + { + s_0: &'a app_e4a8214b::A, + s_1: &'b app_e4a8214b::C, + s_2: &'c app_e4a8214b::E, + s_3: &'d dep_29415e1g::F, + s_4: &'e dep_29415e1g::Z, + next: fn( + &'a app_e4a8214b::A, + &'b app_e4a8214b::C, + &'c app_e4a8214b::E, + &'d dep_29415e1g::F, + &'e dep_29415e1g::Z, + ) -> T, + } + impl<'a, 'b, 'c, 'd, 'e, T> std::future::IntoFuture for Next0<'a, 'b, 'c, 'd, 'e, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0, self.s_1, self.s_2, self.s_3, self.s_4) + } + } +} diff --git a/compiler/ui_tests/blueprint/prebuilts/prebuilts_can_be_cloned/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/prebuilts/prebuilts_can_be_cloned/generated_app/Cargo.toml new file mode 100644 index 000000000..8913b1325 --- /dev/null +++ b/compiler/ui_tests/blueprint/prebuilts/prebuilts_can_be_cloned/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_4c9069e8" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_4c9069e8" + +[dependencies] +app_4c9069e8 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/blueprint/prebuilts/prebuilts_can_be_cloned/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/prebuilts/prebuilts_can_be_cloned/generated_app/src/Cargo.toml new file mode 100644 index 000000000..93cab8f4b --- /dev/null +++ b/compiler/ui_tests/blueprint/prebuilts/prebuilts_can_be_cloned/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_4c9069e8" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_4c9069e8" diff --git a/compiler/ui_tests/blueprint/prebuilts/prebuilts_can_be_cloned/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/prebuilts/prebuilts_can_be_cloned/generated_app/src/lib.rs new file mode 100644 index 000000000..089b9566d --- /dev/null +++ b/compiler/ui_tests/blueprint/prebuilts/prebuilts_can_be_cloned/generated_app/src/lib.rs @@ -0,0 +1,191 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState { + pub a: app_4c9069e8::A, + pub b: app_4c9069e8::B, +} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + v0: app_4c9069e8::A, + ) -> Result { + Ok(Self::_new(v0).await) + } + async fn _new(v0: app_4c9069e8::A) -> crate::ApplicationState { + let v1 = ::clone(&v0); + let v2 = app_4c9069e8::b(v0); + crate::ApplicationState { + a: v1, + b: v2, + } + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => { + route_1::entrypoint(state.a.clone(), &state.b).await + } + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint<'a>( + s_0: app_4c9069e8::A, + s_1: &'a app_4c9069e8::B, + ) -> pavex::Response { + let response = wrapping_0(s_0, s_1).await; + response + } + async fn stage_1<'a>( + s_0: app_4c9069e8::A, + s_1: &'a app_4c9069e8::B, + ) -> pavex::Response { + let response = handler(s_0, s_1).await; + response + } + async fn wrapping_0(v0: app_4c9069e8::A, v1: &app_4c9069e8::B) -> pavex::Response { + let v2 = crate::route_1::Next0 { + s_0: v0, + s_1: v1, + next: stage_1, + }; + let v3 = pavex::middleware::Next::new(v2); + let v4 = pavex::middleware::wrap_noop(v3).await; + ::into_response(v4) + } + async fn handler(v0: app_4c9069e8::A, v1: &app_4c9069e8::B) -> pavex::Response { + let v2 = app_4c9069e8::handler(v0, v1); + ::into_response(v2) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: app_4c9069e8::A, + s_1: &'a app_4c9069e8::B, + next: fn(app_4c9069e8::A, &'a app_4c9069e8::B) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0, self.s_1) + } + } +} diff --git a/compiler/ui_tests/blueprint/prebuilts/unused_prebuilt/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/prebuilts/unused_prebuilt/generated_app/Cargo.toml new file mode 100644 index 000000000..128afb4e8 --- /dev/null +++ b/compiler/ui_tests/blueprint/prebuilts/unused_prebuilt/generated_app/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "application_ee506b88" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_ee506b88" + +[dependencies] +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/blueprint/prebuilts/unused_prebuilt/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/prebuilts/unused_prebuilt/generated_app/src/Cargo.toml new file mode 100644 index 000000000..1de180c69 --- /dev/null +++ b/compiler/ui_tests/blueprint/prebuilts/unused_prebuilt/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_ee506b88" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_ee506b88" diff --git a/compiler/ui_tests/blueprint/prebuilts/unused_prebuilt/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/prebuilts/unused_prebuilt/generated_app/src/lib.rs new file mode 100644 index 000000000..37117e8fc --- /dev/null +++ b/compiler/ui_tests/blueprint/prebuilts/unused_prebuilt/generated_app/src/lib.rs @@ -0,0 +1,120 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let router = matchit::Router::new(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} diff --git a/compiler/ui_tests/blueprint/router/ambiguous_fallback/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/router/ambiguous_fallback/generated_app/Cargo.toml new file mode 100644 index 000000000..17d06b659 --- /dev/null +++ b/compiler/ui_tests/blueprint/router/ambiguous_fallback/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_9fbe7a0c" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_9fbe7a0c" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/router/ambiguous_fallback/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/router/ambiguous_fallback/generated_app/src/Cargo.toml new file mode 100644 index 000000000..493f373e8 --- /dev/null +++ b/compiler/ui_tests/blueprint/router/ambiguous_fallback/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_9fbe7a0c" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_9fbe7a0c" diff --git a/compiler/ui_tests/blueprint/router/ambiguous_fallback/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/router/ambiguous_fallback/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/router/conflicting_any_and_single_method_guards/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/router/conflicting_any_and_single_method_guards/generated_app/Cargo.toml new file mode 100644 index 000000000..86d8191a5 --- /dev/null +++ b/compiler/ui_tests/blueprint/router/conflicting_any_and_single_method_guards/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_6b4ffaf2" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_6b4ffaf2" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/router/conflicting_any_and_single_method_guards/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/router/conflicting_any_and_single_method_guards/generated_app/src/Cargo.toml new file mode 100644 index 000000000..be75dea15 --- /dev/null +++ b/compiler/ui_tests/blueprint/router/conflicting_any_and_single_method_guards/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_6b4ffaf2" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_6b4ffaf2" diff --git a/compiler/ui_tests/blueprint/router/conflicting_any_and_single_method_guards/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/router/conflicting_any_and_single_method_guards/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/router/different_fallback_for_each_method/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/router/different_fallback_for_each_method/generated_app/Cargo.toml new file mode 100644 index 000000000..041a2ad8f --- /dev/null +++ b/compiler/ui_tests/blueprint/router/different_fallback_for_each_method/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_951b7f8d" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_951b7f8d" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/router/different_fallback_for_each_method/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/router/different_fallback_for_each_method/generated_app/src/Cargo.toml new file mode 100644 index 000000000..3846e2e7e --- /dev/null +++ b/compiler/ui_tests/blueprint/router/different_fallback_for_each_method/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_951b7f8d" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_951b7f8d" diff --git a/compiler/ui_tests/blueprint/router/different_fallback_for_each_method/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/router/different_fallback_for_each_method/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/router/domain_conflict/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/router/domain_conflict/generated_app/Cargo.toml new file mode 100644 index 000000000..9872ff740 --- /dev/null +++ b/compiler/ui_tests/blueprint/router/domain_conflict/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_5bd8bb6b" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_5bd8bb6b" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/router/domain_conflict/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/router/domain_conflict/generated_app/src/Cargo.toml new file mode 100644 index 000000000..73be54e86 --- /dev/null +++ b/compiler/ui_tests/blueprint/router/domain_conflict/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_5bd8bb6b" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_5bd8bb6b" diff --git a/compiler/ui_tests/blueprint/router/domain_conflict/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/router/domain_conflict/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/router/domain_is_validated/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/router/domain_is_validated/generated_app/Cargo.toml new file mode 100644 index 000000000..7bd75923f --- /dev/null +++ b/compiler/ui_tests/blueprint/router/domain_is_validated/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_c9d0d698" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_c9d0d698" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/router/domain_is_validated/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/router/domain_is_validated/generated_app/src/Cargo.toml new file mode 100644 index 000000000..936e40c3a --- /dev/null +++ b/compiler/ui_tests/blueprint/router/domain_is_validated/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_c9d0d698" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_c9d0d698" diff --git a/compiler/ui_tests/blueprint/router/domain_is_validated/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/router/domain_is_validated/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/router/domain_routing/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/router/domain_routing/generated_app/Cargo.toml new file mode 100644 index 000000000..cd035d819 --- /dev/null +++ b/compiler/ui_tests/blueprint/router/domain_routing/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_6c2cfd5e" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_6c2cfd5e" + +[dependencies] +app_6c2cfd5e = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/blueprint/router/domain_routing/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/router/domain_routing/generated_app/src/Cargo.toml new file mode 100644 index 000000000..1e1d635d0 --- /dev/null +++ b/compiler/ui_tests/blueprint/router/domain_routing/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_6c2cfd5e" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_6c2cfd5e" diff --git a/compiler/ui_tests/blueprint/router/domain_routing/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/router/domain_routing/generated_app/src/lib.rs new file mode 100644 index 000000000..12ab9f6b5 --- /dev/null +++ b/compiler/ui_tests/blueprint/router/domain_routing/generated_app/src/lib.rs @@ -0,0 +1,550 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + domain_router: matchit::Router, + domain_0: matchit::Router, + domain_1: matchit::Router, + domain_2: matchit::Router, + domain_3: matchit::Router, + domain_4: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { + domain_router: Self::domain_router(), + domain_0: Self::domain_0_router(), + domain_1: Self::domain_1_router(), + domain_2: Self::domain_2_router(), + domain_3: Self::domain_3_router(), + domain_4: Self::domain_4_router(), + } + } + fn domain_router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("moc/ynapmoc/nimda", 0u32).unwrap(); + router.insert("moc/ynapmoc", 1u32).unwrap(); + router.insert("moc/ynapmoc/spo", 2u32).unwrap(); + router.insert("moc/ynapmoc/{sub}/{*any}", 3u32).unwrap(); + router.insert("moc/ynapmoc/{sub}", 4u32).unwrap(); + router + } + fn domain_0_router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + fn domain_1_router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router.insert("/login", 1u32).unwrap(); + router + } + fn domain_2_router() -> matchit::Router { + let router = matchit::Router::new(); + router + } + fn domain_3_router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + fn domain_4_router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + connection_info: Option, + state: &ApplicationState, + ) -> pavex::Response { + let host: Option = request + .headers() + .get(pavex::http::header::HOST) + .map(|h| pavex::http::uri::Authority::try_from(h.as_bytes()).ok()) + .flatten() + .map(|a| { + a.host().trim_end_matches('.').replace('.', "/").chars().rev().collect() + }); + if let Some(host) = host { + if let Ok(m) = self.domain_router.at(host.as_str()) { + return match m.value { + 0u32 => self.route_domain_0(request, connection_info, state).await, + 1u32 => self.route_domain_1(request, connection_info, state).await, + 2u32 => self.route_domain_2(request, connection_info, state).await, + 3u32 => self.route_domain_3(request, connection_info, state).await, + 4u32 => self.route_domain_4(request, connection_info, state).await, + i => unreachable!("Unknown domain id: {}", i), + }; + } + } + let (request_head, request_body) = request.into_parts(); + #[allow(unused)] + let request_body = pavex::request::body::RawIncomingBody::from(request_body); + let request_head: pavex::request::RequestHead = request_head.into(); + route_0::entrypoint(&request_head).await + } + async fn route_domain_0( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.domain_0.at(&request_head.target.path()) else { + return route_7::entrypoint().await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_6::entrypoint().await, + _ => route_7::entrypoint().await, + } + } + i => unreachable!("Unknown route id: {}", i), + } + } + async fn route_domain_1( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.domain_1.at(&request_head.target.path()) else { + return route_0::entrypoint(&request_head).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_4::entrypoint().await, + _ => route_0::entrypoint(&request_head).await, + } + } + 1u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_5::entrypoint().await, + _ => route_0::entrypoint(&request_head).await, + } + } + i => unreachable!("Unknown route id: {}", i), + } + } + async fn route_domain_2( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.domain_2.at(&request_head.target.path()) else { + return route_3::entrypoint().await; + }; + match matched_route.value { + i => unreachable!("Unknown route id: {}", i), + } + } + async fn route_domain_3( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.domain_3.at(&request_head.target.path()) else { + return route_0::entrypoint(&request_head).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => route_0::entrypoint(&request_head).await, + } + } + i => unreachable!("Unknown route id: {}", i), + } + } + async fn route_domain_4( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.domain_4.at(&request_head.target.path()) else { + return route_0::entrypoint(&request_head).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_2::entrypoint().await, + _ => route_0::entrypoint(&request_head).await, + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::request::RequestHead, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::request::RequestHead) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::request::RequestHead) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::request::RequestHead) -> pavex::Response { + let v1 = app_6c2cfd5e::root_fallback(v0); + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::request::RequestHead, + next: fn(&'a pavex::request::RequestHead) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_6c2cfd5e::base_any(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} +pub mod route_2 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_2::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_6c2cfd5e::base_sub(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} +pub mod route_3 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_3::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_6c2cfd5e::ops_fallback(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} +pub mod route_4 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_4::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_6c2cfd5e::base_root(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} +pub mod route_5 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_5::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_6c2cfd5e::base_login(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} +pub mod route_6 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_6::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_6c2cfd5e::admin_root(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} +pub mod route_7 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_7::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_6c2cfd5e::admin_fallback(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/blueprint/router/fallback_priority/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/router/fallback_priority/generated_app/Cargo.toml new file mode 100644 index 000000000..388baf6f9 --- /dev/null +++ b/compiler/ui_tests/blueprint/router/fallback_priority/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_78452ff2" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_78452ff2" + +[dependencies] +app_78452ff2 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/blueprint/router/fallback_priority/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/router/fallback_priority/generated_app/src/Cargo.toml new file mode 100644 index 000000000..e5e85c7ab --- /dev/null +++ b/compiler/ui_tests/blueprint/router/fallback_priority/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_78452ff2" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_78452ff2" diff --git a/compiler/ui_tests/blueprint/router/fallback_priority/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/router/fallback_priority/generated_app/src/lib.rs new file mode 100644 index 000000000..49f8821f7 --- /dev/null +++ b/compiler/ui_tests/blueprint/router/fallback_priority/generated_app/src/lib.rs @@ -0,0 +1,288 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/users/", 0u32).unwrap(); + router.insert("/users/id", 1u32).unwrap(); + router.insert("/users{*catch_all}", 2u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => route_2::entrypoint().await, + } + } + 1u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_3::entrypoint().await, + _ => route_4::entrypoint().await, + } + } + 2u32 => route_2::entrypoint().await, + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_78452ff2::root(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} +pub mod route_2 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_2::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_78452ff2::unauthorized(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} +pub mod route_3 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_3::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_78452ff2::id(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} +pub mod route_4 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_4::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_78452ff2::forbidden(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/blueprint/router/http_method_routing_variants/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/router/http_method_routing_variants/generated_app/Cargo.toml new file mode 100644 index 000000000..edcfb6893 --- /dev/null +++ b/compiler/ui_tests/blueprint/router/http_method_routing_variants/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_a6a2e116" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_a6a2e116" + +[dependencies] +app_a6a2e116 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/blueprint/router/http_method_routing_variants/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/router/http_method_routing_variants/generated_app/src/Cargo.toml new file mode 100644 index 000000000..b92fd3f71 --- /dev/null +++ b/compiler/ui_tests/blueprint/router/http_method_routing_variants/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_a6a2e116" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_a6a2e116" diff --git a/compiler/ui_tests/blueprint/router/http_method_routing_variants/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/router/http_method_routing_variants/generated_app/src/lib.rs new file mode 100644 index 000000000..1f0f1f1f9 --- /dev/null +++ b/compiler/ui_tests/blueprint/router/http_method_routing_variants/generated_app/src/lib.rs @@ -0,0 +1,848 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/any", 0u32).unwrap(); + router.insert("/any_with_extensions", 1u32).unwrap(); + router.insert("/connect", 2u32).unwrap(); + router.insert("/custom", 3u32).unwrap(); + router.insert("/delete", 4u32).unwrap(); + router.insert("/get", 5u32).unwrap(); + router.insert("/head", 6u32).unwrap(); + router.insert("/mixed", 7u32).unwrap(); + router.insert("/mixed_custom", 8u32).unwrap(); + router.insert("/options", 9u32).unwrap(); + router.insert("/patch", 10u32).unwrap(); + router.insert("/post", 11u32).unwrap(); + router.insert("/put", 12u32).unwrap(); + router.insert("/trace", 13u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::CONNECT + | &pavex::http::Method::DELETE + | &pavex::http::Method::GET + | &pavex::http::Method::HEAD + | &pavex::http::Method::OPTIONS + | &pavex::http::Method::PATCH + | &pavex::http::Method::POST + | &pavex::http::Method::PUT + | &pavex::http::Method::TRACE => route_13::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::CONNECT, + pavex::http::Method::DELETE, + pavex::http::Method::GET, + pavex::http::Method::HEAD, + pavex::http::Method::OPTIONS, + pavex::http::Method::PATCH, + pavex::http::Method::POST, + pavex::http::Method::PUT, + pavex::http::Method::TRACE, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + 1u32 => route_14::entrypoint().await, + 2u32 => { + match &request_head.method { + &pavex::http::Method::CONNECT => route_9::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::CONNECT, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + 3u32 => { + match &request_head.method { + s if s.as_str() == "CUSTOM" => route_11::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::try_from("CUSTOM") + .expect("CUSTOM is not a valid (custom) HTTP method"), + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + 4u32 => { + match &request_head.method { + &pavex::http::Method::DELETE => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::DELETE, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + 5u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_2::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + 6u32 => { + match &request_head.method { + &pavex::http::Method::HEAD => route_3::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::HEAD, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + 7u32 => { + match &request_head.method { + &pavex::http::Method::PATCH | &pavex::http::Method::POST => { + route_10::entrypoint().await + } + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::PATCH, + pavex::http::Method::POST, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + 8u32 => { + match &request_head.method { + s if s.as_str() == "CUSTOM" || s.as_str() == "HEY" => { + route_12::entrypoint().await + } + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::try_from("CUSTOM") + .expect("CUSTOM is not a valid (custom) HTTP method"), + pavex::http::Method::try_from("HEY") + .expect("HEY is not a valid (custom) HTTP method"), + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + 9u32 => { + match &request_head.method { + &pavex::http::Method::OPTIONS => route_4::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::OPTIONS, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + 10u32 => { + match &request_head.method { + &pavex::http::Method::PATCH => route_5::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::PATCH, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + 11u32 => { + match &request_head.method { + &pavex::http::Method::POST => route_6::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::POST, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + 12u32 => { + match &request_head.method { + &pavex::http::Method::PUT => route_7::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::PUT, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + 13u32 => { + match &request_head.method { + &pavex::http::Method::TRACE => route_8::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::TRACE, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_a6a2e116::delete(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} +pub mod route_2 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_2::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_a6a2e116::get(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} +pub mod route_3 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_3::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_a6a2e116::head(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} +pub mod route_4 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_4::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_a6a2e116::options(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} +pub mod route_5 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_5::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_a6a2e116::patch(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} +pub mod route_6 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_6::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_a6a2e116::post(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} +pub mod route_7 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_7::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_a6a2e116::put(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} +pub mod route_8 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_8::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_a6a2e116::trace(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} +pub mod route_9 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_9::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_a6a2e116::connect(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} +pub mod route_10 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_10::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_a6a2e116::mixed(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} +pub mod route_11 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_11::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_a6a2e116::custom(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} +pub mod route_12 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_12::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_a6a2e116::mixed_custom(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} +pub mod route_13 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_13::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_a6a2e116::any(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} +pub mod route_14 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_14::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_a6a2e116::any_with_extensions(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/blueprint/router/invalid_paths/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/router/invalid_paths/generated_app/Cargo.toml new file mode 100644 index 000000000..4d6b376fd --- /dev/null +++ b/compiler/ui_tests/blueprint/router/invalid_paths/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_fc852cc3" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_fc852cc3" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/router/invalid_paths/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/router/invalid_paths/generated_app/src/Cargo.toml new file mode 100644 index 000000000..fb851fb9e --- /dev/null +++ b/compiler/ui_tests/blueprint/router/invalid_paths/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_fc852cc3" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_fc852cc3" diff --git a/compiler/ui_tests/blueprint/router/invalid_paths/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/router/invalid_paths/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/router/mixed_domain_and_agnostic_is_forbidden/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/router/mixed_domain_and_agnostic_is_forbidden/generated_app/Cargo.toml new file mode 100644 index 000000000..358949d6f --- /dev/null +++ b/compiler/ui_tests/blueprint/router/mixed_domain_and_agnostic_is_forbidden/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_e09e35a8" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_e09e35a8" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/router/mixed_domain_and_agnostic_is_forbidden/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/router/mixed_domain_and_agnostic_is_forbidden/generated_app/src/Cargo.toml new file mode 100644 index 000000000..d35c20084 --- /dev/null +++ b/compiler/ui_tests/blueprint/router/mixed_domain_and_agnostic_is_forbidden/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_e09e35a8" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_e09e35a8" diff --git a/compiler/ui_tests/blueprint/router/mixed_domain_and_agnostic_is_forbidden/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/router/mixed_domain_and_agnostic_is_forbidden/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/router/path_prefix_is_validated/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/router/path_prefix_is_validated/generated_app/Cargo.toml new file mode 100644 index 000000000..f8630b2bc --- /dev/null +++ b/compiler/ui_tests/blueprint/router/path_prefix_is_validated/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_23cf3c43" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_23cf3c43" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/router/path_prefix_is_validated/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/router/path_prefix_is_validated/generated_app/src/Cargo.toml new file mode 100644 index 000000000..06de1a613 --- /dev/null +++ b/compiler/ui_tests/blueprint/router/path_prefix_is_validated/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_23cf3c43" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_23cf3c43" diff --git a/compiler/ui_tests/blueprint/router/path_prefix_is_validated/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/router/path_prefix_is_validated/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/router/request_handlers_can_take_mut_references/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/router/request_handlers_can_take_mut_references/generated_app/Cargo.toml new file mode 100644 index 000000000..81398c155 --- /dev/null +++ b/compiler/ui_tests/blueprint/router/request_handlers_can_take_mut_references/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_c7a5ef25" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_c7a5ef25" + +[dependencies] +app_c7a5ef25 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/blueprint/router/request_handlers_can_take_mut_references/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/router/request_handlers_can_take_mut_references/generated_app/src/Cargo.toml new file mode 100644 index 000000000..f26d66023 --- /dev/null +++ b/compiler/ui_tests/blueprint/router/request_handlers_can_take_mut_references/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_c7a5ef25" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_c7a5ef25" diff --git a/compiler/ui_tests/blueprint/router/request_handlers_can_take_mut_references/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/router/request_handlers_can_take_mut_references/generated_app/src/lib.rs new file mode 100644 index 000000000..8faad2937 --- /dev/null +++ b/compiler/ui_tests/blueprint/router/request_handlers_can_take_mut_references/generated_app/src/lib.rs @@ -0,0 +1,224 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router.insert("/annotation", 1u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + 1u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_2::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let mut v0 = app_c7a5ef25::build(); + let v1 = app_c7a5ef25::handler(&mut v0); + ::into_response(v1) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} +pub mod route_2 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_2::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let mut v0 = app_c7a5ef25::build(); + let v1 = app_c7a5ef25::handler_ann(&mut v0); + ::into_response(v1) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/blueprint/router/route_path_is_validated/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/router/route_path_is_validated/generated_app/Cargo.toml new file mode 100644 index 000000000..1f5a3a04a --- /dev/null +++ b/compiler/ui_tests/blueprint/router/route_path_is_validated/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_c2e83ed5" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_c2e83ed5" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/router/route_path_is_validated/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/router/route_path_is_validated/generated_app/src/Cargo.toml new file mode 100644 index 000000000..6929af979 --- /dev/null +++ b/compiler/ui_tests/blueprint/router/route_path_is_validated/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_c2e83ed5" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_c2e83ed5" diff --git a/compiler/ui_tests/blueprint/router/route_path_is_validated/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/router/route_path_is_validated/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/wrapping_middlewares/cannot_have_multiple_next_inputs/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/wrapping_middlewares/cannot_have_multiple_next_inputs/generated_app/Cargo.toml new file mode 100644 index 000000000..a6f253fe5 --- /dev/null +++ b/compiler/ui_tests/blueprint/wrapping_middlewares/cannot_have_multiple_next_inputs/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_af31d59e" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_af31d59e" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/wrapping_middlewares/cannot_have_multiple_next_inputs/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/wrapping_middlewares/cannot_have_multiple_next_inputs/generated_app/src/Cargo.toml new file mode 100644 index 000000000..252143b4f --- /dev/null +++ b/compiler/ui_tests/blueprint/wrapping_middlewares/cannot_have_multiple_next_inputs/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_af31d59e" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_af31d59e" diff --git a/compiler/ui_tests/blueprint/wrapping_middlewares/cannot_have_multiple_next_inputs/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/wrapping_middlewares/cannot_have_multiple_next_inputs/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/wrapping_middlewares/must_take_next_as_input/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/wrapping_middlewares/must_take_next_as_input/generated_app/Cargo.toml new file mode 100644 index 000000000..7650966f1 --- /dev/null +++ b/compiler/ui_tests/blueprint/wrapping_middlewares/must_take_next_as_input/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_0cb36ccc" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_0cb36ccc" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/wrapping_middlewares/must_take_next_as_input/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/wrapping_middlewares/must_take_next_as_input/generated_app/src/Cargo.toml new file mode 100644 index 000000000..afd4fa426 --- /dev/null +++ b/compiler/ui_tests/blueprint/wrapping_middlewares/must_take_next_as_input/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_0cb36ccc" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_0cb36ccc" diff --git a/compiler/ui_tests/blueprint/wrapping_middlewares/must_take_next_as_input/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/wrapping_middlewares/must_take_next_as_input/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/wrapping_middlewares/next_must_take_a_naked_generic_parameter/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/wrapping_middlewares/next_must_take_a_naked_generic_parameter/generated_app/Cargo.toml new file mode 100644 index 000000000..3c6866967 --- /dev/null +++ b/compiler/ui_tests/blueprint/wrapping_middlewares/next_must_take_a_naked_generic_parameter/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_3e90eeee" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_3e90eeee" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/wrapping_middlewares/next_must_take_a_naked_generic_parameter/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/wrapping_middlewares/next_must_take_a_naked_generic_parameter/generated_app/src/Cargo.toml new file mode 100644 index 000000000..a78050202 --- /dev/null +++ b/compiler/ui_tests/blueprint/wrapping_middlewares/next_must_take_a_naked_generic_parameter/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_3e90eeee" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_3e90eeee" diff --git a/compiler/ui_tests/blueprint/wrapping_middlewares/next_must_take_a_naked_generic_parameter/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/wrapping_middlewares/next_must_take_a_naked_generic_parameter/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/blueprint/wrapping_middlewares/wrapping_can_fail/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/wrapping_middlewares/wrapping_can_fail/generated_app/Cargo.toml new file mode 100644 index 000000000..6732cf10c --- /dev/null +++ b/compiler/ui_tests/blueprint/wrapping_middlewares/wrapping_can_fail/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_04686649" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_04686649" + +[dependencies] +app_04686649 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/blueprint/wrapping_middlewares/wrapping_can_fail/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/wrapping_middlewares/wrapping_can_fail/generated_app/src/Cargo.toml new file mode 100644 index 000000000..d66de4d99 --- /dev/null +++ b/compiler/ui_tests/blueprint/wrapping_middlewares/wrapping_can_fail/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_04686649" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_04686649" diff --git a/compiler/ui_tests/blueprint/wrapping_middlewares/wrapping_can_fail/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/wrapping_middlewares/wrapping_can_fail/generated_app/src/lib.rs new file mode 100644 index 000000000..391ce9df5 --- /dev/null +++ b/compiler/ui_tests/blueprint/wrapping_middlewares/wrapping_can_fail/generated_app/src/lib.rs @@ -0,0 +1,323 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = wrapping_1(s_0).await; + response + } + async fn stage_2<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = wrapping_2(s_0).await; + response + } + async fn stage_3<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn wrapping_1(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next1 { + s_0: v0, + next: stage_2, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = app_04686649::via_attribute(v2); + let v4 = match v3 { + Ok(ok) => ok, + Err(v4) => { + return { + let v5 = app_04686649::CustomError::into_response(&v4); + ::into_response(v5) + }; + } + }; + ::into_response(v4) + } + async fn wrapping_2(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next2 { + s_0: v0, + next: stage_3, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = app_04686649::override_in_blueprint(v2); + let v4 = match v3 { + Ok(ok) => ok, + Err(v4) => { + return { + let v5 = app_04686649::CustomError::into_response_override(&v4); + ::into_response(v5) + }; + } + }; + ::into_response(v4) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } + struct Next1<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next1<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } + struct Next2<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next2<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = wrapping_1().await; + response + } + async fn stage_2() -> pavex::Response { + let response = wrapping_2().await; + response + } + async fn stage_3() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn wrapping_1() -> pavex::Response { + let v0 = crate::route_1::Next1 { + next: stage_2, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = app_04686649::via_attribute(v1); + let v3 = match v2 { + Ok(ok) => ok, + Err(v3) => { + return { + let v4 = app_04686649::CustomError::into_response(&v3); + ::into_response(v4) + }; + } + }; + ::into_response(v3) + } + async fn wrapping_2() -> pavex::Response { + let v0 = crate::route_1::Next2 { + next: stage_3, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = app_04686649::override_in_blueprint(v1); + let v3 = match v2 { + Ok(ok) => ok, + Err(v3) => { + return { + let v4 = app_04686649::CustomError::into_response_override(&v3); + ::into_response(v4) + }; + } + }; + ::into_response(v3) + } + async fn handler() -> pavex::Response { + let v0 = app_04686649::handler(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } + struct Next1 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next1 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } + struct Next2 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next2 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/blueprint/wrapping_middlewares/wrapping_middlewares_input_parameters_cannot_be_generic/generated_app/Cargo.toml b/compiler/ui_tests/blueprint/wrapping_middlewares/wrapping_middlewares_input_parameters_cannot_be_generic/generated_app/Cargo.toml new file mode 100644 index 000000000..17be1b90b --- /dev/null +++ b/compiler/ui_tests/blueprint/wrapping_middlewares/wrapping_middlewares_input_parameters_cannot_be_generic/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_7479eeb2" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_7479eeb2" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/blueprint/wrapping_middlewares/wrapping_middlewares_input_parameters_cannot_be_generic/generated_app/src/Cargo.toml b/compiler/ui_tests/blueprint/wrapping_middlewares/wrapping_middlewares_input_parameters_cannot_be_generic/generated_app/src/Cargo.toml new file mode 100644 index 000000000..8e233acb8 --- /dev/null +++ b/compiler/ui_tests/blueprint/wrapping_middlewares/wrapping_middlewares_input_parameters_cannot_be_generic/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_7479eeb2" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_7479eeb2" diff --git a/compiler/ui_tests/blueprint/wrapping_middlewares/wrapping_middlewares_input_parameters_cannot_be_generic/generated_app/src/lib.rs b/compiler/ui_tests/blueprint/wrapping_middlewares/wrapping_middlewares_input_parameters_cannot_be_generic/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/borrow_checker/across_middlewares/type_is_cloned_if_consumed_by_wrap_but_needed_by_post/generated_app/Cargo.toml b/compiler/ui_tests/borrow_checker/across_middlewares/type_is_cloned_if_consumed_by_wrap_but_needed_by_post/generated_app/Cargo.toml new file mode 100644 index 000000000..adfa7846d --- /dev/null +++ b/compiler/ui_tests/borrow_checker/across_middlewares/type_is_cloned_if_consumed_by_wrap_but_needed_by_post/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_ffb908fd" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_ffb908fd" + +[dependencies] +app_ffb908fd = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/borrow_checker/across_middlewares/type_is_cloned_if_consumed_by_wrap_but_needed_by_post/generated_app/src/Cargo.toml b/compiler/ui_tests/borrow_checker/across_middlewares/type_is_cloned_if_consumed_by_wrap_but_needed_by_post/generated_app/src/Cargo.toml new file mode 100644 index 000000000..50547d120 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/across_middlewares/type_is_cloned_if_consumed_by_wrap_but_needed_by_post/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_ffb908fd" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_ffb908fd" diff --git a/compiler/ui_tests/borrow_checker/across_middlewares/type_is_cloned_if_consumed_by_wrap_but_needed_by_post/generated_app/src/lib.rs b/compiler/ui_tests/borrow_checker/across_middlewares/type_is_cloned_if_consumed_by_wrap_but_needed_by_post/generated_app/src/lib.rs new file mode 100644 index 000000000..322fa954f --- /dev/null +++ b/compiler/ui_tests/borrow_checker/across_middlewares/type_is_cloned_if_consumed_by_wrap_but_needed_by_post/generated_app/src/lib.rs @@ -0,0 +1,257 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>( + s_0: &'a pavex::router::AllowedMethods, + s_1: app_ffb908fd::A, + ) -> pavex::Response { + let response = wrapping_1(s_1.clone(), s_0).await; + let response = post_processing_0(response, &s_1).await; + response + } + async fn stage_2<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = app_ffb908fd::a(); + let v2 = crate::route_0::Next0 { + s_0: v0, + s_1: v1, + next: stage_1, + }; + let v3 = pavex::middleware::Next::new(v2); + let v4 = pavex::middleware::wrap_noop(v3).await; + ::into_response(v4) + } + async fn wrapping_1( + v0: app_ffb908fd::A, + v1: &pavex::router::AllowedMethods, + ) -> pavex::Response { + let v2 = crate::route_0::Next1 { + s_0: v1, + next: stage_2, + }; + let v3 = pavex::middleware::Next::new(v2); + let v4 = app_ffb908fd::wrap(v3, v0); + ::into_response(v4) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + async fn post_processing_0( + v0: pavex::Response, + v1: &app_ffb908fd::A, + ) -> pavex::Response { + let v2 = app_ffb908fd::post(v0, v1); + ::into_response(v2) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + s_1: app_ffb908fd::A, + next: fn(&'a pavex::router::AllowedMethods, app_ffb908fd::A) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0, self.s_1) + } + } + struct Next1<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next1<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1(s_0: app_ffb908fd::A) -> pavex::Response { + let response = wrapping_1(s_0.clone()).await; + let response = post_processing_0(response, &s_0).await; + response + } + async fn stage_2() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = app_ffb908fd::a(); + let v1 = crate::route_1::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn wrapping_1(v0: app_ffb908fd::A) -> pavex::Response { + let v1 = crate::route_1::Next1 { + next: stage_2, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = app_ffb908fd::wrap(v2, v0); + ::into_response(v3) + } + async fn handler() -> pavex::Response { + let v0 = app_ffb908fd::handler(); + ::into_response(v0) + } + async fn post_processing_0( + v0: pavex::Response, + v1: &app_ffb908fd::A, + ) -> pavex::Response { + let v2 = app_ffb908fd::post(v0, v1); + ::into_response(v2) + } + struct Next0 + where + T: std::future::Future, + { + s_0: app_ffb908fd::A, + next: fn(app_ffb908fd::A) -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } + struct Next1 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next1 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/borrow_checker/across_middlewares/type_is_not_cloned_if_consumed_by_wrap_but_needed_by_post/generated_app/Cargo.toml b/compiler/ui_tests/borrow_checker/across_middlewares/type_is_not_cloned_if_consumed_by_wrap_but_needed_by_post/generated_app/Cargo.toml new file mode 100644 index 000000000..1060d76d9 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/across_middlewares/type_is_not_cloned_if_consumed_by_wrap_but_needed_by_post/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_45abbb8d" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_45abbb8d" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/borrow_checker/across_middlewares/type_is_not_cloned_if_consumed_by_wrap_but_needed_by_post/generated_app/src/Cargo.toml b/compiler/ui_tests/borrow_checker/across_middlewares/type_is_not_cloned_if_consumed_by_wrap_but_needed_by_post/generated_app/src/Cargo.toml new file mode 100644 index 000000000..15ff77291 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/across_middlewares/type_is_not_cloned_if_consumed_by_wrap_but_needed_by_post/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_45abbb8d" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_45abbb8d" diff --git a/compiler/ui_tests/borrow_checker/across_middlewares/type_is_not_cloned_if_consumed_by_wrap_but_needed_by_post/generated_app/src/lib.rs b/compiler/ui_tests/borrow_checker/across_middlewares/type_is_not_cloned_if_consumed_by_wrap_but_needed_by_post/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/borrow_checker/cannot_borrow_cloneable_request_scoped_as_mut/generated_app/Cargo.toml b/compiler/ui_tests/borrow_checker/cannot_borrow_cloneable_request_scoped_as_mut/generated_app/Cargo.toml new file mode 100644 index 000000000..86c8bc7a5 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/cannot_borrow_cloneable_request_scoped_as_mut/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_a564fd27" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_a564fd27" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../workspace_hack" } diff --git a/compiler/ui_tests/borrow_checker/cannot_borrow_cloneable_request_scoped_as_mut/generated_app/src/Cargo.toml b/compiler/ui_tests/borrow_checker/cannot_borrow_cloneable_request_scoped_as_mut/generated_app/src/Cargo.toml new file mode 100644 index 000000000..c513c5fac --- /dev/null +++ b/compiler/ui_tests/borrow_checker/cannot_borrow_cloneable_request_scoped_as_mut/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_a564fd27" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_a564fd27" diff --git a/compiler/ui_tests/borrow_checker/cannot_borrow_cloneable_request_scoped_as_mut/generated_app/src/lib.rs b/compiler/ui_tests/borrow_checker/cannot_borrow_cloneable_request_scoped_as_mut/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/borrow_checker/cannot_borrow_singletons_as_mut/generated_app/Cargo.toml b/compiler/ui_tests/borrow_checker/cannot_borrow_singletons_as_mut/generated_app/Cargo.toml new file mode 100644 index 000000000..b4ee80ceb --- /dev/null +++ b/compiler/ui_tests/borrow_checker/cannot_borrow_singletons_as_mut/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_a7783cd8" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_a7783cd8" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../workspace_hack" } diff --git a/compiler/ui_tests/borrow_checker/cannot_borrow_singletons_as_mut/generated_app/src/Cargo.toml b/compiler/ui_tests/borrow_checker/cannot_borrow_singletons_as_mut/generated_app/src/Cargo.toml new file mode 100644 index 000000000..60cae1ae8 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/cannot_borrow_singletons_as_mut/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_a7783cd8" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_a7783cd8" diff --git a/compiler/ui_tests/borrow_checker/cannot_borrow_singletons_as_mut/generated_app/src/lib.rs b/compiler/ui_tests/borrow_checker/cannot_borrow_singletons_as_mut/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/borrow_checker/cannot_borrow_transients_as_mut/generated_app/Cargo.toml b/compiler/ui_tests/borrow_checker/cannot_borrow_transients_as_mut/generated_app/Cargo.toml new file mode 100644 index 000000000..815eeb742 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/cannot_borrow_transients_as_mut/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_75542b02" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_75542b02" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../workspace_hack" } diff --git a/compiler/ui_tests/borrow_checker/cannot_borrow_transients_as_mut/generated_app/src/Cargo.toml b/compiler/ui_tests/borrow_checker/cannot_borrow_transients_as_mut/generated_app/src/Cargo.toml new file mode 100644 index 000000000..213a24437 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/cannot_borrow_transients_as_mut/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_75542b02" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_75542b02" diff --git a/compiler/ui_tests/borrow_checker/cannot_borrow_transients_as_mut/generated_app/src/lib.rs b/compiler/ui_tests/borrow_checker/cannot_borrow_transients_as_mut/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/borrow_checker/control_flow/multiple_consumers_pass_takes_control_flow_into_account_for_errors/generated_app/Cargo.toml b/compiler/ui_tests/borrow_checker/control_flow/multiple_consumers_pass_takes_control_flow_into_account_for_errors/generated_app/Cargo.toml new file mode 100644 index 000000000..56bc532b7 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/control_flow/multiple_consumers_pass_takes_control_flow_into_account_for_errors/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_23e2eec5" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_23e2eec5" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/borrow_checker/control_flow/multiple_consumers_pass_takes_control_flow_into_account_for_errors/generated_app/src/Cargo.toml b/compiler/ui_tests/borrow_checker/control_flow/multiple_consumers_pass_takes_control_flow_into_account_for_errors/generated_app/src/Cargo.toml new file mode 100644 index 000000000..04b354a0b --- /dev/null +++ b/compiler/ui_tests/borrow_checker/control_flow/multiple_consumers_pass_takes_control_flow_into_account_for_errors/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_23e2eec5" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_23e2eec5" diff --git a/compiler/ui_tests/borrow_checker/control_flow/multiple_consumers_pass_takes_control_flow_into_account_for_errors/generated_app/src/lib.rs b/compiler/ui_tests/borrow_checker/control_flow/multiple_consumers_pass_takes_control_flow_into_account_for_errors/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/borrow_checker/control_flow/you_can_consume_a_non_cloneable_type_from_two_different_control_flow_branches/generated_app/Cargo.toml b/compiler/ui_tests/borrow_checker/control_flow/you_can_consume_a_non_cloneable_type_from_two_different_control_flow_branches/generated_app/Cargo.toml new file mode 100644 index 000000000..659be9729 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/control_flow/you_can_consume_a_non_cloneable_type_from_two_different_control_flow_branches/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_9717f587" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_9717f587" + +[dependencies] +app_9717f587 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/borrow_checker/control_flow/you_can_consume_a_non_cloneable_type_from_two_different_control_flow_branches/generated_app/src/Cargo.toml b/compiler/ui_tests/borrow_checker/control_flow/you_can_consume_a_non_cloneable_type_from_two_different_control_flow_branches/generated_app/src/Cargo.toml new file mode 100644 index 000000000..65175923a --- /dev/null +++ b/compiler/ui_tests/borrow_checker/control_flow/you_can_consume_a_non_cloneable_type_from_two_different_control_flow_branches/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_9717f587" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_9717f587" diff --git a/compiler/ui_tests/borrow_checker/control_flow/you_can_consume_a_non_cloneable_type_from_two_different_control_flow_branches/generated_app/src/lib.rs b/compiler/ui_tests/borrow_checker/control_flow/you_can_consume_a_non_cloneable_type_from_two_different_control_flow_branches/generated_app/src/lib.rs new file mode 100644 index 000000000..485ed902b --- /dev/null +++ b/compiler/ui_tests/borrow_checker/control_flow/you_can_consume_a_non_cloneable_type_from_two_different_control_flow_branches/generated_app/src/lib.rs @@ -0,0 +1,183 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/home", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_9717f587::a(); + let v1 = match v0 { + Ok(ok) => ok, + Err(v1) => { + return { + let v2 = app_9717f587::b(); + let v3 = app_9717f587::error_handler(&v1, v2); + ::into_response(v3) + }; + } + }; + let v2 = app_9717f587::b(); + let v3 = app_9717f587::handler(v1, v2); + ::into_response(v3) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/borrow_checker/diamond/diamond_can_be_solved_if_type_is_copy/generated_app/Cargo.toml b/compiler/ui_tests/borrow_checker/diamond/diamond_can_be_solved_if_type_is_copy/generated_app/Cargo.toml new file mode 100644 index 000000000..83ca351cf --- /dev/null +++ b/compiler/ui_tests/borrow_checker/diamond/diamond_can_be_solved_if_type_is_copy/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_74f21254" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_74f21254" + +[dependencies] +app_74f21254 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/borrow_checker/diamond/diamond_can_be_solved_if_type_is_copy/generated_app/src/Cargo.toml b/compiler/ui_tests/borrow_checker/diamond/diamond_can_be_solved_if_type_is_copy/generated_app/src/Cargo.toml new file mode 100644 index 000000000..76c67baf4 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/diamond/diamond_can_be_solved_if_type_is_copy/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_74f21254" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_74f21254" diff --git a/compiler/ui_tests/borrow_checker/diamond/diamond_can_be_solved_if_type_is_copy/generated_app/src/lib.rs b/compiler/ui_tests/borrow_checker/diamond/diamond_can_be_solved_if_type_is_copy/generated_app/src/lib.rs new file mode 100644 index 000000000..3c4389bbd --- /dev/null +++ b/compiler/ui_tests/borrow_checker/diamond/diamond_can_be_solved_if_type_is_copy/generated_app/src/lib.rs @@ -0,0 +1,175 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/home", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_74f21254::b(); + let v1 = app_74f21254::a(); + let v2 = app_74f21254::d(&v1, v0); + let v3 = app_74f21254::c(v1, &v0); + let v4 = app_74f21254::handler(v3, v2); + ::into_response(v4) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/borrow_checker/diamond/diamond_can_be_solved_if_we_can_clone/generated_app/Cargo.toml b/compiler/ui_tests/borrow_checker/diamond/diamond_can_be_solved_if_we_can_clone/generated_app/Cargo.toml new file mode 100644 index 000000000..1dace0b4b --- /dev/null +++ b/compiler/ui_tests/borrow_checker/diamond/diamond_can_be_solved_if_we_can_clone/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_e8f51606" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_e8f51606" + +[dependencies] +app_e8f51606 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/borrow_checker/diamond/diamond_can_be_solved_if_we_can_clone/generated_app/src/Cargo.toml b/compiler/ui_tests/borrow_checker/diamond/diamond_can_be_solved_if_we_can_clone/generated_app/src/Cargo.toml new file mode 100644 index 000000000..2ae31759c --- /dev/null +++ b/compiler/ui_tests/borrow_checker/diamond/diamond_can_be_solved_if_we_can_clone/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_e8f51606" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_e8f51606" diff --git a/compiler/ui_tests/borrow_checker/diamond/diamond_can_be_solved_if_we_can_clone/generated_app/src/lib.rs b/compiler/ui_tests/borrow_checker/diamond/diamond_can_be_solved_if_we_can_clone/generated_app/src/lib.rs new file mode 100644 index 000000000..64ad4faa9 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/diamond/diamond_can_be_solved_if_we_can_clone/generated_app/src/lib.rs @@ -0,0 +1,176 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/home", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_e8f51606::a(); + let v1 = app_e8f51606::b(); + let v2 = ::clone(&v1); + let v3 = app_e8f51606::d(&v0, v2); + let v4 = app_e8f51606::c(v0, &v1); + let v5 = app_e8f51606::handler(v4, v3); + ::into_response(v5) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/borrow_checker/diamond/diamond_cannot_be_solved_if_we_cannot_clone/generated_app/Cargo.toml b/compiler/ui_tests/borrow_checker/diamond/diamond_cannot_be_solved_if_we_cannot_clone/generated_app/Cargo.toml new file mode 100644 index 000000000..8f69b01dd --- /dev/null +++ b/compiler/ui_tests/borrow_checker/diamond/diamond_cannot_be_solved_if_we_cannot_clone/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_8ce66b53" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_8ce66b53" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/borrow_checker/diamond/diamond_cannot_be_solved_if_we_cannot_clone/generated_app/src/Cargo.toml b/compiler/ui_tests/borrow_checker/diamond/diamond_cannot_be_solved_if_we_cannot_clone/generated_app/src/Cargo.toml new file mode 100644 index 000000000..593ddbbcc --- /dev/null +++ b/compiler/ui_tests/borrow_checker/diamond/diamond_cannot_be_solved_if_we_cannot_clone/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_8ce66b53" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_8ce66b53" diff --git a/compiler/ui_tests/borrow_checker/diamond/diamond_cannot_be_solved_if_we_cannot_clone/generated_app/src/lib.rs b/compiler/ui_tests/borrow_checker/diamond/diamond_cannot_be_solved_if_we_cannot_clone/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/borrow_checker/mixed_mutability/generated_app/Cargo.toml b/compiler/ui_tests/borrow_checker/mixed_mutability/generated_app/Cargo.toml new file mode 100644 index 000000000..a91107fa1 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/mixed_mutability/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_7c2a5f14" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_7c2a5f14" + +[dependencies] +app_7c2a5f14 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/borrow_checker/mixed_mutability/generated_app/src/Cargo.toml b/compiler/ui_tests/borrow_checker/mixed_mutability/generated_app/src/Cargo.toml new file mode 100644 index 000000000..8c7ede12f --- /dev/null +++ b/compiler/ui_tests/borrow_checker/mixed_mutability/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_7c2a5f14" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_7c2a5f14" diff --git a/compiler/ui_tests/borrow_checker/mixed_mutability/generated_app/src/lib.rs b/compiler/ui_tests/borrow_checker/mixed_mutability/generated_app/src/lib.rs new file mode 100644 index 000000000..0f9a3da84 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/mixed_mutability/generated_app/src/lib.rs @@ -0,0 +1,236 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = wrapping_1(s_0).await; + response + } + async fn stage_2<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn wrapping_1(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = app_7c2a5f14::a(); + let v2 = app_7c2a5f14::c(&v1); + let v3 = crate::route_0::Next1 { + s_0: v0, + next: stage_2, + }; + let v4 = pavex::middleware::Next::new(v3); + let v5 = app_7c2a5f14::wrapper(v4, v2); + ::into_response(v5) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } + struct Next1<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next1<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = wrapping_1().await; + response + } + async fn stage_2<'a>(s_0: &'a mut app_7c2a5f14::A) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn wrapping_1() -> pavex::Response { + let mut v0 = app_7c2a5f14::a(); + let v1 = app_7c2a5f14::c(&v0); + let v2 = crate::route_1::Next1 { + s_0: &mut v0, + next: stage_2, + }; + let v3 = pavex::middleware::Next::new(v2); + let v4 = app_7c2a5f14::wrapper(v3, v1); + ::into_response(v4) + } + async fn handler(v0: &mut app_7c2a5f14::A) -> pavex::Response { + let v1 = app_7c2a5f14::b(v0); + let v2 = app_7c2a5f14::handler(v1, v0); + ::into_response(v2) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } + struct Next1<'a, T> + where + T: std::future::Future, + { + s_0: &'a mut app_7c2a5f14::A, + next: fn(&'a mut app_7c2a5f14::A) -> T, + } + impl<'a, T> std::future::IntoFuture for Next1<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} diff --git a/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_framework_type_can_be_moved_twice/generated_app/Cargo.toml b/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_framework_type_can_be_moved_twice/generated_app/Cargo.toml new file mode 100644 index 000000000..82f49791b --- /dev/null +++ b/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_framework_type_can_be_moved_twice/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_bc5c8029" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_bc5c8029" + +[dependencies] +app_bc5c8029 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_framework_type_can_be_moved_twice/generated_app/src/Cargo.toml b/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_framework_type_can_be_moved_twice/generated_app/src/Cargo.toml new file mode 100644 index 000000000..6aa05c134 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_framework_type_can_be_moved_twice/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_bc5c8029" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_bc5c8029" diff --git a/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_framework_type_can_be_moved_twice/generated_app/src/lib.rs b/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_framework_type_can_be_moved_twice/generated_app/src/lib.rs new file mode 100644 index 000000000..42dcadcb4 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_framework_type_can_be_moved_twice/generated_app/src/lib.rs @@ -0,0 +1,190 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/home", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + let url_params: pavex::request::path::RawPathParams<'_, '_> = matched_route + .params + .into(); + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint(url_params).await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint<'a, 'b>( + s_0: pavex::request::path::RawPathParams<'a, 'b>, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a, 'b>( + s_0: pavex::request::path::RawPathParams<'a, 'b>, + ) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0( + v0: pavex::request::path::RawPathParams<'_, '_>, + ) -> pavex::Response { + let v1 = crate::route_1::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler( + v0: pavex::request::path::RawPathParams<'_, '_>, + ) -> pavex::Response { + let v1 = as core::clone::Clone>::clone(&v0); + let v2 = app_bc5c8029::b(v1); + let v3 = app_bc5c8029::c(v0); + let v4 = app_bc5c8029::handler(v2, v3); + ::into_response(v4) + } + struct Next0<'a, 'b, T> + where + T: std::future::Future, + { + s_0: pavex::request::path::RawPathParams<'a, 'b>, + next: fn(pavex::request::path::RawPathParams<'a, 'b>) -> T, + } + impl<'a, 'b, T> std::future::IntoFuture for Next0<'a, 'b, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} diff --git a/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_input_type_can_be_moved_twice/generated_app/Cargo.toml b/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_input_type_can_be_moved_twice/generated_app/Cargo.toml new file mode 100644 index 000000000..c5a087acd --- /dev/null +++ b/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_input_type_can_be_moved_twice/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_a248c801" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_a248c801" + +[dependencies] +app_a248c801 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_input_type_can_be_moved_twice/generated_app/src/Cargo.toml b/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_input_type_can_be_moved_twice/generated_app/src/Cargo.toml new file mode 100644 index 000000000..3ef314db6 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_input_type_can_be_moved_twice/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_a248c801" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_a248c801" diff --git a/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_input_type_can_be_moved_twice/generated_app/src/lib.rs b/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_input_type_can_be_moved_twice/generated_app/src/lib.rs new file mode 100644 index 000000000..c302f658e --- /dev/null +++ b/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_input_type_can_be_moved_twice/generated_app/src/lib.rs @@ -0,0 +1,180 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState { + pub a: app_a248c801::A, +} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + let v0 = app_a248c801::a(); + crate::ApplicationState { a: v0 } + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/home", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => { + route_1::entrypoint(state.a.clone()).await + } + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint(s_0: app_a248c801::A) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1(s_0: app_a248c801::A) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: app_a248c801::A) -> pavex::Response { + let v1 = crate::route_1::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: app_a248c801::A) -> pavex::Response { + let v1 = ::clone(&v0); + let v2 = app_a248c801::b(v1); + let v3 = app_a248c801::c(v0); + let v4 = app_a248c801::handler(v2, v3); + ::into_response(v4) + } + struct Next0 + where + T: std::future::Future, + { + s_0: app_a248c801::A, + next: fn(app_a248c801::A) -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} diff --git a/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_type_can_be_moved_twice/generated_app/Cargo.toml b/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_type_can_be_moved_twice/generated_app/Cargo.toml new file mode 100644 index 000000000..d81f7ec56 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_type_can_be_moved_twice/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_8769849e" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_8769849e" + +[dependencies] +app_8769849e = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_type_can_be_moved_twice/generated_app/src/Cargo.toml b/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_type_can_be_moved_twice/generated_app/src/Cargo.toml new file mode 100644 index 000000000..611e7563e --- /dev/null +++ b/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_type_can_be_moved_twice/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_8769849e" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_8769849e" diff --git a/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_type_can_be_moved_twice/generated_app/src/lib.rs b/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_type_can_be_moved_twice/generated_app/src/lib.rs new file mode 100644 index 000000000..228c435ef --- /dev/null +++ b/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_type_can_be_moved_twice/generated_app/src/lib.rs @@ -0,0 +1,175 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/home", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_8769849e::a(); + let v1 = ::clone(&v0); + let v2 = app_8769849e::b(v1); + let v3 = app_8769849e::c(v0); + let v4 = app_8769849e::handler(v2, v3); + ::into_response(v4) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_type_can_be_moved_twice_when_building_app_state/generated_app/Cargo.toml b/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_type_can_be_moved_twice_when_building_app_state/generated_app/Cargo.toml new file mode 100644 index 000000000..4badd0f48 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_type_can_be_moved_twice_when_building_app_state/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_8cdd5f4a" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_8cdd5f4a" + +[dependencies] +app_8cdd5f4a = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_type_can_be_moved_twice_when_building_app_state/generated_app/src/Cargo.toml b/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_type_can_be_moved_twice_when_building_app_state/generated_app/src/Cargo.toml new file mode 100644 index 000000000..a08ffe667 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_type_can_be_moved_twice_when_building_app_state/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_8cdd5f4a" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_8cdd5f4a" diff --git a/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_type_can_be_moved_twice_when_building_app_state/generated_app/src/lib.rs b/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_type_can_be_moved_twice_when_building_app_state/generated_app/src/lib.rs new file mode 100644 index 000000000..cbb79e892 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/multiple_consumers/a_cloneable_type_can_be_moved_twice_when_building_app_state/generated_app/src/lib.rs @@ -0,0 +1,216 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState { + pub b: app_8cdd5f4a::B, + pub c: app_8cdd5f4a::C, +} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Self::_new().await + } + async fn _new() -> Result { + let v0 = app_8cdd5f4a::a(); + let v1 = match v0 { + Ok(ok) => ok, + Err(v1) => { + return { + let v2 = crate::ApplicationStateError::A(v1); + core::result::Result::Err(v2) + }; + } + }; + let v2 = ::clone(&v1); + let v3 = app_8cdd5f4a::b(v2); + let v4 = app_8cdd5f4a::c(v1); + let v5 = match v4 { + Ok(ok) => ok, + Err(v5) => { + return { + let v6 = crate::ApplicationStateError::C(v5); + core::result::Result::Err(v6) + }; + } + }; + let v6 = crate::ApplicationState { + b: v3, + c: v5, + }; + core::result::Result::Ok(v6) + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError { + #[error(transparent)] + A(pavex::Error), + #[error(transparent)] + C(pavex::Error), +} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => { + route_1::entrypoint(&state.c, &state.b).await + } + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint<'a, 'b>( + s_0: &'a app_8cdd5f4a::C, + s_1: &'b app_8cdd5f4a::B, + ) -> pavex::Response { + let response = wrapping_0(s_0, s_1).await; + response + } + async fn stage_1<'a, 'b>( + s_0: &'a app_8cdd5f4a::C, + s_1: &'b app_8cdd5f4a::B, + ) -> pavex::Response { + let response = handler(s_0, s_1).await; + response + } + async fn wrapping_0(v0: &app_8cdd5f4a::C, v1: &app_8cdd5f4a::B) -> pavex::Response { + let v2 = crate::route_1::Next0 { + s_0: v0, + s_1: v1, + next: stage_1, + }; + let v3 = pavex::middleware::Next::new(v2); + let v4 = pavex::middleware::wrap_noop(v3).await; + ::into_response(v4) + } + async fn handler(v0: &app_8cdd5f4a::C, v1: &app_8cdd5f4a::B) -> pavex::Response { + let v2 = app_8cdd5f4a::handler(v0, v1); + ::into_response(v2) + } + struct Next0<'a, 'b, T> + where + T: std::future::Future, + { + s_0: &'a app_8cdd5f4a::C, + s_1: &'b app_8cdd5f4a::B, + next: fn(&'a app_8cdd5f4a::C, &'b app_8cdd5f4a::B) -> T, + } + impl<'a, 'b, T> std::future::IntoFuture for Next0<'a, 'b, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0, self.s_1) + } + } +} diff --git a/compiler/ui_tests/borrow_checker/multiple_consumers/a_copy_type_can_be_moved_twice/generated_app/Cargo.toml b/compiler/ui_tests/borrow_checker/multiple_consumers/a_copy_type_can_be_moved_twice/generated_app/Cargo.toml new file mode 100644 index 000000000..66e850b9f --- /dev/null +++ b/compiler/ui_tests/borrow_checker/multiple_consumers/a_copy_type_can_be_moved_twice/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_ba0e5d33" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_ba0e5d33" + +[dependencies] +app_ba0e5d33 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/borrow_checker/multiple_consumers/a_copy_type_can_be_moved_twice/generated_app/src/Cargo.toml b/compiler/ui_tests/borrow_checker/multiple_consumers/a_copy_type_can_be_moved_twice/generated_app/src/Cargo.toml new file mode 100644 index 000000000..577276ff1 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/multiple_consumers/a_copy_type_can_be_moved_twice/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_ba0e5d33" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_ba0e5d33" diff --git a/compiler/ui_tests/borrow_checker/multiple_consumers/a_copy_type_can_be_moved_twice/generated_app/src/lib.rs b/compiler/ui_tests/borrow_checker/multiple_consumers/a_copy_type_can_be_moved_twice/generated_app/src/lib.rs new file mode 100644 index 000000000..226a9de2f --- /dev/null +++ b/compiler/ui_tests/borrow_checker/multiple_consumers/a_copy_type_can_be_moved_twice/generated_app/src/lib.rs @@ -0,0 +1,174 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/home", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_ba0e5d33::a(); + let v1 = app_ba0e5d33::c(v0); + let v2 = app_ba0e5d33::b(v0); + let v3 = app_ba0e5d33::handler(v2, v1); + ::into_response(v3) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/borrow_checker/multiple_consumers/a_non_cloneable_framework_type_cannot_be_moved_twice/generated_app/Cargo.toml b/compiler/ui_tests/borrow_checker/multiple_consumers/a_non_cloneable_framework_type_cannot_be_moved_twice/generated_app/Cargo.toml new file mode 100644 index 000000000..b5d328eb6 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/multiple_consumers/a_non_cloneable_framework_type_cannot_be_moved_twice/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_4c40ab7f" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_4c40ab7f" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/borrow_checker/multiple_consumers/a_non_cloneable_framework_type_cannot_be_moved_twice/generated_app/src/Cargo.toml b/compiler/ui_tests/borrow_checker/multiple_consumers/a_non_cloneable_framework_type_cannot_be_moved_twice/generated_app/src/Cargo.toml new file mode 100644 index 000000000..bfb8e35be --- /dev/null +++ b/compiler/ui_tests/borrow_checker/multiple_consumers/a_non_cloneable_framework_type_cannot_be_moved_twice/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_4c40ab7f" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_4c40ab7f" diff --git a/compiler/ui_tests/borrow_checker/multiple_consumers/a_non_cloneable_framework_type_cannot_be_moved_twice/generated_app/src/lib.rs b/compiler/ui_tests/borrow_checker/multiple_consumers/a_non_cloneable_framework_type_cannot_be_moved_twice/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/borrow_checker/multiple_consumers/a_non_cloneable_input_type_cannot_be_moved_twice/generated_app/Cargo.toml b/compiler/ui_tests/borrow_checker/multiple_consumers/a_non_cloneable_input_type_cannot_be_moved_twice/generated_app/Cargo.toml new file mode 100644 index 000000000..6bf0120ca --- /dev/null +++ b/compiler/ui_tests/borrow_checker/multiple_consumers/a_non_cloneable_input_type_cannot_be_moved_twice/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_904b391f" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_904b391f" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/borrow_checker/multiple_consumers/a_non_cloneable_input_type_cannot_be_moved_twice/generated_app/src/Cargo.toml b/compiler/ui_tests/borrow_checker/multiple_consumers/a_non_cloneable_input_type_cannot_be_moved_twice/generated_app/src/Cargo.toml new file mode 100644 index 000000000..26f6c9673 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/multiple_consumers/a_non_cloneable_input_type_cannot_be_moved_twice/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_904b391f" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_904b391f" diff --git a/compiler/ui_tests/borrow_checker/multiple_consumers/a_non_cloneable_input_type_cannot_be_moved_twice/generated_app/src/lib.rs b/compiler/ui_tests/borrow_checker/multiple_consumers/a_non_cloneable_input_type_cannot_be_moved_twice/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/borrow_checker/multiple_consumers/a_non_cloneable_type_cannot_be_moved_twice/generated_app/Cargo.toml b/compiler/ui_tests/borrow_checker/multiple_consumers/a_non_cloneable_type_cannot_be_moved_twice/generated_app/Cargo.toml new file mode 100644 index 000000000..a885ce1b7 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/multiple_consumers/a_non_cloneable_type_cannot_be_moved_twice/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_e609c930" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_e609c930" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/borrow_checker/multiple_consumers/a_non_cloneable_type_cannot_be_moved_twice/generated_app/src/Cargo.toml b/compiler/ui_tests/borrow_checker/multiple_consumers/a_non_cloneable_type_cannot_be_moved_twice/generated_app/src/Cargo.toml new file mode 100644 index 000000000..a822583d0 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/multiple_consumers/a_non_cloneable_type_cannot_be_moved_twice/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_e609c930" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_e609c930" diff --git a/compiler/ui_tests/borrow_checker/multiple_consumers/a_non_cloneable_type_cannot_be_moved_twice/generated_app/src/lib.rs b/compiler/ui_tests/borrow_checker/multiple_consumers/a_non_cloneable_type_cannot_be_moved_twice/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/borrow_checker/multiple_consumers/a_non_cloneable_type_cannot_be_moved_twice_across_stages/generated_app/Cargo.toml b/compiler/ui_tests/borrow_checker/multiple_consumers/a_non_cloneable_type_cannot_be_moved_twice_across_stages/generated_app/Cargo.toml new file mode 100644 index 000000000..a692bbc40 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/multiple_consumers/a_non_cloneable_type_cannot_be_moved_twice_across_stages/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_16375429" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_16375429" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/borrow_checker/multiple_consumers/a_non_cloneable_type_cannot_be_moved_twice_across_stages/generated_app/src/Cargo.toml b/compiler/ui_tests/borrow_checker/multiple_consumers/a_non_cloneable_type_cannot_be_moved_twice_across_stages/generated_app/src/Cargo.toml new file mode 100644 index 000000000..7240b5414 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/multiple_consumers/a_non_cloneable_type_cannot_be_moved_twice_across_stages/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_16375429" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_16375429" diff --git a/compiler/ui_tests/borrow_checker/multiple_consumers/a_non_cloneable_type_cannot_be_moved_twice_across_stages/generated_app/src/lib.rs b/compiler/ui_tests/borrow_checker/multiple_consumers/a_non_cloneable_type_cannot_be_moved_twice_across_stages/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/borrow_checker/mutability/generated_app/Cargo.toml b/compiler/ui_tests/borrow_checker/mutability/generated_app/Cargo.toml new file mode 100644 index 000000000..4171a7576 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/mutability/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_90734139" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_90734139" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../workspace_hack" } diff --git a/compiler/ui_tests/borrow_checker/mutability/generated_app/src/Cargo.toml b/compiler/ui_tests/borrow_checker/mutability/generated_app/src/Cargo.toml new file mode 100644 index 000000000..2b8a968a9 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/mutability/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_90734139" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_90734139" diff --git a/compiler/ui_tests/borrow_checker/mutability/generated_app/src/lib.rs b/compiler/ui_tests/borrow_checker/mutability/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/borrow_checker/transitive_borrows/generated_app/Cargo.toml b/compiler/ui_tests/borrow_checker/transitive_borrows/generated_app/Cargo.toml new file mode 100644 index 000000000..a6260a906 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/transitive_borrows/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_7321b637" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_7321b637" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../workspace_hack" } diff --git a/compiler/ui_tests/borrow_checker/transitive_borrows/generated_app/src/Cargo.toml b/compiler/ui_tests/borrow_checker/transitive_borrows/generated_app/src/Cargo.toml new file mode 100644 index 000000000..5547aba79 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/transitive_borrows/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_7321b637" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_7321b637" diff --git a/compiler/ui_tests/borrow_checker/transitive_borrows/generated_app/src/lib.rs b/compiler/ui_tests/borrow_checker/transitive_borrows/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_framework_type_is_cloneable/generated_app/Cargo.toml b/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_framework_type_is_cloneable/generated_app/Cargo.toml new file mode 100644 index 000000000..1d8a3b42b --- /dev/null +++ b/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_framework_type_is_cloneable/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_2f58149a" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_2f58149a" + +[dependencies] +app_2f58149a = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_framework_type_is_cloneable/generated_app/src/Cargo.toml b/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_framework_type_is_cloneable/generated_app/src/Cargo.toml new file mode 100644 index 000000000..f40b90063 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_framework_type_is_cloneable/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_2f58149a" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_2f58149a" diff --git a/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_framework_type_is_cloneable/generated_app/src/lib.rs b/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_framework_type_is_cloneable/generated_app/src/lib.rs new file mode 100644 index 000000000..027cf0f4a --- /dev/null +++ b/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_framework_type_is_cloneable/generated_app/src/lib.rs @@ -0,0 +1,189 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/home", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + let url_params: pavex::request::path::RawPathParams<'_, '_> = matched_route + .params + .into(); + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint(url_params).await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint<'a, 'b>( + s_0: pavex::request::path::RawPathParams<'a, 'b>, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a, 'b>( + s_0: pavex::request::path::RawPathParams<'a, 'b>, + ) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0( + v0: pavex::request::path::RawPathParams<'_, '_>, + ) -> pavex::Response { + let v1 = crate::route_1::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler( + v0: pavex::request::path::RawPathParams<'_, '_>, + ) -> pavex::Response { + let v1 = as core::clone::Clone>::clone(&v0); + let v2 = app_2f58149a::b(v1); + let v3 = app_2f58149a::handler(&v0, v2); + ::into_response(v3) + } + struct Next0<'a, 'b, T> + where + T: std::future::Future, + { + s_0: pavex::request::path::RawPathParams<'a, 'b>, + next: fn(pavex::request::path::RawPathParams<'a, 'b>) -> T, + } + impl<'a, 'b, T> std::future::IntoFuture for Next0<'a, 'b, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} diff --git a/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_input_type_is_cloneable/generated_app/Cargo.toml b/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_input_type_is_cloneable/generated_app/Cargo.toml new file mode 100644 index 000000000..9bf692bc4 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_input_type_is_cloneable/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_30dedb44" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_30dedb44" + +[dependencies] +app_30dedb44 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_input_type_is_cloneable/generated_app/src/Cargo.toml b/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_input_type_is_cloneable/generated_app/src/Cargo.toml new file mode 100644 index 000000000..74bcf8b08 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_input_type_is_cloneable/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_30dedb44" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_30dedb44" diff --git a/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_input_type_is_cloneable/generated_app/src/lib.rs b/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_input_type_is_cloneable/generated_app/src/lib.rs new file mode 100644 index 000000000..040c51551 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_input_type_is_cloneable/generated_app/src/lib.rs @@ -0,0 +1,179 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState { + pub a: app_30dedb44::A, +} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + let v0 = app_30dedb44::a(); + crate::ApplicationState { a: v0 } + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/home", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => { + route_1::entrypoint(state.a.clone()).await + } + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint(s_0: app_30dedb44::A) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1(s_0: app_30dedb44::A) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: app_30dedb44::A) -> pavex::Response { + let v1 = crate::route_1::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: app_30dedb44::A) -> pavex::Response { + let v1 = ::clone(&v0); + let v2 = app_30dedb44::b(v1); + let v3 = app_30dedb44::handler(&v0, v2); + ::into_response(v3) + } + struct Next0 + where + T: std::future::Future, + { + s_0: app_30dedb44::A, + next: fn(app_30dedb44::A) -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} diff --git a/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_type_is_cloneable/generated_app/Cargo.toml b/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_type_is_cloneable/generated_app/Cargo.toml new file mode 100644 index 000000000..74390d1d7 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_type_is_cloneable/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_a837b935" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_a837b935" + +[dependencies] +app_a837b935 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_type_is_cloneable/generated_app/src/Cargo.toml b/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_type_is_cloneable/generated_app/src/Cargo.toml new file mode 100644 index 000000000..38dbe8504 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_type_is_cloneable/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_a837b935" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_a837b935" diff --git a/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_type_is_cloneable/generated_app/src/lib.rs b/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_type_is_cloneable/generated_app/src/lib.rs new file mode 100644 index 000000000..630ad3ee4 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_type_is_cloneable/generated_app/src/lib.rs @@ -0,0 +1,174 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/home", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_a837b935::a(); + let v1 = ::clone(&v0); + let v2 = app_a837b935::b(v1); + let v3 = app_a837b935::handler(&v0, v2); + ::into_response(v3) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_type_is_copy/generated_app/Cargo.toml b/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_type_is_copy/generated_app/Cargo.toml new file mode 100644 index 000000000..22707852f --- /dev/null +++ b/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_type_is_copy/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_2546f91e" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_2546f91e" + +[dependencies] +app_2546f91e = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_type_is_copy/generated_app/src/Cargo.toml b/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_type_is_copy/generated_app/src/Cargo.toml new file mode 100644 index 000000000..f1ac927a6 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_type_is_copy/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_2546f91e" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_2546f91e" diff --git a/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_type_is_copy/generated_app/src/lib.rs b/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_type_is_copy/generated_app/src/lib.rs new file mode 100644 index 000000000..9821f3082 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/triangle/triangle_can_be_solved_if_type_is_copy/generated_app/src/lib.rs @@ -0,0 +1,173 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/home", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_2546f91e::a(); + let v1 = app_2546f91e::b(v0); + let v2 = app_2546f91e::handler(&v0, v1); + ::into_response(v2) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/borrow_checker/triangle/triangle_cannot_be_solved_if_framework_type_is_not_cloneable/generated_app/Cargo.toml b/compiler/ui_tests/borrow_checker/triangle/triangle_cannot_be_solved_if_framework_type_is_not_cloneable/generated_app/Cargo.toml new file mode 100644 index 000000000..99801a47a --- /dev/null +++ b/compiler/ui_tests/borrow_checker/triangle/triangle_cannot_be_solved_if_framework_type_is_not_cloneable/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_d273f8d0" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_d273f8d0" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/borrow_checker/triangle/triangle_cannot_be_solved_if_framework_type_is_not_cloneable/generated_app/src/Cargo.toml b/compiler/ui_tests/borrow_checker/triangle/triangle_cannot_be_solved_if_framework_type_is_not_cloneable/generated_app/src/Cargo.toml new file mode 100644 index 000000000..41873ef63 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/triangle/triangle_cannot_be_solved_if_framework_type_is_not_cloneable/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_d273f8d0" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_d273f8d0" diff --git a/compiler/ui_tests/borrow_checker/triangle/triangle_cannot_be_solved_if_framework_type_is_not_cloneable/generated_app/src/lib.rs b/compiler/ui_tests/borrow_checker/triangle/triangle_cannot_be_solved_if_framework_type_is_not_cloneable/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/borrow_checker/triangle/triangle_cannot_be_solved_if_input_type_is_not_cloneable/generated_app/Cargo.toml b/compiler/ui_tests/borrow_checker/triangle/triangle_cannot_be_solved_if_input_type_is_not_cloneable/generated_app/Cargo.toml new file mode 100644 index 000000000..ddde779c5 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/triangle/triangle_cannot_be_solved_if_input_type_is_not_cloneable/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_e888f1b9" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_e888f1b9" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/borrow_checker/triangle/triangle_cannot_be_solved_if_input_type_is_not_cloneable/generated_app/src/Cargo.toml b/compiler/ui_tests/borrow_checker/triangle/triangle_cannot_be_solved_if_input_type_is_not_cloneable/generated_app/src/Cargo.toml new file mode 100644 index 000000000..75683e279 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/triangle/triangle_cannot_be_solved_if_input_type_is_not_cloneable/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_e888f1b9" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_e888f1b9" diff --git a/compiler/ui_tests/borrow_checker/triangle/triangle_cannot_be_solved_if_input_type_is_not_cloneable/generated_app/src/lib.rs b/compiler/ui_tests/borrow_checker/triangle/triangle_cannot_be_solved_if_input_type_is_not_cloneable/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/borrow_checker/triangle/triangle_cannot_be_solved_if_type_is_not_cloneable/generated_app/Cargo.toml b/compiler/ui_tests/borrow_checker/triangle/triangle_cannot_be_solved_if_type_is_not_cloneable/generated_app/Cargo.toml new file mode 100644 index 000000000..ecdab5d18 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/triangle/triangle_cannot_be_solved_if_type_is_not_cloneable/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_fe4b5fec" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_fe4b5fec" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/borrow_checker/triangle/triangle_cannot_be_solved_if_type_is_not_cloneable/generated_app/src/Cargo.toml b/compiler/ui_tests/borrow_checker/triangle/triangle_cannot_be_solved_if_type_is_not_cloneable/generated_app/src/Cargo.toml new file mode 100644 index 000000000..fb3af7db4 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/triangle/triangle_cannot_be_solved_if_type_is_not_cloneable/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_fe4b5fec" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_fe4b5fec" diff --git a/compiler/ui_tests/borrow_checker/triangle/triangle_cannot_be_solved_if_type_is_not_cloneable/generated_app/src/lib.rs b/compiler/ui_tests/borrow_checker/triangle/triangle_cannot_be_solved_if_type_is_not_cloneable/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/borrow_checker/triangle/triangle_with_middleware_can_be_solved_if_type_is_cloneable/generated_app/Cargo.toml b/compiler/ui_tests/borrow_checker/triangle/triangle_with_middleware_can_be_solved_if_type_is_cloneable/generated_app/Cargo.toml new file mode 100644 index 000000000..5fbd07548 --- /dev/null +++ b/compiler/ui_tests/borrow_checker/triangle/triangle_with_middleware_can_be_solved_if_type_is_cloneable/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_c4ef979d" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_c4ef979d" + +[dependencies] +app_c4ef979d = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/borrow_checker/triangle/triangle_with_middleware_can_be_solved_if_type_is_cloneable/generated_app/src/Cargo.toml b/compiler/ui_tests/borrow_checker/triangle/triangle_with_middleware_can_be_solved_if_type_is_cloneable/generated_app/src/Cargo.toml new file mode 100644 index 000000000..2a435b2ba --- /dev/null +++ b/compiler/ui_tests/borrow_checker/triangle/triangle_with_middleware_can_be_solved_if_type_is_cloneable/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_c4ef979d" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_c4ef979d" diff --git a/compiler/ui_tests/borrow_checker/triangle/triangle_with_middleware_can_be_solved_if_type_is_cloneable/generated_app/src/lib.rs b/compiler/ui_tests/borrow_checker/triangle/triangle_with_middleware_can_be_solved_if_type_is_cloneable/generated_app/src/lib.rs new file mode 100644 index 000000000..e55a40dfd --- /dev/null +++ b/compiler/ui_tests/borrow_checker/triangle/triangle_with_middleware_can_be_solved_if_type_is_cloneable/generated_app/src/lib.rs @@ -0,0 +1,234 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/home", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = wrapping_1(s_0).await; + response + } + async fn stage_2<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn wrapping_1(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next1 { + s_0: v0, + next: stage_2, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = app_c4ef979d::a(); + let v4 = app_c4ef979d::mw(v3, v2); + ::into_response(v4) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } + struct Next1<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next1<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = wrapping_1().await; + response + } + async fn stage_2<'a>(s_0: &'a app_c4ef979d::A) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn wrapping_1() -> pavex::Response { + let v0 = app_c4ef979d::a(); + let v1 = crate::route_1::Next1 { + s_0: &v0, + next: stage_2, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = ::clone(&v0); + let v4 = app_c4ef979d::mw(v3, v2); + ::into_response(v4) + } + async fn handler(v0: &app_c4ef979d::A) -> pavex::Response { + let v1 = app_c4ef979d::handler(v0); + ::into_response(v1) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } + struct Next1<'a, T> + where + T: std::future::Future, + { + s_0: &'a app_c4ef979d::A, + next: fn(&'a app_c4ef979d::A) -> T, + } + impl<'a, T> std::future::IntoFuture for Next1<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} diff --git a/compiler/ui_tests/connection_info/connection_info_fallback_happy_path/generated_app/Cargo.toml b/compiler/ui_tests/connection_info/connection_info_fallback_happy_path/generated_app/Cargo.toml new file mode 100644 index 000000000..508d83636 --- /dev/null +++ b/compiler/ui_tests/connection_info/connection_info_fallback_happy_path/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_56967fe8" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_56967fe8" + +[dependencies] +app_56967fe8 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/connection_info/connection_info_fallback_happy_path/generated_app/src/Cargo.toml b/compiler/ui_tests/connection_info/connection_info_fallback_happy_path/generated_app/src/Cargo.toml new file mode 100644 index 000000000..2124e2254 --- /dev/null +++ b/compiler/ui_tests/connection_info/connection_info_fallback_happy_path/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_56967fe8" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_56967fe8" diff --git a/compiler/ui_tests/connection_info/connection_info_fallback_happy_path/generated_app/src/lib.rs b/compiler/ui_tests/connection_info/connection_info_fallback_happy_path/generated_app/src/lib.rs new file mode 100644 index 000000000..47858040e --- /dev/null +++ b/compiler/ui_tests/connection_info/connection_info_fallback_happy_path/generated_app/src/lib.rs @@ -0,0 +1,167 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/route", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let connection_info = connection_info + .expect("Required ConnectionInfo is missing"); + return route_0::entrypoint(&connection_info).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let connection_info = connection_info + .expect("Required `ConnectionInfo` is missing"); + route_0::entrypoint(&connection_info).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::connection::ConnectionInfo, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::connection::ConnectionInfo) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::connection::ConnectionInfo) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::connection::ConnectionInfo) -> pavex::Response { + let v1 = app_56967fe8::get_connection_info(v0); + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::connection::ConnectionInfo, + next: fn(&'a pavex::connection::ConnectionInfo) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_56967fe8::root(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/connection_info/connection_info_happy_path/generated_app/Cargo.toml b/compiler/ui_tests/connection_info/connection_info_happy_path/generated_app/Cargo.toml new file mode 100644 index 000000000..86368ddb1 --- /dev/null +++ b/compiler/ui_tests/connection_info/connection_info_happy_path/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_a1f930e1" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_a1f930e1" + +[dependencies] +app_a1f930e1 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/connection_info/connection_info_happy_path/generated_app/src/Cargo.toml b/compiler/ui_tests/connection_info/connection_info_happy_path/generated_app/src/Cargo.toml new file mode 100644 index 000000000..7b12ab260 --- /dev/null +++ b/compiler/ui_tests/connection_info/connection_info_happy_path/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_a1f930e1" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_a1f930e1" diff --git a/compiler/ui_tests/connection_info/connection_info_happy_path/generated_app/src/lib.rs b/compiler/ui_tests/connection_info/connection_info_happy_path/generated_app/src/lib.rs new file mode 100644 index 000000000..b6b075aab --- /dev/null +++ b/compiler/ui_tests/connection_info/connection_info_happy_path/generated_app/src/lib.rs @@ -0,0 +1,179 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => { + let connection_info = connection_info + .expect("Required `ConnectionInfo` is missing"); + route_1::entrypoint(&connection_info).await + } + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::connection::ConnectionInfo, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::connection::ConnectionInfo) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::connection::ConnectionInfo) -> pavex::Response { + let v1 = crate::route_1::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::connection::ConnectionInfo) -> pavex::Response { + let v1 = app_a1f930e1::get_connection_info(v0); + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::connection::ConnectionInfo, + next: fn(&'a pavex::connection::ConnectionInfo) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} diff --git a/compiler/ui_tests/dependency_injection/clone_nodes_are_only_added_where_needed/generated_app/Cargo.toml b/compiler/ui_tests/dependency_injection/clone_nodes_are_only_added_where_needed/generated_app/Cargo.toml new file mode 100644 index 000000000..f33272a30 --- /dev/null +++ b/compiler/ui_tests/dependency_injection/clone_nodes_are_only_added_where_needed/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_366b29bf" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_366b29bf" + +[dependencies] +app_366b29bf = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/dependency_injection/clone_nodes_are_only_added_where_needed/generated_app/src/Cargo.toml b/compiler/ui_tests/dependency_injection/clone_nodes_are_only_added_where_needed/generated_app/src/Cargo.toml new file mode 100644 index 000000000..3e9e536a0 --- /dev/null +++ b/compiler/ui_tests/dependency_injection/clone_nodes_are_only_added_where_needed/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_366b29bf" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_366b29bf" diff --git a/compiler/ui_tests/dependency_injection/clone_nodes_are_only_added_where_needed/generated_app/src/lib.rs b/compiler/ui_tests/dependency_injection/clone_nodes_are_only_added_where_needed/generated_app/src/lib.rs new file mode 100644 index 000000000..6b17f4da7 --- /dev/null +++ b/compiler/ui_tests/dependency_injection/clone_nodes_are_only_added_where_needed/generated_app/src/lib.rs @@ -0,0 +1,253 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState { + pub singleton: app_366b29bf::Singleton, +} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + let v0 = app_366b29bf::Singleton::new(); + crate::ApplicationState { + singleton: v0, + } + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(state.singleton.clone(), &allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => { + route_1::entrypoint(state.singleton.clone()).await + } + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(state.singleton.clone(), &allowed_methods) + .await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: app_366b29bf::Singleton, + s_1: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0, s_1).await; + response + } + async fn stage_1<'a>( + s_0: &'a pavex::router::AllowedMethods, + s_1: app_366b29bf::Singleton, + ) -> pavex::Response { + let response = wrapping_1(s_0, s_1).await; + response + } + async fn stage_2<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0( + v0: app_366b29bf::Singleton, + v1: &pavex::router::AllowedMethods, + ) -> pavex::Response { + let v2 = crate::route_0::Next0 { + s_0: v1, + s_1: v0, + next: stage_1, + }; + let v3 = pavex::middleware::Next::new(v2); + let v4 = pavex::middleware::wrap_noop(v3).await; + ::into_response(v4) + } + async fn wrapping_1( + v0: &pavex::router::AllowedMethods, + v1: app_366b29bf::Singleton, + ) -> pavex::Response { + let v2 = crate::route_0::Next1 { + s_0: v0, + next: stage_2, + }; + let v3 = pavex::middleware::Next::new(v2); + let v4 = app_366b29bf::mw(v1, v3); + ::into_response(v4) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + s_1: app_366b29bf::Singleton, + next: fn(&'a pavex::router::AllowedMethods, app_366b29bf::Singleton) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0, self.s_1) + } + } + struct Next1<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next1<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint(s_0: app_366b29bf::Singleton) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1(s_0: app_366b29bf::Singleton) -> pavex::Response { + let response = wrapping_1(s_0).await; + response + } + async fn stage_2(s_0: app_366b29bf::Singleton) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: app_366b29bf::Singleton) -> pavex::Response { + let v1 = crate::route_1::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn wrapping_1(v0: app_366b29bf::Singleton) -> pavex::Response { + let v1 = ::clone(&v0); + let v2 = crate::route_1::Next1 { + s_0: v0, + next: stage_2, + }; + let v3 = pavex::middleware::Next::new(v2); + let v4 = app_366b29bf::mw(v1, v3); + ::into_response(v4) + } + async fn handler(v0: app_366b29bf::Singleton) -> pavex::Response { + let v1 = app_366b29bf::handler(v0); + ::into_response(v1) + } + struct Next0 + where + T: std::future::Future, + { + s_0: app_366b29bf::Singleton, + next: fn(app_366b29bf::Singleton) -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } + struct Next1 + where + T: std::future::Future, + { + s_0: app_366b29bf::Singleton, + next: fn(app_366b29bf::Singleton) -> T, + } + impl std::future::IntoFuture for Next1 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} diff --git a/compiler/ui_tests/dependency_injection/cycles/cycle_across_a_match_statement/generated_app/Cargo.toml b/compiler/ui_tests/dependency_injection/cycles/cycle_across_a_match_statement/generated_app/Cargo.toml new file mode 100644 index 000000000..7a8b6f447 --- /dev/null +++ b/compiler/ui_tests/dependency_injection/cycles/cycle_across_a_match_statement/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_4bcfa44d" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_4bcfa44d" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/dependency_injection/cycles/cycle_across_a_match_statement/generated_app/src/Cargo.toml b/compiler/ui_tests/dependency_injection/cycles/cycle_across_a_match_statement/generated_app/src/Cargo.toml new file mode 100644 index 000000000..d1ce59336 --- /dev/null +++ b/compiler/ui_tests/dependency_injection/cycles/cycle_across_a_match_statement/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_4bcfa44d" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_4bcfa44d" diff --git a/compiler/ui_tests/dependency_injection/cycles/cycle_across_a_match_statement/generated_app/src/lib.rs b/compiler/ui_tests/dependency_injection/cycles/cycle_across_a_match_statement/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/dependency_injection/cycles/request_scoped_cycles/generated_app/Cargo.toml b/compiler/ui_tests/dependency_injection/cycles/request_scoped_cycles/generated_app/Cargo.toml new file mode 100644 index 000000000..ed5ef53c4 --- /dev/null +++ b/compiler/ui_tests/dependency_injection/cycles/request_scoped_cycles/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_2480aa2b" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_2480aa2b" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/dependency_injection/cycles/request_scoped_cycles/generated_app/src/Cargo.toml b/compiler/ui_tests/dependency_injection/cycles/request_scoped_cycles/generated_app/src/Cargo.toml new file mode 100644 index 000000000..08aecbdc7 --- /dev/null +++ b/compiler/ui_tests/dependency_injection/cycles/request_scoped_cycles/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_2480aa2b" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_2480aa2b" diff --git a/compiler/ui_tests/dependency_injection/cycles/request_scoped_cycles/generated_app/src/lib.rs b/compiler/ui_tests/dependency_injection/cycles/request_scoped_cycles/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/dependency_injection/cycles/transient_cycles/generated_app/Cargo.toml b/compiler/ui_tests/dependency_injection/cycles/transient_cycles/generated_app/Cargo.toml new file mode 100644 index 000000000..2d1cb781e --- /dev/null +++ b/compiler/ui_tests/dependency_injection/cycles/transient_cycles/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_ca08c5dd" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_ca08c5dd" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/dependency_injection/cycles/transient_cycles/generated_app/src/Cargo.toml b/compiler/ui_tests/dependency_injection/cycles/transient_cycles/generated_app/src/Cargo.toml new file mode 100644 index 000000000..e62626119 --- /dev/null +++ b/compiler/ui_tests/dependency_injection/cycles/transient_cycles/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_ca08c5dd" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_ca08c5dd" diff --git a/compiler/ui_tests/dependency_injection/cycles/transient_cycles/generated_app/src/lib.rs b/compiler/ui_tests/dependency_injection/cycles/transient_cycles/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/dependency_injection/downstream_code_needs_both_owned_and_ref_to_same_type/generated_app/Cargo.toml b/compiler/ui_tests/dependency_injection/downstream_code_needs_both_owned_and_ref_to_same_type/generated_app/Cargo.toml new file mode 100644 index 000000000..5ac8c4767 --- /dev/null +++ b/compiler/ui_tests/dependency_injection/downstream_code_needs_both_owned_and_ref_to_same_type/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_40ab089d" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_40ab089d" + +[dependencies] +app_40ab089d = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/dependency_injection/downstream_code_needs_both_owned_and_ref_to_same_type/generated_app/src/Cargo.toml b/compiler/ui_tests/dependency_injection/downstream_code_needs_both_owned_and_ref_to_same_type/generated_app/src/Cargo.toml new file mode 100644 index 000000000..255ebc956 --- /dev/null +++ b/compiler/ui_tests/dependency_injection/downstream_code_needs_both_owned_and_ref_to_same_type/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_40ab089d" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_40ab089d" diff --git a/compiler/ui_tests/dependency_injection/downstream_code_needs_both_owned_and_ref_to_same_type/generated_app/src/lib.rs b/compiler/ui_tests/dependency_injection/downstream_code_needs_both_owned_and_ref_to_same_type/generated_app/src/lib.rs new file mode 100644 index 000000000..322dae1bf --- /dev/null +++ b/compiler/ui_tests/dependency_injection/downstream_code_needs_both_owned_and_ref_to_same_type/generated_app/src/lib.rs @@ -0,0 +1,304 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = wrapping_1(s_0).await; + response + } + async fn stage_2<'a, 'b>( + s_0: &'a pavex::router::AllowedMethods, + s_1: &'b app_40ab089d::Scoped, + ) -> pavex::Response { + let response = wrapping_2(s_0, s_1).await; + response + } + async fn stage_3<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn wrapping_1(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = app_40ab089d::Scoped::new(); + let v2 = crate::route_0::Next1 { + s_0: v0, + s_1: &v1, + next: stage_2, + }; + let v3 = pavex::middleware::Next::new(v2); + let v4 = ::clone(&v1); + let v5 = app_40ab089d::mw(v4, v3); + ::into_response(v5) + } + async fn wrapping_2( + v0: &pavex::router::AllowedMethods, + v1: &app_40ab089d::Scoped, + ) -> pavex::Response { + let v2 = crate::route_0::Next2 { + s_0: v0, + next: stage_3, + }; + let v3 = pavex::middleware::Next::new(v2); + let v4 = app_40ab089d::mw2(v1, v3); + ::into_response(v4) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } + struct Next1<'a, 'b, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + s_1: &'b app_40ab089d::Scoped, + next: fn(&'a pavex::router::AllowedMethods, &'b app_40ab089d::Scoped) -> T, + } + impl<'a, 'b, T> std::future::IntoFuture for Next1<'a, 'b, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0, self.s_1) + } + } + struct Next2<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next2<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = wrapping_1().await; + response + } + async fn stage_2(s_0: app_40ab089d::Scoped) -> pavex::Response { + let response = wrapping_2(s_0).await; + response + } + async fn stage_3(s_0: app_40ab089d::Scoped) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn wrapping_1() -> pavex::Response { + let v0 = app_40ab089d::Scoped::new(); + let v1 = ::clone(&v0); + let v2 = crate::route_1::Next1 { + s_0: v0, + next: stage_2, + }; + let v3 = pavex::middleware::Next::new(v2); + let v4 = app_40ab089d::mw(v1, v3); + ::into_response(v4) + } + async fn wrapping_2(v0: app_40ab089d::Scoped) -> pavex::Response { + let v1 = ::clone(&v0); + let v2 = crate::route_1::Next2 { + s_0: v1, + next: stage_3, + }; + let v3 = pavex::middleware::Next::new(v2); + let v4 = app_40ab089d::mw2(&v0, v3); + ::into_response(v4) + } + async fn handler(v0: app_40ab089d::Scoped) -> pavex::Response { + let v1 = app_40ab089d::handler(v0); + ::into_response(v1) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } + struct Next1 + where + T: std::future::Future, + { + s_0: app_40ab089d::Scoped, + next: fn(app_40ab089d::Scoped) -> T, + } + impl std::future::IntoFuture for Next1 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } + struct Next2 + where + T: std::future::Future, + { + s_0: app_40ab089d::Scoped, + next: fn(app_40ab089d::Scoped) -> T, + } + impl std::future::IntoFuture for Next2 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} diff --git a/compiler/ui_tests/dependency_injection/elided_lifetimes_are_handled/generated_app/Cargo.toml b/compiler/ui_tests/dependency_injection/elided_lifetimes_are_handled/generated_app/Cargo.toml new file mode 100644 index 000000000..7406f407d --- /dev/null +++ b/compiler/ui_tests/dependency_injection/elided_lifetimes_are_handled/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_ddc3d7f1" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_ddc3d7f1" + +[dependencies] +app_ddc3d7f1 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/dependency_injection/elided_lifetimes_are_handled/generated_app/src/Cargo.toml b/compiler/ui_tests/dependency_injection/elided_lifetimes_are_handled/generated_app/src/Cargo.toml new file mode 100644 index 000000000..e667f84e2 --- /dev/null +++ b/compiler/ui_tests/dependency_injection/elided_lifetimes_are_handled/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_ddc3d7f1" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_ddc3d7f1" diff --git a/compiler/ui_tests/dependency_injection/elided_lifetimes_are_handled/generated_app/src/lib.rs b/compiler/ui_tests/dependency_injection/elided_lifetimes_are_handled/generated_app/src/lib.rs new file mode 100644 index 000000000..1e28f074f --- /dev/null +++ b/compiler/ui_tests/dependency_injection/elided_lifetimes_are_handled/generated_app/src/lib.rs @@ -0,0 +1,176 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState { + pub a: app_ddc3d7f1::A, +} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + let v0 = app_ddc3d7f1::A::new(); + crate::ApplicationState { a: v0 } + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint(&state.a).await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint<'a>(s_0: &'a app_ddc3d7f1::A) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a app_ddc3d7f1::A) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &app_ddc3d7f1::A) -> pavex::Response { + let v1 = crate::route_1::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &app_ddc3d7f1::A) -> pavex::Response { + let v1 = app_ddc3d7f1::Generic::new(v0); + let v2 = app_ddc3d7f1::handler(v1); + ::into_response(v2) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a app_ddc3d7f1::A, + next: fn(&'a app_ddc3d7f1::A) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} diff --git a/compiler/ui_tests/dependency_injection/fallbacks_can_access_all_primitives/generated_app/Cargo.toml b/compiler/ui_tests/dependency_injection/fallbacks_can_access_all_primitives/generated_app/Cargo.toml new file mode 100644 index 000000000..1e202e122 --- /dev/null +++ b/compiler/ui_tests/dependency_injection/fallbacks_can_access_all_primitives/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_9d4349b6" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_9d4349b6" + +[dependencies] +app_9d4349b6 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/dependency_injection/fallbacks_can_access_all_primitives/generated_app/src/Cargo.toml b/compiler/ui_tests/dependency_injection/fallbacks_can_access_all_primitives/generated_app/src/Cargo.toml new file mode 100644 index 000000000..dfd8ac4df --- /dev/null +++ b/compiler/ui_tests/dependency_injection/fallbacks_can_access_all_primitives/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_9d4349b6" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_9d4349b6" diff --git a/compiler/ui_tests/dependency_injection/fallbacks_can_access_all_primitives/generated_app/src/lib.rs b/compiler/ui_tests/dependency_injection/fallbacks_can_access_all_primitives/generated_app/src/lib.rs new file mode 100644 index 000000000..dfd1b2170 --- /dev/null +++ b/compiler/ui_tests/dependency_injection/fallbacks_can_access_all_primitives/generated_app/src/lib.rs @@ -0,0 +1,287 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/nested{*catch_all}", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, request_body) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let request_body = pavex::request::body::RawIncomingBody::from(request_body); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let url_params = pavex::request::path::RawPathParams::default(); + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + let matched_route_template = pavex::request::path::MatchedPathPattern::new( + "*", + ); + let connection_info = connection_info + .expect("Required ConnectionInfo is missing"); + return route_0::entrypoint( + &connection_info, + &request_head, + &request_body, + &allowed_methods, + &matched_route_template, + &url_params, + ) + .await; + }; + let url_params: pavex::request::path::RawPathParams<'_, '_> = matched_route + .params + .into(); + match matched_route.value { + 0u32 => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([]) + .into(); + let connection_info = connection_info + .expect("Required `ConnectionInfo` is missing"); + let matched_route_template = pavex::request::path::MatchedPathPattern::new( + "/nested{*catch_all}", + ); + route_1::entrypoint( + &connection_info, + &request_head, + &request_body, + &allowed_methods, + &matched_route_template, + &url_params, + ) + .await + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h>( + s_0: &'a pavex::connection::ConnectionInfo, + s_1: &'b pavex::request::RequestHead, + s_2: &'c pavex::request::body::RawIncomingBody, + s_3: &'d pavex::router::AllowedMethods, + s_4: &'e pavex::request::path::MatchedPathPattern, + s_5: &'h pavex::request::path::RawPathParams<'f, 'g>, + ) -> pavex::Response { + let response = wrapping_0(s_0, s_1, s_2, s_3, s_4, s_5).await; + response + } + async fn stage_1<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h>( + s_0: &'a pavex::connection::ConnectionInfo, + s_1: &'b pavex::request::RequestHead, + s_2: &'c pavex::request::body::RawIncomingBody, + s_3: &'d pavex::router::AllowedMethods, + s_4: &'e pavex::request::path::MatchedPathPattern, + s_5: &'h pavex::request::path::RawPathParams<'f, 'g>, + ) -> pavex::Response { + let response = handler(s_0, s_1, s_2, s_3, s_4, s_5).await; + response + } + async fn wrapping_0( + v0: &pavex::connection::ConnectionInfo, + v1: &pavex::request::RequestHead, + v2: &pavex::request::body::RawIncomingBody, + v3: &pavex::router::AllowedMethods, + v4: &pavex::request::path::MatchedPathPattern, + v5: &pavex::request::path::RawPathParams<'_, '_>, + ) -> pavex::Response { + let v6 = crate::route_0::Next0 { + s_0: v0, + s_1: v1, + s_2: v2, + s_3: v3, + s_4: v4, + s_5: v5, + next: stage_1, + }; + let v7 = pavex::middleware::Next::new(v6); + let v8 = pavex::middleware::wrap_noop(v7).await; + ::into_response(v8) + } + async fn handler( + v0: &pavex::connection::ConnectionInfo, + v1: &pavex::request::RequestHead, + v2: &pavex::request::body::RawIncomingBody, + v3: &pavex::router::AllowedMethods, + v4: &pavex::request::path::MatchedPathPattern, + v5: &pavex::request::path::RawPathParams<'_, '_>, + ) -> pavex::Response { + let v6 = app_9d4349b6::handler(v0, v1, v2, v3, v4, v5); + ::into_response(v6) + } + struct Next0<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, T> + where + T: std::future::Future, + { + s_0: &'a pavex::connection::ConnectionInfo, + s_1: &'b pavex::request::RequestHead, + s_2: &'c pavex::request::body::RawIncomingBody, + s_3: &'d pavex::router::AllowedMethods, + s_4: &'e pavex::request::path::MatchedPathPattern, + s_5: &'h pavex::request::path::RawPathParams<'f, 'g>, + next: fn( + &'a pavex::connection::ConnectionInfo, + &'b pavex::request::RequestHead, + &'c pavex::request::body::RawIncomingBody, + &'d pavex::router::AllowedMethods, + &'e pavex::request::path::MatchedPathPattern, + &'h pavex::request::path::RawPathParams<'f, 'g>, + ) -> T, + } + impl<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, T> std::future::IntoFuture + for Next0<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0, self.s_1, self.s_2, self.s_3, self.s_4, self.s_5) + } + } +} +pub mod route_1 { + pub async fn entrypoint<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h>( + s_0: &'a pavex::connection::ConnectionInfo, + s_1: &'b pavex::request::RequestHead, + s_2: &'c pavex::request::body::RawIncomingBody, + s_3: &'d pavex::router::AllowedMethods, + s_4: &'e pavex::request::path::MatchedPathPattern, + s_5: &'h pavex::request::path::RawPathParams<'f, 'g>, + ) -> pavex::Response { + let response = wrapping_0(s_0, s_1, s_2, s_3, s_4, s_5).await; + response + } + async fn stage_1<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h>( + s_0: &'a pavex::connection::ConnectionInfo, + s_1: &'b pavex::request::RequestHead, + s_2: &'c pavex::request::body::RawIncomingBody, + s_3: &'d pavex::router::AllowedMethods, + s_4: &'e pavex::request::path::MatchedPathPattern, + s_5: &'h pavex::request::path::RawPathParams<'f, 'g>, + ) -> pavex::Response { + let response = handler(s_0, s_1, s_2, s_3, s_4, s_5).await; + response + } + async fn wrapping_0( + v0: &pavex::connection::ConnectionInfo, + v1: &pavex::request::RequestHead, + v2: &pavex::request::body::RawIncomingBody, + v3: &pavex::router::AllowedMethods, + v4: &pavex::request::path::MatchedPathPattern, + v5: &pavex::request::path::RawPathParams<'_, '_>, + ) -> pavex::Response { + let v6 = crate::route_1::Next0 { + s_0: v0, + s_1: v1, + s_2: v2, + s_3: v3, + s_4: v4, + s_5: v5, + next: stage_1, + }; + let v7 = pavex::middleware::Next::new(v6); + let v8 = pavex::middleware::wrap_noop(v7).await; + ::into_response(v8) + } + async fn handler( + v0: &pavex::connection::ConnectionInfo, + v1: &pavex::request::RequestHead, + v2: &pavex::request::body::RawIncomingBody, + v3: &pavex::router::AllowedMethods, + v4: &pavex::request::path::MatchedPathPattern, + v5: &pavex::request::path::RawPathParams<'_, '_>, + ) -> pavex::Response { + let v6 = app_9d4349b6::handler(v0, v1, v2, v3, v4, v5); + ::into_response(v6) + } + struct Next0<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, T> + where + T: std::future::Future, + { + s_0: &'a pavex::connection::ConnectionInfo, + s_1: &'b pavex::request::RequestHead, + s_2: &'c pavex::request::body::RawIncomingBody, + s_3: &'d pavex::router::AllowedMethods, + s_4: &'e pavex::request::path::MatchedPathPattern, + s_5: &'h pavex::request::path::RawPathParams<'f, 'g>, + next: fn( + &'a pavex::connection::ConnectionInfo, + &'b pavex::request::RequestHead, + &'c pavex::request::body::RawIncomingBody, + &'d pavex::router::AllowedMethods, + &'e pavex::request::path::MatchedPathPattern, + &'h pavex::request::path::RawPathParams<'f, 'g>, + ) -> T, + } + impl<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, T> std::future::IntoFuture + for Next0<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0, self.s_1, self.s_2, self.s_3, self.s_4, self.s_5) + } + } +} diff --git a/compiler/ui_tests/dependency_injection/lifecycles/non_static_references_cannot_be_singletons/generated_app/Cargo.toml b/compiler/ui_tests/dependency_injection/lifecycles/non_static_references_cannot_be_singletons/generated_app/Cargo.toml new file mode 100644 index 000000000..49fc522db --- /dev/null +++ b/compiler/ui_tests/dependency_injection/lifecycles/non_static_references_cannot_be_singletons/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_d408236b" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_d408236b" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/dependency_injection/lifecycles/non_static_references_cannot_be_singletons/generated_app/src/Cargo.toml b/compiler/ui_tests/dependency_injection/lifecycles/non_static_references_cannot_be_singletons/generated_app/src/Cargo.toml new file mode 100644 index 000000000..2478a403e --- /dev/null +++ b/compiler/ui_tests/dependency_injection/lifecycles/non_static_references_cannot_be_singletons/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_d408236b" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_d408236b" diff --git a/compiler/ui_tests/dependency_injection/lifecycles/non_static_references_cannot_be_singletons/generated_app/src/lib.rs b/compiler/ui_tests/dependency_injection/lifecycles/non_static_references_cannot_be_singletons/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/dependency_injection/lifecycles/singletons_cannot_depend_on_request_scoped/generated_app/Cargo.toml b/compiler/ui_tests/dependency_injection/lifecycles/singletons_cannot_depend_on_request_scoped/generated_app/Cargo.toml new file mode 100644 index 000000000..4660b1927 --- /dev/null +++ b/compiler/ui_tests/dependency_injection/lifecycles/singletons_cannot_depend_on_request_scoped/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_7c78acb2" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_7c78acb2" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/dependency_injection/lifecycles/singletons_cannot_depend_on_request_scoped/generated_app/src/Cargo.toml b/compiler/ui_tests/dependency_injection/lifecycles/singletons_cannot_depend_on_request_scoped/generated_app/src/Cargo.toml new file mode 100644 index 000000000..9ce4db835 --- /dev/null +++ b/compiler/ui_tests/dependency_injection/lifecycles/singletons_cannot_depend_on_request_scoped/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_7c78acb2" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_7c78acb2" diff --git a/compiler/ui_tests/dependency_injection/lifecycles/singletons_cannot_depend_on_request_scoped/generated_app/src/lib.rs b/compiler/ui_tests/dependency_injection/lifecycles/singletons_cannot_depend_on_request_scoped/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/dependency_injection/lifecycles/singletons_cannot_have_non_static_lifetime_parameters/generated_app/Cargo.toml b/compiler/ui_tests/dependency_injection/lifecycles/singletons_cannot_have_non_static_lifetime_parameters/generated_app/Cargo.toml new file mode 100644 index 000000000..b5af7afea --- /dev/null +++ b/compiler/ui_tests/dependency_injection/lifecycles/singletons_cannot_have_non_static_lifetime_parameters/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_381916a7" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_381916a7" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../../workspace_hack" } diff --git a/compiler/ui_tests/dependency_injection/lifecycles/singletons_cannot_have_non_static_lifetime_parameters/generated_app/src/Cargo.toml b/compiler/ui_tests/dependency_injection/lifecycles/singletons_cannot_have_non_static_lifetime_parameters/generated_app/src/Cargo.toml new file mode 100644 index 000000000..134b7bf8f --- /dev/null +++ b/compiler/ui_tests/dependency_injection/lifecycles/singletons_cannot_have_non_static_lifetime_parameters/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_381916a7" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_381916a7" diff --git a/compiler/ui_tests/dependency_injection/lifecycles/singletons_cannot_have_non_static_lifetime_parameters/generated_app/src/lib.rs b/compiler/ui_tests/dependency_injection/lifecycles/singletons_cannot_have_non_static_lifetime_parameters/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/dependency_injection/missing_handler_dependency/generated_app/Cargo.toml b/compiler/ui_tests/dependency_injection/missing_handler_dependency/generated_app/Cargo.toml new file mode 100644 index 000000000..8f1de7d75 --- /dev/null +++ b/compiler/ui_tests/dependency_injection/missing_handler_dependency/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_ce0a2170" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_ce0a2170" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../workspace_hack" } diff --git a/compiler/ui_tests/dependency_injection/missing_handler_dependency/generated_app/src/Cargo.toml b/compiler/ui_tests/dependency_injection/missing_handler_dependency/generated_app/src/Cargo.toml new file mode 100644 index 000000000..428a337ce --- /dev/null +++ b/compiler/ui_tests/dependency_injection/missing_handler_dependency/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_ce0a2170" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_ce0a2170" diff --git a/compiler/ui_tests/dependency_injection/missing_handler_dependency/generated_app/src/lib.rs b/compiler/ui_tests/dependency_injection/missing_handler_dependency/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/dependency_injection/missing_singleton_dependency/generated_app/Cargo.toml b/compiler/ui_tests/dependency_injection/missing_singleton_dependency/generated_app/Cargo.toml new file mode 100644 index 000000000..5043803ab --- /dev/null +++ b/compiler/ui_tests/dependency_injection/missing_singleton_dependency/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_67306117" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_67306117" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../workspace_hack" } diff --git a/compiler/ui_tests/dependency_injection/missing_singleton_dependency/generated_app/src/Cargo.toml b/compiler/ui_tests/dependency_injection/missing_singleton_dependency/generated_app/src/Cargo.toml new file mode 100644 index 000000000..88825caf1 --- /dev/null +++ b/compiler/ui_tests/dependency_injection/missing_singleton_dependency/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_67306117" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_67306117" diff --git a/compiler/ui_tests/dependency_injection/missing_singleton_dependency/generated_app/src/lib.rs b/compiler/ui_tests/dependency_injection/missing_singleton_dependency/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/dependency_injection/next_state_is_populated_correctly/generated_app/Cargo.toml b/compiler/ui_tests/dependency_injection/next_state_is_populated_correctly/generated_app/Cargo.toml new file mode 100644 index 000000000..938658f5a --- /dev/null +++ b/compiler/ui_tests/dependency_injection/next_state_is_populated_correctly/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_8b5f0867" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_8b5f0867" + +[dependencies] +app_8b5f0867 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/dependency_injection/next_state_is_populated_correctly/generated_app/src/Cargo.toml b/compiler/ui_tests/dependency_injection/next_state_is_populated_correctly/generated_app/src/Cargo.toml new file mode 100644 index 000000000..2ba16ddea --- /dev/null +++ b/compiler/ui_tests/dependency_injection/next_state_is_populated_correctly/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_8b5f0867" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_8b5f0867" diff --git a/compiler/ui_tests/dependency_injection/next_state_is_populated_correctly/generated_app/src/lib.rs b/compiler/ui_tests/dependency_injection/next_state_is_populated_correctly/generated_app/src/lib.rs new file mode 100644 index 000000000..b64f89860 --- /dev/null +++ b/compiler/ui_tests/dependency_injection/next_state_is_populated_correctly/generated_app/src/lib.rs @@ -0,0 +1,274 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState { + pub singleton: app_8b5f0867::Singleton, +} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + let v0 = app_8b5f0867::Singleton::new(); + crate::ApplicationState { + singleton: v0, + } + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&state.singleton, &allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => { + route_1::entrypoint(&state.singleton).await + } + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&state.singleton, &allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a, 'b>( + s_0: &'a app_8b5f0867::Singleton, + s_1: &'b pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0, s_1).await; + response + } + async fn stage_1<'a, 'b>( + s_0: &'a app_8b5f0867::Singleton, + s_1: &'b pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_1(s_0, s_1).await; + response + } + async fn stage_2<'a, 'b>( + s_0: &'a app_8b5f0867::Singleton, + s_1: &'b pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = handler(s_1).await; + let response = post_processing_0(response, s_0).await; + response + } + async fn wrapping_0( + v0: &app_8b5f0867::Singleton, + v1: &pavex::router::AllowedMethods, + ) -> pavex::Response { + let v2 = crate::route_0::Next0 { + s_0: v0, + s_1: v1, + next: stage_1, + }; + let v3 = pavex::middleware::Next::new(v2); + let v4 = pavex::middleware::wrap_noop(v3).await; + ::into_response(v4) + } + async fn wrapping_1( + v0: &app_8b5f0867::Singleton, + v1: &pavex::router::AllowedMethods, + ) -> pavex::Response { + let v2 = crate::route_0::Next1 { + s_0: v0, + s_1: v1, + next: stage_2, + }; + let v3 = pavex::middleware::Next::new(v2); + let v4 = app_8b5f0867::wrap(v3); + ::into_response(v4) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + async fn post_processing_0( + v0: pavex::Response, + v1: &app_8b5f0867::Singleton, + ) -> pavex::Response { + let v2 = app_8b5f0867::request_scoped(v1); + let v3 = app_8b5f0867::post(v0, &v2); + ::into_response(v3) + } + struct Next0<'a, 'b, T> + where + T: std::future::Future, + { + s_0: &'a app_8b5f0867::Singleton, + s_1: &'b pavex::router::AllowedMethods, + next: fn(&'a app_8b5f0867::Singleton, &'b pavex::router::AllowedMethods) -> T, + } + impl<'a, 'b, T> std::future::IntoFuture for Next0<'a, 'b, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0, self.s_1) + } + } + struct Next1<'a, 'b, T> + where + T: std::future::Future, + { + s_0: &'a app_8b5f0867::Singleton, + s_1: &'b pavex::router::AllowedMethods, + next: fn(&'a app_8b5f0867::Singleton, &'b pavex::router::AllowedMethods) -> T, + } + impl<'a, 'b, T> std::future::IntoFuture for Next1<'a, 'b, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0, self.s_1) + } + } +} +pub mod route_1 { + pub async fn entrypoint<'a>(s_0: &'a app_8b5f0867::Singleton) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a app_8b5f0867::Singleton) -> pavex::Response { + let response = wrapping_1(s_0).await; + response + } + async fn stage_2<'a>(s_0: &'a app_8b5f0867::RequestScoped) -> pavex::Response { + let response = handler(s_0).await; + let response = post_processing_0(response, s_0).await; + response + } + async fn wrapping_0(v0: &app_8b5f0867::Singleton) -> pavex::Response { + let v1 = crate::route_1::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn wrapping_1(v0: &app_8b5f0867::Singleton) -> pavex::Response { + let v1 = app_8b5f0867::request_scoped(v0); + let v2 = crate::route_1::Next1 { + s_0: &v1, + next: stage_2, + }; + let v3 = pavex::middleware::Next::new(v2); + let v4 = app_8b5f0867::wrap(v3); + ::into_response(v4) + } + async fn handler(v0: &app_8b5f0867::RequestScoped) -> pavex::Response { + let v1 = app_8b5f0867::handler(v0); + ::into_response(v1) + } + async fn post_processing_0( + v0: pavex::Response, + v1: &app_8b5f0867::RequestScoped, + ) -> pavex::Response { + let v2 = app_8b5f0867::post(v0, v1); + ::into_response(v2) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a app_8b5f0867::Singleton, + next: fn(&'a app_8b5f0867::Singleton) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } + struct Next1<'a, T> + where + T: std::future::Future, + { + s_0: &'a app_8b5f0867::RequestScoped, + next: fn(&'a app_8b5f0867::RequestScoped) -> T, + } + impl<'a, T> std::future::IntoFuture for Next1<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} diff --git a/compiler/ui_tests/dependency_injection/pavex_honors_the_restrictions_on_generics_introduced_by_constructors/generated_app/Cargo.toml b/compiler/ui_tests/dependency_injection/pavex_honors_the_restrictions_on_generics_introduced_by_constructors/generated_app/Cargo.toml new file mode 100644 index 000000000..5df1e2574 --- /dev/null +++ b/compiler/ui_tests/dependency_injection/pavex_honors_the_restrictions_on_generics_introduced_by_constructors/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_f1383503" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_f1383503" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../workspace_hack" } diff --git a/compiler/ui_tests/dependency_injection/pavex_honors_the_restrictions_on_generics_introduced_by_constructors/generated_app/src/Cargo.toml b/compiler/ui_tests/dependency_injection/pavex_honors_the_restrictions_on_generics_introduced_by_constructors/generated_app/src/Cargo.toml new file mode 100644 index 000000000..c790347fe --- /dev/null +++ b/compiler/ui_tests/dependency_injection/pavex_honors_the_restrictions_on_generics_introduced_by_constructors/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_f1383503" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_f1383503" diff --git a/compiler/ui_tests/dependency_injection/pavex_honors_the_restrictions_on_generics_introduced_by_constructors/generated_app/src/lib.rs b/compiler/ui_tests/dependency_injection/pavex_honors_the_restrictions_on_generics_introduced_by_constructors/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/dependency_injection/references_to_constructible_types_are_allowed/generated_app/Cargo.toml b/compiler/ui_tests/dependency_injection/references_to_constructible_types_are_allowed/generated_app/Cargo.toml new file mode 100644 index 000000000..2020e9689 --- /dev/null +++ b/compiler/ui_tests/dependency_injection/references_to_constructible_types_are_allowed/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_c266691d" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_c266691d" + +[dependencies] +app_c266691d = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/dependency_injection/references_to_constructible_types_are_allowed/generated_app/src/Cargo.toml b/compiler/ui_tests/dependency_injection/references_to_constructible_types_are_allowed/generated_app/src/Cargo.toml new file mode 100644 index 000000000..71260c2fc --- /dev/null +++ b/compiler/ui_tests/dependency_injection/references_to_constructible_types_are_allowed/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_c266691d" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_c266691d" diff --git a/compiler/ui_tests/dependency_injection/references_to_constructible_types_are_allowed/generated_app/src/lib.rs b/compiler/ui_tests/dependency_injection/references_to_constructible_types_are_allowed/generated_app/src/lib.rs new file mode 100644 index 000000000..cc3a83754 --- /dev/null +++ b/compiler/ui_tests/dependency_injection/references_to_constructible_types_are_allowed/generated_app/src/lib.rs @@ -0,0 +1,181 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState { + pub singleton: app_c266691d::Singleton, +} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + let v0 = app_c266691d::Singleton::new(); + crate::ApplicationState { + singleton: v0, + } + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/home", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => { + route_1::entrypoint(&state.singleton).await + } + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint<'a>(s_0: &'a app_c266691d::Singleton) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a app_c266691d::Singleton) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &app_c266691d::Singleton) -> pavex::Response { + let v1 = crate::route_1::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &app_c266691d::Singleton) -> pavex::Response { + let v1 = app_c266691d::transient(); + let v2 = app_c266691d::request_scoped(); + let v3 = app_c266691d::stream_file(v0, &v2, &v1); + ::into_response(v3) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a app_c266691d::Singleton, + next: fn(&'a app_c266691d::Singleton) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} diff --git a/compiler/ui_tests/dependency_injection/some_types_cannot_be_constructed/generated_app/Cargo.toml b/compiler/ui_tests/dependency_injection/some_types_cannot_be_constructed/generated_app/Cargo.toml new file mode 100644 index 000000000..7b75bf7a3 --- /dev/null +++ b/compiler/ui_tests/dependency_injection/some_types_cannot_be_constructed/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_d238c5d8" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_d238c5d8" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../workspace_hack" } diff --git a/compiler/ui_tests/dependency_injection/some_types_cannot_be_constructed/generated_app/src/Cargo.toml b/compiler/ui_tests/dependency_injection/some_types_cannot_be_constructed/generated_app/src/Cargo.toml new file mode 100644 index 000000000..760720639 --- /dev/null +++ b/compiler/ui_tests/dependency_injection/some_types_cannot_be_constructed/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_d238c5d8" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_d238c5d8" diff --git a/compiler/ui_tests/dependency_injection/some_types_cannot_be_constructed/generated_app/src/lib.rs b/compiler/ui_tests/dependency_injection/some_types_cannot_be_constructed/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/error_observers/error_observer_cannot_depend_directly_on_fallible_constructors/generated_app/Cargo.toml b/compiler/ui_tests/error_observers/error_observer_cannot_depend_directly_on_fallible_constructors/generated_app/Cargo.toml new file mode 100644 index 000000000..b0cc27dde --- /dev/null +++ b/compiler/ui_tests/error_observers/error_observer_cannot_depend_directly_on_fallible_constructors/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_f6a54ba5" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_f6a54ba5" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../workspace_hack" } diff --git a/compiler/ui_tests/error_observers/error_observer_cannot_depend_directly_on_fallible_constructors/generated_app/src/Cargo.toml b/compiler/ui_tests/error_observers/error_observer_cannot_depend_directly_on_fallible_constructors/generated_app/src/Cargo.toml new file mode 100644 index 000000000..5a0e7dbed --- /dev/null +++ b/compiler/ui_tests/error_observers/error_observer_cannot_depend_directly_on_fallible_constructors/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_f6a54ba5" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_f6a54ba5" diff --git a/compiler/ui_tests/error_observers/error_observer_cannot_depend_directly_on_fallible_constructors/generated_app/src/lib.rs b/compiler/ui_tests/error_observers/error_observer_cannot_depend_directly_on_fallible_constructors/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/error_observers/error_observer_cannot_depend_transitively_on_fallible_constructors/generated_app/Cargo.toml b/compiler/ui_tests/error_observers/error_observer_cannot_depend_transitively_on_fallible_constructors/generated_app/Cargo.toml new file mode 100644 index 000000000..becb83792 --- /dev/null +++ b/compiler/ui_tests/error_observers/error_observer_cannot_depend_transitively_on_fallible_constructors/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_01bbcc3d" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_01bbcc3d" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../workspace_hack" } diff --git a/compiler/ui_tests/error_observers/error_observer_cannot_depend_transitively_on_fallible_constructors/generated_app/src/Cargo.toml b/compiler/ui_tests/error_observers/error_observer_cannot_depend_transitively_on_fallible_constructors/generated_app/src/Cargo.toml new file mode 100644 index 000000000..9771255dc --- /dev/null +++ b/compiler/ui_tests/error_observers/error_observer_cannot_depend_transitively_on_fallible_constructors/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_01bbcc3d" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_01bbcc3d" diff --git a/compiler/ui_tests/error_observers/error_observer_cannot_depend_transitively_on_fallible_constructors/generated_app/src/lib.rs b/compiler/ui_tests/error_observers/error_observer_cannot_depend_transitively_on_fallible_constructors/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/error_observers/error_observer_with_generic_error/generated_app/Cargo.toml b/compiler/ui_tests/error_observers/error_observer_with_generic_error/generated_app/Cargo.toml new file mode 100644 index 000000000..d4c79c29e --- /dev/null +++ b/compiler/ui_tests/error_observers/error_observer_with_generic_error/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_00ed62be" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_00ed62be" + +[dependencies] +app_00ed62be = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/error_observers/error_observer_with_generic_error/generated_app/src/Cargo.toml b/compiler/ui_tests/error_observers/error_observer_with_generic_error/generated_app/src/Cargo.toml new file mode 100644 index 000000000..d033f0877 --- /dev/null +++ b/compiler/ui_tests/error_observers/error_observer_with_generic_error/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_00ed62be" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_00ed62be" diff --git a/compiler/ui_tests/error_observers/error_observer_with_generic_error/generated_app/src/lib.rs b/compiler/ui_tests/error_observers/error_observer_with_generic_error/generated_app/src/lib.rs new file mode 100644 index 000000000..50af9d15c --- /dev/null +++ b/compiler/ui_tests/error_observers/error_observer_with_generic_error/generated_app/src/lib.rs @@ -0,0 +1,183 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/home", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_00ed62be::constructor(); + let v1 = match v0 { + Ok(ok) => ok, + Err(v1) => { + return { + let v2 = app_00ed62be::error_handler(&v1); + let v3 = pavex::Error::new(v1); + app_00ed62be::error_observer(&v3); + ::into_response(v2) + }; + } + }; + let v2 = app_00ed62be::handler(v1); + ::into_response(v2) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/error_observers/error_observers_can_depend_on_fallible_singletons/generated_app/Cargo.toml b/compiler/ui_tests/error_observers/error_observers_can_depend_on_fallible_singletons/generated_app/Cargo.toml new file mode 100644 index 000000000..1b04948cb --- /dev/null +++ b/compiler/ui_tests/error_observers/error_observers_can_depend_on_fallible_singletons/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_028e5d85" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_028e5d85" + +[dependencies] +app_028e5d85 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/error_observers/error_observers_can_depend_on_fallible_singletons/generated_app/src/Cargo.toml b/compiler/ui_tests/error_observers/error_observers_can_depend_on_fallible_singletons/generated_app/src/Cargo.toml new file mode 100644 index 000000000..ac36c422a --- /dev/null +++ b/compiler/ui_tests/error_observers/error_observers_can_depend_on_fallible_singletons/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_028e5d85" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_028e5d85" diff --git a/compiler/ui_tests/error_observers/error_observers_can_depend_on_fallible_singletons/generated_app/src/lib.rs b/compiler/ui_tests/error_observers/error_observers_can_depend_on_fallible_singletons/generated_app/src/lib.rs new file mode 100644 index 000000000..f08671bc5 --- /dev/null +++ b/compiler/ui_tests/error_observers/error_observers_can_depend_on_fallible_singletons/generated_app/src/lib.rs @@ -0,0 +1,200 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState { + pub a: app_028e5d85::A, +} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Self::_new().await + } + async fn _new() -> Result { + let v0 = app_028e5d85::a(); + let v1 = match v0 { + Ok(ok) => ok, + Err(v1) => { + return { + let v2 = crate::ApplicationStateError::A(v1); + core::result::Result::Err(v2) + }; + } + }; + let v2 = crate::ApplicationState { a: v1 }; + core::result::Result::Ok(v2) + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError { + #[error(transparent)] + A(app_028e5d85::AnError), +} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint(&state.a).await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint<'a>(s_0: &'a app_028e5d85::A) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a app_028e5d85::A) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &app_028e5d85::A) -> pavex::Response { + let v1 = crate::route_1::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &app_028e5d85::A) -> pavex::Response { + let v1 = app_028e5d85::b(v0); + let v2 = match v1 { + Ok(ok) => ok, + Err(v2) => { + return { + let v3 = app_028e5d85::error_handler(v0, &v2); + let v4 = pavex::Error::new(v2); + app_028e5d85::error_observer(v0, &v4); + ::into_response(v3) + }; + } + }; + let v3 = app_028e5d85::handler(&v2); + ::into_response(v3) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a app_028e5d85::A, + next: fn(&'a app_028e5d85::A) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} diff --git a/compiler/ui_tests/error_observers/error_observers_happy_path/generated_app/Cargo.toml b/compiler/ui_tests/error_observers/error_observers_happy_path/generated_app/Cargo.toml new file mode 100644 index 000000000..9f90a5a27 --- /dev/null +++ b/compiler/ui_tests/error_observers/error_observers_happy_path/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_0ca8edfa" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_0ca8edfa" + +[dependencies] +app_0ca8edfa = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/error_observers/error_observers_happy_path/generated_app/src/Cargo.toml b/compiler/ui_tests/error_observers/error_observers_happy_path/generated_app/src/Cargo.toml new file mode 100644 index 000000000..502470e05 --- /dev/null +++ b/compiler/ui_tests/error_observers/error_observers_happy_path/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_0ca8edfa" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_0ca8edfa" diff --git a/compiler/ui_tests/error_observers/error_observers_happy_path/generated_app/src/lib.rs b/compiler/ui_tests/error_observers/error_observers_happy_path/generated_app/src/lib.rs new file mode 100644 index 000000000..325aba3e2 --- /dev/null +++ b/compiler/ui_tests/error_observers/error_observers_happy_path/generated_app/src/lib.rs @@ -0,0 +1,187 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/home", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_0ca8edfa::a(); + let v1 = app_0ca8edfa::b(&v0); + let v2 = match v1 { + Ok(ok) => ok, + Err(v2) => { + return { + let v3 = app_0ca8edfa::error_handler(&v0, &v2); + let v4 = pavex::Error::new(v2); + { + app_0ca8edfa::error_observer(&v0, &v4); + app_0ca8edfa::error_observer2(&v4) + }; + ::into_response(v3) + }; + } + }; + let v3 = app_0ca8edfa::handler(&v2); + ::into_response(v3) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/middlewares/middlewares_execution_order/generated_app/Cargo.toml b/compiler/ui_tests/middlewares/middlewares_execution_order/generated_app/Cargo.toml new file mode 100644 index 000000000..662730b39 --- /dev/null +++ b/compiler/ui_tests/middlewares/middlewares_execution_order/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_e628417e" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_e628417e" + +[dependencies] +app_e628417e = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/middlewares/middlewares_execution_order/generated_app/src/Cargo.toml b/compiler/ui_tests/middlewares/middlewares_execution_order/generated_app/src/Cargo.toml new file mode 100644 index 000000000..32fefb8b2 --- /dev/null +++ b/compiler/ui_tests/middlewares/middlewares_execution_order/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_e628417e" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_e628417e" diff --git a/compiler/ui_tests/middlewares/middlewares_execution_order/generated_app/src/lib.rs b/compiler/ui_tests/middlewares/middlewares_execution_order/generated_app/src/lib.rs new file mode 100644 index 000000000..8b583c8c5 --- /dev/null +++ b/compiler/ui_tests/middlewares/middlewares_execution_order/generated_app/src/lib.rs @@ -0,0 +1,810 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState { + pub spy: app_e628417e::Spy, +} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + v0: app_e628417e::Spy, + ) -> Result { + Ok(Self::_new(v0).await) + } + async fn _new(v0: app_e628417e::Spy) -> crate::ApplicationState { + crate::ApplicationState { spy: v0 } + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/after_handler", 0u32).unwrap(); + router.insert("/early_return", 1u32).unwrap(); + router.insert("/failing_pre", 2u32).unwrap(); + router.insert("/nested", 3u32).unwrap(); + router.insert("/top_level", 4u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_4::entrypoint(&state.spy).await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + 1u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_3::entrypoint(&state.spy).await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + 2u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_2::entrypoint(&state.spy).await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + 3u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint(&state.spy).await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + 4u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_5::entrypoint(&state.spy).await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint<'a>(s_0: &'a app_e628417e::Spy) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a app_e628417e::Spy) -> pavex::Response { + let response = wrapping_1(s_0).await; + response + } + async fn stage_2<'a>(s_0: &'a app_e628417e::Spy) -> pavex::Response { + let response = 'incoming: { + if let Some(response) = pre_processing_0(s_0).await.into_response() { + break 'incoming response; + } + wrapping_2(s_0).await + }; + let response = post_processing_1(response, s_0).await; + response + } + async fn stage_3<'a>(s_0: &'a app_e628417e::Spy) -> pavex::Response { + let response = 'incoming: { + if let Some(response) = pre_processing_1(s_0).await.into_response() { + break 'incoming response; + } + handler(s_0).await + }; + let response = post_processing_0(response, s_0).await; + response + } + async fn wrapping_0(v0: &app_e628417e::Spy) -> pavex::Response { + let v1 = crate::route_1::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn wrapping_1(v0: &app_e628417e::Spy) -> pavex::Response { + let v1 = crate::route_1::Next1 { + s_0: v0, + next: stage_2, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = app_e628417e::first(v0, v2).await; + ::into_response(v3) + } + async fn pre_processing_0(v0: &app_e628417e::Spy) -> pavex::middleware::Processing { + app_e628417e::first_pre(v0).await + } + async fn wrapping_2(v0: &app_e628417e::Spy) -> pavex::Response { + let v1 = crate::route_1::Next2 { + s_0: v0, + next: stage_3, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = app_e628417e::second(v0, v2).await; + ::into_response(v3) + } + async fn pre_processing_1(v0: &app_e628417e::Spy) -> pavex::middleware::Processing { + app_e628417e::second_pre(v0).await + } + async fn handler(v0: &app_e628417e::Spy) -> pavex::Response { + let v1 = app_e628417e::nested_handler(v0).await; + ::into_response(v1) + } + async fn post_processing_0( + v0: pavex::Response, + v1: &app_e628417e::Spy, + ) -> pavex::Response { + let v2 = app_e628417e::second_post(v1, v0).await; + ::into_response(v2) + } + async fn post_processing_1( + v0: pavex::Response, + v1: &app_e628417e::Spy, + ) -> pavex::Response { + let v2 = app_e628417e::first_post(v1, v0).await; + ::into_response(v2) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a app_e628417e::Spy, + next: fn(&'a app_e628417e::Spy) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } + struct Next1<'a, T> + where + T: std::future::Future, + { + s_0: &'a app_e628417e::Spy, + next: fn(&'a app_e628417e::Spy) -> T, + } + impl<'a, T> std::future::IntoFuture for Next1<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } + struct Next2<'a, T> + where + T: std::future::Future, + { + s_0: &'a app_e628417e::Spy, + next: fn(&'a app_e628417e::Spy) -> T, + } + impl<'a, T> std::future::IntoFuture for Next2<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_2 { + pub async fn entrypoint<'a>(s_0: &'a app_e628417e::Spy) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a app_e628417e::Spy) -> pavex::Response { + let response = wrapping_1(s_0).await; + response + } + async fn stage_2<'a>(s_0: &'a app_e628417e::Spy) -> pavex::Response { + let response = 'incoming: { + if let Some(response) = pre_processing_0(s_0).await.into_response() { + break 'incoming response; + } + wrapping_2(s_0).await + }; + let response = post_processing_1(response, s_0).await; + response + } + async fn stage_3<'a>(s_0: &'a app_e628417e::Spy) -> pavex::Response { + let response = 'incoming: { + if let Some(response) = pre_processing_1(s_0).await.into_response() { + break 'incoming response; + } + handler(s_0).await + }; + let response = post_processing_0(response, s_0).await; + response + } + async fn wrapping_0(v0: &app_e628417e::Spy) -> pavex::Response { + let v1 = crate::route_2::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn wrapping_1(v0: &app_e628417e::Spy) -> pavex::Response { + let v1 = crate::route_2::Next1 { + s_0: v0, + next: stage_2, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = app_e628417e::first(v0, v2).await; + ::into_response(v3) + } + async fn pre_processing_0(v0: &app_e628417e::Spy) -> pavex::middleware::Processing { + let v1 = app_e628417e::failing_pre_(v0).await; + let v2 = match v1 { + Ok(ok) => ok, + Err(v2) => { + return { + let v3 = app_e628417e::e500(&v2); + let v4 = ::into_response(v3); + pavex::middleware::Processing::EarlyReturn(v4) + }; + } + }; + v2 + } + async fn wrapping_2(v0: &app_e628417e::Spy) -> pavex::Response { + let v1 = crate::route_2::Next2 { + s_0: v0, + next: stage_3, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = app_e628417e::second(v0, v2).await; + ::into_response(v3) + } + async fn pre_processing_1(v0: &app_e628417e::Spy) -> pavex::middleware::Processing { + app_e628417e::second_pre(v0).await + } + async fn handler(v0: &app_e628417e::Spy) -> pavex::Response { + let v1 = app_e628417e::failing_pre_handler(v0).await; + ::into_response(v1) + } + async fn post_processing_0( + v0: pavex::Response, + v1: &app_e628417e::Spy, + ) -> pavex::Response { + let v2 = app_e628417e::second_post(v1, v0).await; + ::into_response(v2) + } + async fn post_processing_1( + v0: pavex::Response, + v1: &app_e628417e::Spy, + ) -> pavex::Response { + let v2 = app_e628417e::first_post(v1, v0).await; + ::into_response(v2) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a app_e628417e::Spy, + next: fn(&'a app_e628417e::Spy) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } + struct Next1<'a, T> + where + T: std::future::Future, + { + s_0: &'a app_e628417e::Spy, + next: fn(&'a app_e628417e::Spy) -> T, + } + impl<'a, T> std::future::IntoFuture for Next1<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } + struct Next2<'a, T> + where + T: std::future::Future, + { + s_0: &'a app_e628417e::Spy, + next: fn(&'a app_e628417e::Spy) -> T, + } + impl<'a, T> std::future::IntoFuture for Next2<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_3 { + pub async fn entrypoint<'a>(s_0: &'a app_e628417e::Spy) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a app_e628417e::Spy) -> pavex::Response { + let response = wrapping_1(s_0).await; + response + } + async fn stage_2<'a>(s_0: &'a app_e628417e::Spy) -> pavex::Response { + let response = 'incoming: { + if let Some(response) = pre_processing_0(s_0).await.into_response() { + break 'incoming response; + } + wrapping_2(s_0).await + }; + let response = post_processing_1(response, s_0).await; + response + } + async fn stage_3<'a>(s_0: &'a app_e628417e::Spy) -> pavex::Response { + let response = 'incoming: { + if let Some(response) = pre_processing_1(s_0).await.into_response() { + break 'incoming response; + } + handler(s_0).await + }; + let response = post_processing_0(response, s_0).await; + response + } + async fn wrapping_0(v0: &app_e628417e::Spy) -> pavex::Response { + let v1 = crate::route_3::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn wrapping_1(v0: &app_e628417e::Spy) -> pavex::Response { + let v1 = crate::route_3::Next1 { + s_0: v0, + next: stage_2, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = app_e628417e::first(v0, v2).await; + ::into_response(v3) + } + async fn pre_processing_0(v0: &app_e628417e::Spy) -> pavex::middleware::Processing { + app_e628417e::early_return_pre(v0).await + } + async fn wrapping_2(v0: &app_e628417e::Spy) -> pavex::Response { + let v1 = crate::route_3::Next2 { + s_0: v0, + next: stage_3, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = app_e628417e::second(v0, v2).await; + ::into_response(v3) + } + async fn pre_processing_1(v0: &app_e628417e::Spy) -> pavex::middleware::Processing { + app_e628417e::second_pre(v0).await + } + async fn handler(v0: &app_e628417e::Spy) -> pavex::Response { + let v1 = app_e628417e::early_return_handler(v0).await; + ::into_response(v1) + } + async fn post_processing_0( + v0: pavex::Response, + v1: &app_e628417e::Spy, + ) -> pavex::Response { + let v2 = app_e628417e::second_post(v1, v0).await; + ::into_response(v2) + } + async fn post_processing_1( + v0: pavex::Response, + v1: &app_e628417e::Spy, + ) -> pavex::Response { + let v2 = app_e628417e::first_post(v1, v0).await; + ::into_response(v2) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a app_e628417e::Spy, + next: fn(&'a app_e628417e::Spy) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } + struct Next1<'a, T> + where + T: std::future::Future, + { + s_0: &'a app_e628417e::Spy, + next: fn(&'a app_e628417e::Spy) -> T, + } + impl<'a, T> std::future::IntoFuture for Next1<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } + struct Next2<'a, T> + where + T: std::future::Future, + { + s_0: &'a app_e628417e::Spy, + next: fn(&'a app_e628417e::Spy) -> T, + } + impl<'a, T> std::future::IntoFuture for Next2<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_4 { + pub async fn entrypoint<'a>(s_0: &'a app_e628417e::Spy) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a app_e628417e::Spy) -> pavex::Response { + let response = wrapping_1(s_0).await; + response + } + async fn stage_2<'a>(s_0: &'a app_e628417e::Spy) -> pavex::Response { + let response = 'incoming: { + if let Some(response) = pre_processing_0(s_0).await.into_response() { + break 'incoming response; + } + handler(s_0).await + }; + let response = post_processing_0(response, s_0).await; + response + } + async fn wrapping_0(v0: &app_e628417e::Spy) -> pavex::Response { + let v1 = crate::route_4::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn wrapping_1(v0: &app_e628417e::Spy) -> pavex::Response { + let v1 = crate::route_4::Next1 { + s_0: v0, + next: stage_2, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = app_e628417e::first(v0, v2).await; + ::into_response(v3) + } + async fn pre_processing_0(v0: &app_e628417e::Spy) -> pavex::middleware::Processing { + app_e628417e::first_pre(v0).await + } + async fn handler(v0: &app_e628417e::Spy) -> pavex::Response { + let v1 = app_e628417e::after_handler_handler(v0).await; + ::into_response(v1) + } + async fn post_processing_0( + v0: pavex::Response, + v1: &app_e628417e::Spy, + ) -> pavex::Response { + let v2 = app_e628417e::first_post(v1, v0).await; + ::into_response(v2) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a app_e628417e::Spy, + next: fn(&'a app_e628417e::Spy) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } + struct Next1<'a, T> + where + T: std::future::Future, + { + s_0: &'a app_e628417e::Spy, + next: fn(&'a app_e628417e::Spy) -> T, + } + impl<'a, T> std::future::IntoFuture for Next1<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_5 { + pub async fn entrypoint<'a>(s_0: &'a app_e628417e::Spy) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a app_e628417e::Spy) -> pavex::Response { + let response = wrapping_1(s_0).await; + response + } + async fn stage_2<'a>(s_0: &'a app_e628417e::Spy) -> pavex::Response { + let response = wrapping_2(s_0).await; + response + } + async fn stage_3<'a>(s_0: &'a app_e628417e::Spy) -> pavex::Response { + let response = 'incoming: { + if let Some(response) = pre_processing_0(s_0).await.into_response() { + break 'incoming response; + } + if let Some(response) = pre_processing_1(s_0).await.into_response() { + break 'incoming response; + } + handler(s_0).await + }; + let response = post_processing_0(response, s_0).await; + let response = post_processing_1(response, s_0).await; + response + } + async fn wrapping_0(v0: &app_e628417e::Spy) -> pavex::Response { + let v1 = crate::route_5::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn wrapping_1(v0: &app_e628417e::Spy) -> pavex::Response { + let v1 = crate::route_5::Next1 { + s_0: v0, + next: stage_2, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = app_e628417e::first(v0, v2).await; + ::into_response(v3) + } + async fn wrapping_2(v0: &app_e628417e::Spy) -> pavex::Response { + let v1 = crate::route_5::Next2 { + s_0: v0, + next: stage_3, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = app_e628417e::second(v0, v2).await; + ::into_response(v3) + } + async fn pre_processing_0(v0: &app_e628417e::Spy) -> pavex::middleware::Processing { + app_e628417e::first_pre(v0).await + } + async fn pre_processing_1(v0: &app_e628417e::Spy) -> pavex::middleware::Processing { + app_e628417e::second_pre(v0).await + } + async fn handler(v0: &app_e628417e::Spy) -> pavex::Response { + let v1 = app_e628417e::top_level_handler(v0).await; + ::into_response(v1) + } + async fn post_processing_0( + v0: pavex::Response, + v1: &app_e628417e::Spy, + ) -> pavex::Response { + let v2 = app_e628417e::first_post(v1, v0).await; + ::into_response(v2) + } + async fn post_processing_1( + v0: pavex::Response, + v1: &app_e628417e::Spy, + ) -> pavex::Response { + let v2 = app_e628417e::second_post(v1, v0).await; + ::into_response(v2) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a app_e628417e::Spy, + next: fn(&'a app_e628417e::Spy) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } + struct Next1<'a, T> + where + T: std::future::Future, + { + s_0: &'a app_e628417e::Spy, + next: fn(&'a app_e628417e::Spy) -> T, + } + impl<'a, T> std::future::IntoFuture for Next1<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } + struct Next2<'a, T> + where + T: std::future::Future, + { + s_0: &'a app_e628417e::Spy, + next: fn(&'a app_e628417e::Spy) -> T, + } + impl<'a, T> std::future::IntoFuture for Next2<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} diff --git a/compiler/ui_tests/middlewares/middlewares_execution_order/src/lib.rs b/compiler/ui_tests/middlewares/middlewares_execution_order/src/lib.rs index 84c140db4..6dabf1110 100644 --- a/compiler/ui_tests/middlewares/middlewares_execution_order/src/lib.rs +++ b/compiler/ui_tests/middlewares/middlewares_execution_order/src/lib.rs @@ -181,7 +181,7 @@ pub async fn early_return_pre(spy: &Spy) -> pavex::middleware::Processing { pavex::middleware::Processing::EarlyReturn(Response::ok()) } -#[pavex::pre_process] +#[pavex::pre_process(id = "FAILING_PRE")] pub async fn failing_pre_(spy: &Spy) -> Result { spy.push("failing_pre".to_string()).await; Err(pavex::Error::new("failing_pre")) diff --git a/compiler/ui_tests/middlewares/next_handles_lifetimes/generated_app/Cargo.toml b/compiler/ui_tests/middlewares/next_handles_lifetimes/generated_app/Cargo.toml new file mode 100644 index 000000000..e44714138 --- /dev/null +++ b/compiler/ui_tests/middlewares/next_handles_lifetimes/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_dc1710a5" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_dc1710a5" + +[dependencies] +app_dc1710a5 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/middlewares/next_handles_lifetimes/generated_app/src/Cargo.toml b/compiler/ui_tests/middlewares/next_handles_lifetimes/generated_app/src/Cargo.toml new file mode 100644 index 000000000..ae23723b4 --- /dev/null +++ b/compiler/ui_tests/middlewares/next_handles_lifetimes/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_dc1710a5" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_dc1710a5" diff --git a/compiler/ui_tests/middlewares/next_handles_lifetimes/generated_app/src/lib.rs b/compiler/ui_tests/middlewares/next_handles_lifetimes/generated_app/src/lib.rs new file mode 100644 index 000000000..e60d7ec4d --- /dev/null +++ b/compiler/ui_tests/middlewares/next_handles_lifetimes/generated_app/src/lib.rs @@ -0,0 +1,242 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/home", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = wrapping_1(s_0).await; + response + } + async fn stage_2<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn wrapping_1(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = app_dc1710a5::c(); + let v2 = app_dc1710a5::a(); + let v3 = app_dc1710a5::b(&v2, &v1); + let v4 = crate::route_0::Next1 { + s_0: v0, + next: stage_2, + }; + let v5 = pavex::middleware::Next::new(v4); + let v6 = app_dc1710a5::mw(v5, v3); + ::into_response(v6) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } + struct Next1<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next1<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = wrapping_1().await; + response + } + async fn stage_2<'a, 'b>( + s_0: &'a app_dc1710a5::A, + s_1: &'b app_dc1710a5::C, + ) -> pavex::Response { + let response = handler(s_0, s_1).await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn wrapping_1() -> pavex::Response { + let v0 = app_dc1710a5::c(); + let v1 = app_dc1710a5::a(); + let v2 = app_dc1710a5::b(&v1, &v0); + let v3 = crate::route_1::Next1 { + s_0: &v1, + s_1: &v0, + next: stage_2, + }; + let v4 = pavex::middleware::Next::new(v3); + let v5 = app_dc1710a5::mw(v4, v2); + ::into_response(v5) + } + async fn handler(v0: &app_dc1710a5::A, v1: &app_dc1710a5::C) -> pavex::Response { + let v2 = app_dc1710a5::handler(v0, v1); + ::into_response(v2) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } + struct Next1<'a, 'b, T> + where + T: std::future::Future, + { + s_0: &'a app_dc1710a5::A, + s_1: &'b app_dc1710a5::C, + next: fn(&'a app_dc1710a5::A, &'b app_dc1710a5::C) -> T, + } + impl<'a, 'b, T> std::future::IntoFuture for Next1<'a, 'b, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0, self.s_1) + } + } +} diff --git a/compiler/ui_tests/middlewares/next_handles_mut_references/generated_app/Cargo.toml b/compiler/ui_tests/middlewares/next_handles_mut_references/generated_app/Cargo.toml new file mode 100644 index 000000000..838ed1e51 --- /dev/null +++ b/compiler/ui_tests/middlewares/next_handles_mut_references/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_db1cbdff" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_db1cbdff" + +[dependencies] +app_db1cbdff = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/middlewares/next_handles_mut_references/generated_app/src/Cargo.toml b/compiler/ui_tests/middlewares/next_handles_mut_references/generated_app/src/Cargo.toml new file mode 100644 index 000000000..05710286a --- /dev/null +++ b/compiler/ui_tests/middlewares/next_handles_mut_references/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_db1cbdff" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_db1cbdff" diff --git a/compiler/ui_tests/middlewares/next_handles_mut_references/generated_app/src/lib.rs b/compiler/ui_tests/middlewares/next_handles_mut_references/generated_app/src/lib.rs new file mode 100644 index 000000000..89024bf7a --- /dev/null +++ b/compiler/ui_tests/middlewares/next_handles_mut_references/generated_app/src/lib.rs @@ -0,0 +1,248 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/home", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = wrapping_1(s_0).await; + let response = post_processing_0(response).await; + response + } + async fn stage_2<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn wrapping_1(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next1 { + s_0: v0, + next: stage_2, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = app_db1cbdff::mw(v2); + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + async fn post_processing_0(v0: pavex::Response) -> pavex::Response { + let v1 = app_db1cbdff::a(); + let v2 = app_db1cbdff::post(v1, v0); + ::into_response(v2) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } + struct Next1<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next1<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1(mut s_0: app_db1cbdff::A) -> pavex::Response { + let response = wrapping_1(&mut s_0).await; + let response = post_processing_0(response, s_0).await; + response + } + async fn stage_2<'a>(s_0: &'a mut app_db1cbdff::A) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = app_db1cbdff::a(); + let v1 = crate::route_1::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn wrapping_1(v0: &mut app_db1cbdff::A) -> pavex::Response { + let v1 = crate::route_1::Next1 { + s_0: v0, + next: stage_2, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = app_db1cbdff::mw(v2); + ::into_response(v3) + } + async fn handler(v0: &mut app_db1cbdff::A) -> pavex::Response { + let v1 = app_db1cbdff::handler(v0); + ::into_response(v1) + } + async fn post_processing_0( + v0: pavex::Response, + v1: app_db1cbdff::A, + ) -> pavex::Response { + let v2 = app_db1cbdff::post(v1, v0); + ::into_response(v2) + } + struct Next0 + where + T: std::future::Future, + { + s_0: app_db1cbdff::A, + next: fn(app_db1cbdff::A) -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } + struct Next1<'a, T> + where + T: std::future::Future, + { + s_0: &'a mut app_db1cbdff::A, + next: fn(&'a mut app_db1cbdff::A) -> T, + } + impl<'a, T> std::future::IntoFuture for Next1<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} diff --git a/compiler/ui_tests/middlewares/request_scoped_state_is_shared_correctly_among_middlewares/generated_app/Cargo.toml b/compiler/ui_tests/middlewares/request_scoped_state_is_shared_correctly_among_middlewares/generated_app/Cargo.toml new file mode 100644 index 000000000..bd416cbcf --- /dev/null +++ b/compiler/ui_tests/middlewares/request_scoped_state_is_shared_correctly_among_middlewares/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_4b6f5359" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_4b6f5359" + +[dependencies] +app_4b6f5359 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/middlewares/request_scoped_state_is_shared_correctly_among_middlewares/generated_app/src/Cargo.toml b/compiler/ui_tests/middlewares/request_scoped_state_is_shared_correctly_among_middlewares/generated_app/src/Cargo.toml new file mode 100644 index 000000000..9edeec435 --- /dev/null +++ b/compiler/ui_tests/middlewares/request_scoped_state_is_shared_correctly_among_middlewares/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_4b6f5359" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_4b6f5359" diff --git a/compiler/ui_tests/middlewares/request_scoped_state_is_shared_correctly_among_middlewares/generated_app/src/lib.rs b/compiler/ui_tests/middlewares/request_scoped_state_is_shared_correctly_among_middlewares/generated_app/src/lib.rs new file mode 100644 index 000000000..c71d4c0f9 --- /dev/null +++ b/compiler/ui_tests/middlewares/request_scoped_state_is_shared_correctly_among_middlewares/generated_app/src/lib.rs @@ -0,0 +1,273 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>( + s_0: &'a pavex::router::AllowedMethods, + s_1: app_4b6f5359::A, + ) -> pavex::Response { + let response = 'incoming: { + if let Some(response) = pre_processing_0(&s_1).await.into_response() { + break 'incoming response; + } + wrapping_1(s_0, &s_1).await + }; + let response = post_processing_0(response, s_1).await; + response + } + async fn stage_2<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = app_4b6f5359::a(); + let v2 = crate::route_0::Next0 { + s_0: v0, + s_1: v1, + next: stage_1, + }; + let v3 = pavex::middleware::Next::new(v2); + let v4 = pavex::middleware::wrap_noop(v3).await; + ::into_response(v4) + } + async fn pre_processing_0(v0: &app_4b6f5359::A) -> pavex::middleware::Processing { + app_4b6f5359::pre(v0) + } + async fn wrapping_1( + v0: &pavex::router::AllowedMethods, + v1: &app_4b6f5359::A, + ) -> pavex::Response { + let v2 = crate::route_0::Next1 { + s_0: v0, + next: stage_2, + }; + let v3 = pavex::middleware::Next::new(v2); + let v4 = app_4b6f5359::wrap(v3, v1); + ::into_response(v4) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + async fn post_processing_0( + v0: pavex::Response, + v1: app_4b6f5359::A, + ) -> pavex::Response { + let v2 = app_4b6f5359::post(v0, v1); + ::into_response(v2) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + s_1: app_4b6f5359::A, + next: fn(&'a pavex::router::AllowedMethods, app_4b6f5359::A) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0, self.s_1) + } + } + struct Next1<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next1<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1(s_0: app_4b6f5359::A) -> pavex::Response { + let response = 'incoming: { + if let Some(response) = pre_processing_0(&s_0).await.into_response() { + break 'incoming response; + } + wrapping_1(&s_0).await + }; + let response = post_processing_0(response, s_0).await; + response + } + async fn stage_2() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = app_4b6f5359::a(); + let v1 = crate::route_1::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn pre_processing_0(v0: &app_4b6f5359::A) -> pavex::middleware::Processing { + app_4b6f5359::pre(v0) + } + async fn wrapping_1(v0: &app_4b6f5359::A) -> pavex::Response { + let v1 = crate::route_1::Next1 { + next: stage_2, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = app_4b6f5359::wrap(v2, v0); + ::into_response(v3) + } + async fn handler() -> pavex::Response { + let v0 = app_4b6f5359::handler(); + ::into_response(v0) + } + async fn post_processing_0( + v0: pavex::Response, + v1: app_4b6f5359::A, + ) -> pavex::Response { + let v2 = app_4b6f5359::post(v0, v1); + ::into_response(v2) + } + struct Next0 + where + T: std::future::Future, + { + s_0: app_4b6f5359::A, + next: fn(app_4b6f5359::A) -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } + struct Next1 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next1 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/path_parameters/path_parameters_happy_path/generated_app/Cargo.toml b/compiler/ui_tests/path_parameters/path_parameters_happy_path/generated_app/Cargo.toml new file mode 100644 index 000000000..469917495 --- /dev/null +++ b/compiler/ui_tests/path_parameters/path_parameters_happy_path/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_c1ac8ad4" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_c1ac8ad4" + +[dependencies] +app_c1ac8ad4 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/path_parameters/path_parameters_happy_path/generated_app/src/Cargo.toml b/compiler/ui_tests/path_parameters/path_parameters_happy_path/generated_app/src/Cargo.toml new file mode 100644 index 000000000..22ed9e654 --- /dev/null +++ b/compiler/ui_tests/path_parameters/path_parameters_happy_path/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_c1ac8ad4" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_c1ac8ad4" diff --git a/compiler/ui_tests/path_parameters/path_parameters_happy_path/generated_app/src/lib.rs b/compiler/ui_tests/path_parameters/path_parameters_happy_path/generated_app/src/lib.rs new file mode 100644 index 000000000..1f7a59dd8 --- /dev/null +++ b/compiler/ui_tests/path_parameters/path_parameters_happy_path/generated_app/src/lib.rs @@ -0,0 +1,342 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/home/{home_id}", 0u32).unwrap(); + router.insert("/home/{home_id}/room/{room_id}", 1u32).unwrap(); + router.insert("/town/{*town}", 2u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + let url_params: pavex::request::path::RawPathParams<'_, '_> = matched_route + .params + .into(); + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint(url_params).await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + 1u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_2::entrypoint(url_params).await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + 2u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_3::entrypoint(url_params).await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint<'a, 'b>( + s_0: pavex::request::path::RawPathParams<'a, 'b>, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a, 'b>( + s_0: pavex::request::path::RawPathParams<'a, 'b>, + ) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0( + v0: pavex::request::path::RawPathParams<'_, '_>, + ) -> pavex::Response { + let v1 = crate::route_1::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler( + v0: pavex::request::path::RawPathParams<'_, '_>, + ) -> pavex::Response { + let v1 = pavex::request::path::PathParams::extract(v0); + let v2 = match v1 { + Ok(ok) => ok, + Err(v2) => { + return { + let v3 = pavex::request::path::errors::ExtractPathParamsError::into_response( + &v2, + ); + ::into_response(v3) + }; + } + }; + let v3 = app_c1ac8ad4::get_home(v2); + ::into_response(v3) + } + struct Next0<'a, 'b, T> + where + T: std::future::Future, + { + s_0: pavex::request::path::RawPathParams<'a, 'b>, + next: fn(pavex::request::path::RawPathParams<'a, 'b>) -> T, + } + impl<'a, 'b, T> std::future::IntoFuture for Next0<'a, 'b, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_2 { + pub async fn entrypoint<'a, 'b>( + s_0: pavex::request::path::RawPathParams<'a, 'b>, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a, 'b>( + s_0: pavex::request::path::RawPathParams<'a, 'b>, + ) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0( + v0: pavex::request::path::RawPathParams<'_, '_>, + ) -> pavex::Response { + let v1 = crate::route_2::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler( + v0: pavex::request::path::RawPathParams<'_, '_>, + ) -> pavex::Response { + let v1 = pavex::request::path::PathParams::extract(v0); + let v2 = match v1 { + Ok(ok) => ok, + Err(v2) => { + return { + let v3 = pavex::request::path::errors::ExtractPathParamsError::into_response( + &v2, + ); + ::into_response(v3) + }; + } + }; + let v3 = app_c1ac8ad4::get_room(v2); + ::into_response(v3) + } + struct Next0<'a, 'b, T> + where + T: std::future::Future, + { + s_0: pavex::request::path::RawPathParams<'a, 'b>, + next: fn(pavex::request::path::RawPathParams<'a, 'b>) -> T, + } + impl<'a, 'b, T> std::future::IntoFuture for Next0<'a, 'b, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_3 { + pub async fn entrypoint<'a, 'b>( + s_0: pavex::request::path::RawPathParams<'a, 'b>, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a, 'b>( + s_0: pavex::request::path::RawPathParams<'a, 'b>, + ) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0( + v0: pavex::request::path::RawPathParams<'_, '_>, + ) -> pavex::Response { + let v1 = crate::route_3::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler( + v0: pavex::request::path::RawPathParams<'_, '_>, + ) -> pavex::Response { + let v1 = pavex::request::path::PathParams::extract(v0); + let v2 = match v1 { + Ok(ok) => ok, + Err(v2) => { + return { + let v3 = pavex::request::path::errors::ExtractPathParamsError::into_response( + &v2, + ); + ::into_response(v3) + }; + } + }; + let v3 = app_c1ac8ad4::get_town(v2); + ::into_response(v3) + } + struct Next0<'a, 'b, T> + where + T: std::future::Future, + { + s_0: pavex::request::path::RawPathParams<'a, 'b>, + next: fn(pavex::request::path::RawPathParams<'a, 'b>) -> T, + } + impl<'a, 'b, T> std::future::IntoFuture for Next0<'a, 'b, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} diff --git a/compiler/ui_tests/path_parameters/path_parameters_non_existing_fields/generated_app/Cargo.toml b/compiler/ui_tests/path_parameters/path_parameters_non_existing_fields/generated_app/Cargo.toml new file mode 100644 index 000000000..a74a25bf8 --- /dev/null +++ b/compiler/ui_tests/path_parameters/path_parameters_non_existing_fields/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_c51a0844" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_c51a0844" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../workspace_hack" } diff --git a/compiler/ui_tests/path_parameters/path_parameters_non_existing_fields/generated_app/src/Cargo.toml b/compiler/ui_tests/path_parameters/path_parameters_non_existing_fields/generated_app/src/Cargo.toml new file mode 100644 index 000000000..96022bae6 --- /dev/null +++ b/compiler/ui_tests/path_parameters/path_parameters_non_existing_fields/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_c51a0844" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_c51a0844" diff --git a/compiler/ui_tests/path_parameters/path_parameters_non_existing_fields/generated_app/src/lib.rs b/compiler/ui_tests/path_parameters/path_parameters_non_existing_fields/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/path_parameters/path_parameters_unsupported_types/generated_app/Cargo.toml b/compiler/ui_tests/path_parameters/path_parameters_unsupported_types/generated_app/Cargo.toml new file mode 100644 index 000000000..fdba91648 --- /dev/null +++ b/compiler/ui_tests/path_parameters/path_parameters_unsupported_types/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_53b2f5d8" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_53b2f5d8" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../workspace_hack" } diff --git a/compiler/ui_tests/path_parameters/path_parameters_unsupported_types/generated_app/src/Cargo.toml b/compiler/ui_tests/path_parameters/path_parameters_unsupported_types/generated_app/src/Cargo.toml new file mode 100644 index 000000000..8ded56ced --- /dev/null +++ b/compiler/ui_tests/path_parameters/path_parameters_unsupported_types/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_53b2f5d8" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_53b2f5d8" diff --git a/compiler/ui_tests/path_parameters/path_parameters_unsupported_types/generated_app/src/lib.rs b/compiler/ui_tests/path_parameters/path_parameters_unsupported_types/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/reflection/always_use_public_path/generated_app/Cargo.toml b/compiler/ui_tests/reflection/always_use_public_path/generated_app/Cargo.toml new file mode 100644 index 000000000..e504ef1d0 --- /dev/null +++ b/compiler/ui_tests/reflection/always_use_public_path/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_73b868ae" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_73b868ae" + +[dependencies] +app_73b868ae = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/reflection/always_use_public_path/generated_app/src/Cargo.toml b/compiler/ui_tests/reflection/always_use_public_path/generated_app/src/Cargo.toml new file mode 100644 index 000000000..5b62daa2c --- /dev/null +++ b/compiler/ui_tests/reflection/always_use_public_path/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_73b868ae" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_73b868ae" diff --git a/compiler/ui_tests/reflection/always_use_public_path/generated_app/src/lib.rs b/compiler/ui_tests/reflection/always_use_public_path/generated_app/src/lib.rs new file mode 100644 index 000000000..4df7bd9ec --- /dev/null +++ b/compiler/ui_tests/reflection/always_use_public_path/generated_app/src/lib.rs @@ -0,0 +1,173 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_73b868ae::B::new(); + let v1 = app_73b868ae::a(); + let v2 = app_73b868ae::handler(v1, v0); + ::into_response(v2) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/reflection/ambiguous_dependency_version_is_handled/generated_app/Cargo.toml b/compiler/ui_tests/reflection/ambiguous_dependency_version_is_handled/generated_app/Cargo.toml new file mode 100644 index 000000000..8416af655 --- /dev/null +++ b/compiler/ui_tests/reflection/ambiguous_dependency_version_is_handled/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_ca963e92" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_ca963e92" + +[dependencies] +app_ca963e92 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/reflection/ambiguous_dependency_version_is_handled/generated_app/src/Cargo.toml b/compiler/ui_tests/reflection/ambiguous_dependency_version_is_handled/generated_app/src/Cargo.toml new file mode 100644 index 000000000..6810d9299 --- /dev/null +++ b/compiler/ui_tests/reflection/ambiguous_dependency_version_is_handled/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_ca963e92" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_ca963e92" diff --git a/compiler/ui_tests/reflection/ambiguous_dependency_version_is_handled/generated_app/src/lib.rs b/compiler/ui_tests/reflection/ambiguous_dependency_version_is_handled/generated_app/src/lib.rs new file mode 100644 index 000000000..cc59faee5 --- /dev/null +++ b/compiler/ui_tests/reflection/ambiguous_dependency_version_is_handled/generated_app/src/lib.rs @@ -0,0 +1,171 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/home", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_ca963e92::handler(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/reflection/arc_singletons_are_supported/generated_app/Cargo.toml b/compiler/ui_tests/reflection/arc_singletons_are_supported/generated_app/Cargo.toml new file mode 100644 index 000000000..ffc21e4f6 --- /dev/null +++ b/compiler/ui_tests/reflection/arc_singletons_are_supported/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_933292bd" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_933292bd" + +[dependencies] +app_933292bd = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/reflection/arc_singletons_are_supported/generated_app/src/Cargo.toml b/compiler/ui_tests/reflection/arc_singletons_are_supported/generated_app/src/Cargo.toml new file mode 100644 index 000000000..52c87fb02 --- /dev/null +++ b/compiler/ui_tests/reflection/arc_singletons_are_supported/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_933292bd" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_933292bd" diff --git a/compiler/ui_tests/reflection/arc_singletons_are_supported/generated_app/src/lib.rs b/compiler/ui_tests/reflection/arc_singletons_are_supported/generated_app/src/lib.rs new file mode 100644 index 000000000..1f7d2a83f --- /dev/null +++ b/compiler/ui_tests/reflection/arc_singletons_are_supported/generated_app/src/lib.rs @@ -0,0 +1,214 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState { + pub arc_custom: alloc::sync::Arc, + pub arc_mutex: alloc::sync::Arc>, + pub arc_rw_lock: alloc::sync::Arc>, +} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + let v0 = app_933292bd::arc_rwlock(); + let v1 = app_933292bd::arc_mutex(); + let v2 = app_933292bd::arc(); + crate::ApplicationState { + arc_custom: v2, + arc_mutex: v1, + arc_rw_lock: v0, + } + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => { + route_1::entrypoint( + &state.arc_custom, + &state.arc_mutex, + &state.arc_rw_lock, + ) + .await + } + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint<'a, 'b, 'c>( + s_0: &'a alloc::sync::Arc, + s_1: &'b alloc::sync::Arc>, + s_2: &'c alloc::sync::Arc>, + ) -> pavex::Response { + let response = wrapping_0(s_0, s_1, s_2).await; + response + } + async fn stage_1<'a, 'b, 'c>( + s_0: &'a alloc::sync::Arc, + s_1: &'b alloc::sync::Arc>, + s_2: &'c alloc::sync::Arc>, + ) -> pavex::Response { + let response = handler(s_0, s_1, s_2).await; + response + } + async fn wrapping_0( + v0: &alloc::sync::Arc, + v1: &alloc::sync::Arc>, + v2: &alloc::sync::Arc>, + ) -> pavex::Response { + let v3 = crate::route_1::Next0 { + s_0: v0, + s_1: v1, + s_2: v2, + next: stage_1, + }; + let v4 = pavex::middleware::Next::new(v3); + let v5 = pavex::middleware::wrap_noop(v4).await; + ::into_response(v5) + } + async fn handler( + v0: &alloc::sync::Arc, + v1: &alloc::sync::Arc>, + v2: &alloc::sync::Arc>, + ) -> pavex::Response { + let v3 = app_933292bd::route_handler(v0, v1, v2); + ::into_response(v3) + } + struct Next0<'a, 'b, 'c, T> + where + T: std::future::Future, + { + s_0: &'a alloc::sync::Arc, + s_1: &'b alloc::sync::Arc>, + s_2: &'c alloc::sync::Arc>, + next: fn( + &'a alloc::sync::Arc, + &'b alloc::sync::Arc>, + &'c alloc::sync::Arc>, + ) -> T, + } + impl<'a, 'b, 'c, T> std::future::IntoFuture for Next0<'a, 'b, 'c, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0, self.s_1, self.s_2) + } + } +} diff --git a/compiler/ui_tests/reflection/common_response_types_are_supported/generated_app/Cargo.toml b/compiler/ui_tests/reflection/common_response_types_are_supported/generated_app/Cargo.toml new file mode 100644 index 000000000..fca7b6362 --- /dev/null +++ b/compiler/ui_tests/reflection/common_response_types_are_supported/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_88bca0dc" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_88bca0dc" + +[dependencies] +app_88bca0dc = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/reflection/common_response_types_are_supported/generated_app/src/Cargo.toml b/compiler/ui_tests/reflection/common_response_types_are_supported/generated_app/src/Cargo.toml new file mode 100644 index 000000000..20e501e12 --- /dev/null +++ b/compiler/ui_tests/reflection/common_response_types_are_supported/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_88bca0dc" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_88bca0dc" diff --git a/compiler/ui_tests/reflection/common_response_types_are_supported/generated_app/src/lib.rs b/compiler/ui_tests/reflection/common_response_types_are_supported/generated_app/src/lib.rs new file mode 100644 index 000000000..f359fbfb7 --- /dev/null +++ b/compiler/ui_tests/reflection/common_response_types_are_supported/generated_app/src/lib.rs @@ -0,0 +1,324 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/head", 0u32).unwrap(); + router.insert("/parts", 1u32).unwrap(); + router.insert("/response", 2u32).unwrap(); + router.insert("/status_code", 3u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_4::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + 1u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_3::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + 2u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + 3u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_2::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_88bca0dc::route_response(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} +pub mod route_2 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_2::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_88bca0dc::route_status_code(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} +pub mod route_3 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_3::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_88bca0dc::route_parts(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} +pub mod route_4 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_4::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_88bca0dc::route_response_head(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/reflection/crate_resolution/dependencies_can_register_local_items/generated_app/Cargo.toml b/compiler/ui_tests/reflection/crate_resolution/dependencies_can_register_local_items/generated_app/Cargo.toml new file mode 100644 index 000000000..97033592e --- /dev/null +++ b/compiler/ui_tests/reflection/crate_resolution/dependencies_can_register_local_items/generated_app/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "application_39415e2f" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_39415e2f" + +[dependencies] +app_39415e2f = { version = "0.1", path = "..", default-features = false } +dep_39415e2f = { version = "0.1", path = "../ephemeral_deps/dep", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/reflection/crate_resolution/dependencies_can_register_local_items/generated_app/src/Cargo.toml b/compiler/ui_tests/reflection/crate_resolution/dependencies_can_register_local_items/generated_app/src/Cargo.toml new file mode 100644 index 000000000..d2a92196d --- /dev/null +++ b/compiler/ui_tests/reflection/crate_resolution/dependencies_can_register_local_items/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_39415e2f" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_39415e2f" diff --git a/compiler/ui_tests/reflection/crate_resolution/dependencies_can_register_local_items/generated_app/src/lib.rs b/compiler/ui_tests/reflection/crate_resolution/dependencies_can_register_local_items/generated_app/src/lib.rs new file mode 100644 index 000000000..fdfa9cd8a --- /dev/null +++ b/compiler/ui_tests/reflection/crate_resolution/dependencies_can_register_local_items/generated_app/src/lib.rs @@ -0,0 +1,172 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/home", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = dep_39415e2f::new_logger(); + let v1 = app_39415e2f::handler(v0); + ::into_response(v1) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/reflection/crate_resolution/multiple_versions_for_the_same_crate_are_supported/generated_app/Cargo.toml b/compiler/ui_tests/reflection/crate_resolution/multiple_versions_for_the_same_crate_are_supported/generated_app/Cargo.toml new file mode 100644 index 000000000..cfd80352b --- /dev/null +++ b/compiler/ui_tests/reflection/crate_resolution/multiple_versions_for_the_same_crate_are_supported/generated_app/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "application_cb7427d1" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_cb7427d1" + +[dependencies] +app_cb7427d1 = { version = "0.1", path = "..", default-features = false } +http_0_1 = { version = "0.1", default-features = false, package = "http" } +http_0_2 = { version = "0.2", default-features = false, package = "http" } +http_1 = { version = "1", default-features = false, package = "http" } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/reflection/crate_resolution/multiple_versions_for_the_same_crate_are_supported/generated_app/src/Cargo.toml b/compiler/ui_tests/reflection/crate_resolution/multiple_versions_for_the_same_crate_are_supported/generated_app/src/Cargo.toml new file mode 100644 index 000000000..b8fdabf5c --- /dev/null +++ b/compiler/ui_tests/reflection/crate_resolution/multiple_versions_for_the_same_crate_are_supported/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_cb7427d1" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_cb7427d1" diff --git a/compiler/ui_tests/reflection/crate_resolution/multiple_versions_for_the_same_crate_are_supported/generated_app/src/lib.rs b/compiler/ui_tests/reflection/crate_resolution/multiple_versions_for_the_same_crate_are_supported/generated_app/src/lib.rs new file mode 100644 index 000000000..4199ee21d --- /dev/null +++ b/compiler/ui_tests/reflection/crate_resolution/multiple_versions_for_the_same_crate_are_supported/generated_app/src/lib.rs @@ -0,0 +1,173 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http_1::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http_1::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_cb7427d1::header2(); + let v1 = app_cb7427d1::header1(); + let v2 = app_cb7427d1::handler(v1, v0); + ::into_response(v2) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/reflection/crate_resolution/transitive_dependencies_can_be_renamed/generated_app/Cargo.toml b/compiler/ui_tests/reflection/crate_resolution/transitive_dependencies_can_be_renamed/generated_app/Cargo.toml new file mode 100644 index 000000000..a0443825b --- /dev/null +++ b/compiler/ui_tests/reflection/crate_resolution/transitive_dependencies_can_be_renamed/generated_app/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "application_a0f4586a" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_a0f4586a" + +[dependencies] +dep_a0f4586a = { version = "0.1", path = "../ephemeral_deps/dep", default-features = false } +http_0_1 = { version = "0.1", default-features = false, package = "http" } +http_0_2 = { version = "0.2", default-features = false, package = "http" } +http_1 = { version = "1", default-features = false, package = "http" } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/reflection/crate_resolution/transitive_dependencies_can_be_renamed/generated_app/src/Cargo.toml b/compiler/ui_tests/reflection/crate_resolution/transitive_dependencies_can_be_renamed/generated_app/src/Cargo.toml new file mode 100644 index 000000000..461351dd6 --- /dev/null +++ b/compiler/ui_tests/reflection/crate_resolution/transitive_dependencies_can_be_renamed/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_a0f4586a" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_a0f4586a" diff --git a/compiler/ui_tests/reflection/crate_resolution/transitive_dependencies_can_be_renamed/generated_app/src/lib.rs b/compiler/ui_tests/reflection/crate_resolution/transitive_dependencies_can_be_renamed/generated_app/src/lib.rs new file mode 100644 index 000000000..8e7644054 --- /dev/null +++ b/compiler/ui_tests/reflection/crate_resolution/transitive_dependencies_can_be_renamed/generated_app/src/lib.rs @@ -0,0 +1,173 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http_1::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/handler", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http_1::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = dep_a0f4586a::header2(); + let v1 = dep_a0f4586a::header1(); + let v2 = dep_a0f4586a::handler(v1, v0); + ::into_response(v2) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/reflection/generic_parameters_can_come_from_another_crate/generated_app/Cargo.toml b/compiler/ui_tests/reflection/generic_parameters_can_come_from_another_crate/generated_app/Cargo.toml new file mode 100644 index 000000000..dbed0fac4 --- /dev/null +++ b/compiler/ui_tests/reflection/generic_parameters_can_come_from_another_crate/generated_app/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "application_dcb9931d" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_dcb9931d" + +[dependencies] +app_dcb9931d = { version = "0.1", path = "..", default-features = false } +dep_dcb9931d = { version = "1", path = "../ephemeral_deps/dep_1", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/reflection/generic_parameters_can_come_from_another_crate/generated_app/src/Cargo.toml b/compiler/ui_tests/reflection/generic_parameters_can_come_from_another_crate/generated_app/src/Cargo.toml new file mode 100644 index 000000000..b6923267e --- /dev/null +++ b/compiler/ui_tests/reflection/generic_parameters_can_come_from_another_crate/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_dcb9931d" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_dcb9931d" diff --git a/compiler/ui_tests/reflection/generic_parameters_can_come_from_another_crate/generated_app/src/lib.rs b/compiler/ui_tests/reflection/generic_parameters_can_come_from_another_crate/generated_app/src/lib.rs new file mode 100644 index 000000000..4735d9fae --- /dev/null +++ b/compiler/ui_tests/reflection/generic_parameters_can_come_from_another_crate/generated_app/src/lib.rs @@ -0,0 +1,173 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/home", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_dcb9931d::handler(); + as pavex::IntoResponse>::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/reflection/ids_can_conflict_across_crates/generated_app/Cargo.toml b/compiler/ui_tests/reflection/ids_can_conflict_across_crates/generated_app/Cargo.toml new file mode 100644 index 000000000..d9ce2b445 --- /dev/null +++ b/compiler/ui_tests/reflection/ids_can_conflict_across_crates/generated_app/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "application_b58d3639" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_b58d3639" + +[dependencies] +app_b58d3639 = { version = "0.1", path = "..", default-features = false } +dep_daa9931d = { version = "1", path = "../ephemeral_deps/dep_1", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/reflection/ids_can_conflict_across_crates/generated_app/src/Cargo.toml b/compiler/ui_tests/reflection/ids_can_conflict_across_crates/generated_app/src/Cargo.toml new file mode 100644 index 000000000..58e2cae05 --- /dev/null +++ b/compiler/ui_tests/reflection/ids_can_conflict_across_crates/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_b58d3639" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_b58d3639" diff --git a/compiler/ui_tests/reflection/ids_can_conflict_across_crates/generated_app/src/lib.rs b/compiler/ui_tests/reflection/ids_can_conflict_across_crates/generated_app/src/lib.rs new file mode 100644 index 000000000..029b358fd --- /dev/null +++ b/compiler/ui_tests/reflection/ids_can_conflict_across_crates/generated_app/src/lib.rs @@ -0,0 +1,175 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState { + pub a: dep_daa9931d::A, +} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + let v0 = dep_daa9931d::conflict(); + crate::ApplicationState { a: v0 } + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint(&state.a).await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint<'a>(s_0: &'a dep_daa9931d::A) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a dep_daa9931d::A) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &dep_daa9931d::A) -> pavex::Response { + let v1 = crate::route_1::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &dep_daa9931d::A) -> pavex::Response { + let v1 = app_b58d3639::handler(v0); + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a dep_daa9931d::A, + next: fn(&'a dep_daa9931d::A) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} diff --git a/compiler/ui_tests/reflection/ids_must_be_unique_within_the_same_crate/generated_app/Cargo.toml b/compiler/ui_tests/reflection/ids_must_be_unique_within_the_same_crate/generated_app/Cargo.toml new file mode 100644 index 000000000..cb0f99fa4 --- /dev/null +++ b/compiler/ui_tests/reflection/ids_must_be_unique_within_the_same_crate/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_3418fa18" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_3418fa18" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../workspace_hack" } diff --git a/compiler/ui_tests/reflection/ids_must_be_unique_within_the_same_crate/generated_app/src/Cargo.toml b/compiler/ui_tests/reflection/ids_must_be_unique_within_the_same_crate/generated_app/src/Cargo.toml new file mode 100644 index 000000000..10d8793da --- /dev/null +++ b/compiler/ui_tests/reflection/ids_must_be_unique_within_the_same_crate/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_3418fa18" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_3418fa18" diff --git a/compiler/ui_tests/reflection/ids_must_be_unique_within_the_same_crate/generated_app/src/lib.rs b/compiler/ui_tests/reflection/ids_must_be_unique_within_the_same_crate/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/reflection/lifetime_restrictions_are_handled/generated_app/Cargo.toml b/compiler/ui_tests/reflection/lifetime_restrictions_are_handled/generated_app/Cargo.toml new file mode 100644 index 000000000..ca917910f --- /dev/null +++ b/compiler/ui_tests/reflection/lifetime_restrictions_are_handled/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_d56c0f9d" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_d56c0f9d" + +[dependencies] +app_d56c0f9d = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/reflection/lifetime_restrictions_are_handled/generated_app/src/Cargo.toml b/compiler/ui_tests/reflection/lifetime_restrictions_are_handled/generated_app/src/Cargo.toml new file mode 100644 index 000000000..f774fd254 --- /dev/null +++ b/compiler/ui_tests/reflection/lifetime_restrictions_are_handled/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_d56c0f9d" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_d56c0f9d" diff --git a/compiler/ui_tests/reflection/lifetime_restrictions_are_handled/generated_app/src/lib.rs b/compiler/ui_tests/reflection/lifetime_restrictions_are_handled/generated_app/src/lib.rs new file mode 100644 index 000000000..2a4dcedac --- /dev/null +++ b/compiler/ui_tests/reflection/lifetime_restrictions_are_handled/generated_app/src/lib.rs @@ -0,0 +1,248 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + let url_params: pavex::request::path::RawPathParams<'_, '_> = matched_route + .params + .into(); + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint(&url_params).await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = wrapping_1(s_0).await; + response + } + async fn stage_2<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn wrapping_1(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next1 { + s_0: v0, + next: stage_2, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = app_d56c0f9d::mw(v2); + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } + struct Next1<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next1<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint<'a, 'b, 'c>( + s_0: &'c pavex::request::path::RawPathParams<'a, 'b>, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a, 'b, 'c>( + s_0: &'c pavex::request::path::RawPathParams<'a, 'b>, + ) -> pavex::Response { + let response = wrapping_1(s_0).await; + response + } + async fn stage_2<'a, 'b, 'c>( + s_0: &'c pavex::request::path::RawPathParams<'a, 'b>, + ) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0( + v0: &pavex::request::path::RawPathParams<'_, '_>, + ) -> pavex::Response { + let v1 = crate::route_1::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn wrapping_1( + v0: &pavex::request::path::RawPathParams<'_, '_>, + ) -> pavex::Response { + let v1 = crate::route_1::Next1 { + s_0: v0, + next: stage_2, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = app_d56c0f9d::mw(v2); + ::into_response(v3) + } + async fn handler( + v0: &pavex::request::path::RawPathParams<'_, '_>, + ) -> pavex::Response { + let v1 = app_d56c0f9d::handler(v0); + ::into_response(v1) + } + struct Next0<'a, 'b, 'c, T> + where + T: std::future::Future, + { + s_0: &'c pavex::request::path::RawPathParams<'a, 'b>, + next: fn(&'c pavex::request::path::RawPathParams<'a, 'b>) -> T, + } + impl<'a, 'b, 'c, T> std::future::IntoFuture for Next0<'a, 'b, 'c, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } + struct Next1<'a, 'b, 'c, T> + where + T: std::future::Future, + { + s_0: &'c pavex::request::path::RawPathParams<'a, 'b>, + next: fn(&'c pavex::request::path::RawPathParams<'a, 'b>) -> T, + } + impl<'a, 'b, 'c, T> std::future::IntoFuture for Next1<'a, 'b, 'c, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} diff --git a/compiler/ui_tests/reflection/local_glob_reexports_are_supported/generated_app/Cargo.toml b/compiler/ui_tests/reflection/local_glob_reexports_are_supported/generated_app/Cargo.toml new file mode 100644 index 000000000..eede0eba1 --- /dev/null +++ b/compiler/ui_tests/reflection/local_glob_reexports_are_supported/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_e6a3fe43" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_e6a3fe43" + +[dependencies] +app_e6a3fe43 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/reflection/local_glob_reexports_are_supported/generated_app/src/Cargo.toml b/compiler/ui_tests/reflection/local_glob_reexports_are_supported/generated_app/src/Cargo.toml new file mode 100644 index 000000000..599a2e10f --- /dev/null +++ b/compiler/ui_tests/reflection/local_glob_reexports_are_supported/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_e6a3fe43" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_e6a3fe43" diff --git a/compiler/ui_tests/reflection/local_glob_reexports_are_supported/generated_app/src/lib.rs b/compiler/ui_tests/reflection/local_glob_reexports_are_supported/generated_app/src/lib.rs new file mode 100644 index 000000000..cc2fe187e --- /dev/null +++ b/compiler/ui_tests/reflection/local_glob_reexports_are_supported/generated_app/src/lib.rs @@ -0,0 +1,171 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/home", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_e6a3fe43::nested::function(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/reflection/non_static_methods_are_supported/generated_app/Cargo.toml b/compiler/ui_tests/reflection/non_static_methods_are_supported/generated_app/Cargo.toml new file mode 100644 index 000000000..d0c42951b --- /dev/null +++ b/compiler/ui_tests/reflection/non_static_methods_are_supported/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_40e90d31" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_40e90d31" + +[dependencies] +app_40e90d31 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/reflection/non_static_methods_are_supported/generated_app/src/Cargo.toml b/compiler/ui_tests/reflection/non_static_methods_are_supported/generated_app/src/Cargo.toml new file mode 100644 index 000000000..0fede5b01 --- /dev/null +++ b/compiler/ui_tests/reflection/non_static_methods_are_supported/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_40e90d31" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_40e90d31" diff --git a/compiler/ui_tests/reflection/non_static_methods_are_supported/generated_app/src/lib.rs b/compiler/ui_tests/reflection/non_static_methods_are_supported/generated_app/src/lib.rs new file mode 100644 index 000000000..c712d72b0 --- /dev/null +++ b/compiler/ui_tests/reflection/non_static_methods_are_supported/generated_app/src/lib.rs @@ -0,0 +1,183 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState { + pub logger_factory: app_40e90d31::LoggerFactory, +} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + let v0 = app_40e90d31::LoggerFactory::new(); + crate::ApplicationState { + logger_factory: v0, + } + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/home", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => { + route_1::entrypoint(&state.logger_factory).await + } + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint<'a>( + s_0: &'a app_40e90d31::LoggerFactory, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a app_40e90d31::LoggerFactory) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &app_40e90d31::LoggerFactory) -> pavex::Response { + let v1 = crate::route_1::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &app_40e90d31::LoggerFactory) -> pavex::Response { + let v1 = app_40e90d31::LoggerFactory::logger(v0); + let v2 = app_40e90d31::Streamer::new(); + let v3 = app_40e90d31::Streamer::stream_file(&v2, v1); + ::into_response(v3) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a app_40e90d31::LoggerFactory, + next: fn(&'a app_40e90d31::LoggerFactory) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} diff --git a/compiler/ui_tests/reflection/output_parameter_cannot_be_handled/generated_app/Cargo.toml b/compiler/ui_tests/reflection/output_parameter_cannot_be_handled/generated_app/Cargo.toml new file mode 100644 index 000000000..641ec8928 --- /dev/null +++ b/compiler/ui_tests/reflection/output_parameter_cannot_be_handled/generated_app/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "application_e5e761b9" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_e5e761b9" + +[dependencies] +workspace_hack = { version = "0.1", path = "../../../workspace_hack" } diff --git a/compiler/ui_tests/reflection/output_parameter_cannot_be_handled/generated_app/src/Cargo.toml b/compiler/ui_tests/reflection/output_parameter_cannot_be_handled/generated_app/src/Cargo.toml new file mode 100644 index 000000000..abedb25d3 --- /dev/null +++ b/compiler/ui_tests/reflection/output_parameter_cannot_be_handled/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_e5e761b9" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_e5e761b9" diff --git a/compiler/ui_tests/reflection/output_parameter_cannot_be_handled/generated_app/src/lib.rs b/compiler/ui_tests/reflection/output_parameter_cannot_be_handled/generated_app/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/compiler/ui_tests/reflection/pattern_bindings_in_input_parameters_are_supported/generated_app/Cargo.toml b/compiler/ui_tests/reflection/pattern_bindings_in_input_parameters_are_supported/generated_app/Cargo.toml new file mode 100644 index 000000000..6227ebef1 --- /dev/null +++ b/compiler/ui_tests/reflection/pattern_bindings_in_input_parameters_are_supported/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_d1b695a6" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_d1b695a6" + +[dependencies] +app_d1b695a6 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/reflection/pattern_bindings_in_input_parameters_are_supported/generated_app/src/Cargo.toml b/compiler/ui_tests/reflection/pattern_bindings_in_input_parameters_are_supported/generated_app/src/Cargo.toml new file mode 100644 index 000000000..26686588a --- /dev/null +++ b/compiler/ui_tests/reflection/pattern_bindings_in_input_parameters_are_supported/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_d1b695a6" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_d1b695a6" diff --git a/compiler/ui_tests/reflection/pattern_bindings_in_input_parameters_are_supported/generated_app/src/lib.rs b/compiler/ui_tests/reflection/pattern_bindings_in_input_parameters_are_supported/generated_app/src/lib.rs new file mode 100644 index 000000000..506a53bda --- /dev/null +++ b/compiler/ui_tests/reflection/pattern_bindings_in_input_parameters_are_supported/generated_app/src/lib.rs @@ -0,0 +1,179 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState { + pub streamer: app_d1b695a6::Streamer, +} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + let v0 = app_d1b695a6::streamer(); + crate::ApplicationState { + streamer: v0, + } + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/home", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => { + route_1::entrypoint(&state.streamer).await + } + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint<'a>(s_0: &'a app_d1b695a6::Streamer) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a app_d1b695a6::Streamer) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &app_d1b695a6::Streamer) -> pavex::Response { + let v1 = crate::route_1::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &app_d1b695a6::Streamer) -> pavex::Response { + let v1 = app_d1b695a6::route_handler(v0); + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a app_d1b695a6::Streamer, + next: fn(&'a app_d1b695a6::Streamer) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} diff --git a/compiler/ui_tests/reflection/reexported_type_alias_work/generated_app/Cargo.toml b/compiler/ui_tests/reflection/reexported_type_alias_work/generated_app/Cargo.toml new file mode 100644 index 000000000..ef0bd681c --- /dev/null +++ b/compiler/ui_tests/reflection/reexported_type_alias_work/generated_app/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "application_065fd341" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_065fd341" + +[dependencies] +app_065fd341 = { version = "0.1", path = "..", default-features = false } +dep_065fd341 = { version = "0.1", path = "../ephemeral_deps/dep", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/reflection/reexported_type_alias_work/generated_app/src/Cargo.toml b/compiler/ui_tests/reflection/reexported_type_alias_work/generated_app/src/Cargo.toml new file mode 100644 index 000000000..881f26521 --- /dev/null +++ b/compiler/ui_tests/reflection/reexported_type_alias_work/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_065fd341" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_065fd341" diff --git a/compiler/ui_tests/reflection/reexported_type_alias_work/generated_app/src/lib.rs b/compiler/ui_tests/reflection/reexported_type_alias_work/generated_app/src/lib.rs new file mode 100644 index 000000000..2f42bbeb8 --- /dev/null +++ b/compiler/ui_tests/reflection/reexported_type_alias_work/generated_app/src/lib.rs @@ -0,0 +1,187 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState { + pub surreal: dep_065fd341::Surreal, +} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + let v0 = app_065fd341::constructor(); + crate::ApplicationState { + surreal: v0, + } + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => { + route_1::entrypoint(&state.surreal).await + } + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint<'a>( + s_0: &'a dep_065fd341::Surreal, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>( + s_0: &'a dep_065fd341::Surreal, + ) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0( + v0: &dep_065fd341::Surreal, + ) -> pavex::Response { + let v1 = crate::route_1::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler( + v0: &dep_065fd341::Surreal, + ) -> pavex::Response { + let v1 = app_065fd341::handler(v0); + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a dep_065fd341::Surreal, + next: fn(&'a dep_065fd341::Surreal) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} diff --git a/compiler/ui_tests/reflection/self_as_generic_parameter_is_supported/generated_app/Cargo.toml b/compiler/ui_tests/reflection/self_as_generic_parameter_is_supported/generated_app/Cargo.toml new file mode 100644 index 000000000..762d7662b --- /dev/null +++ b/compiler/ui_tests/reflection/self_as_generic_parameter_is_supported/generated_app/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "application_d89d2d61" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_d89d2d61" + +[dependencies] +anyhow = { version = "1", default-features = false } +app_d89d2d61 = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/reflection/self_as_generic_parameter_is_supported/generated_app/src/Cargo.toml b/compiler/ui_tests/reflection/self_as_generic_parameter_is_supported/generated_app/src/Cargo.toml new file mode 100644 index 000000000..9a741f5b6 --- /dev/null +++ b/compiler/ui_tests/reflection/self_as_generic_parameter_is_supported/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_d89d2d61" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_d89d2d61" diff --git a/compiler/ui_tests/reflection/self_as_generic_parameter_is_supported/generated_app/src/lib.rs b/compiler/ui_tests/reflection/self_as_generic_parameter_is_supported/generated_app/src/lib.rs new file mode 100644 index 000000000..12e581564 --- /dev/null +++ b/compiler/ui_tests/reflection/self_as_generic_parameter_is_supported/generated_app/src/lib.rs @@ -0,0 +1,181 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_d89d2d61::A::new(); + let v1 = match v0 { + Ok(ok) => ok, + Err(v1) => { + return { + let v2 = app_d89d2d61::error_handler(&v1); + ::into_response(v2) + }; + } + }; + let v2 = app_d89d2d61::handler(v1); + ::into_response(v2) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/reflection/static_methods_are_supported/generated_app/Cargo.toml b/compiler/ui_tests/reflection/static_methods_are_supported/generated_app/Cargo.toml new file mode 100644 index 000000000..74d606905 --- /dev/null +++ b/compiler/ui_tests/reflection/static_methods_are_supported/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_d50c6d0c" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_d50c6d0c" + +[dependencies] +app_d50c6d0c = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/reflection/static_methods_are_supported/generated_app/src/Cargo.toml b/compiler/ui_tests/reflection/static_methods_are_supported/generated_app/src/Cargo.toml new file mode 100644 index 000000000..0bfbf9ffb --- /dev/null +++ b/compiler/ui_tests/reflection/static_methods_are_supported/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_d50c6d0c" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_d50c6d0c" diff --git a/compiler/ui_tests/reflection/static_methods_are_supported/generated_app/src/lib.rs b/compiler/ui_tests/reflection/static_methods_are_supported/generated_app/src/lib.rs new file mode 100644 index 000000000..a1cbf9a0b --- /dev/null +++ b/compiler/ui_tests/reflection/static_methods_are_supported/generated_app/src/lib.rs @@ -0,0 +1,171 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = app_d50c6d0c::Streamer::stream_file(); + ::into_response(v0) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/reflection/trait_methods_are_supported/generated_app/Cargo.toml b/compiler/ui_tests/reflection/trait_methods_are_supported/generated_app/Cargo.toml new file mode 100644 index 000000000..901c7749b --- /dev/null +++ b/compiler/ui_tests/reflection/trait_methods_are_supported/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_a7fd6a2c" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_a7fd6a2c" + +[dependencies] +app_a7fd6a2c = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/reflection/trait_methods_are_supported/generated_app/src/Cargo.toml b/compiler/ui_tests/reflection/trait_methods_are_supported/generated_app/src/Cargo.toml new file mode 100644 index 000000000..bbec88d44 --- /dev/null +++ b/compiler/ui_tests/reflection/trait_methods_are_supported/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_a7fd6a2c" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_a7fd6a2c" diff --git a/compiler/ui_tests/reflection/trait_methods_are_supported/generated_app/src/lib.rs b/compiler/ui_tests/reflection/trait_methods_are_supported/generated_app/src/lib.rs new file mode 100644 index 000000000..2649e6c43 --- /dev/null +++ b/compiler/ui_tests/reflection/trait_methods_are_supported/generated_app/src/lib.rs @@ -0,0 +1,179 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + #[allow(dead_code)] + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState {} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + crate::ApplicationState {} + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => route_1::entrypoint().await, + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint() -> pavex::Response { + let response = wrapping_0().await; + response + } + async fn stage_1() -> pavex::Response { + let response = handler().await; + response + } + async fn wrapping_0() -> pavex::Response { + let v0 = crate::route_1::Next0 { + next: stage_1, + }; + let v1 = pavex::middleware::Next::new(v0); + let v2 = pavex::middleware::wrap_noop(v1).await; + ::into_response(v2) + } + async fn handler() -> pavex::Response { + let v0 = ::default(); + let v1 = ::a_method_that_returns_self(); + let v2 = ::a_method_that_borrows_self( + &v1, + ); + let v3 = ::a_method_that_consumes_self( + v2, + ); + let v4 = app_a7fd6a2c::handler(v1, v3, v0); + ::into_response(v4) + } + struct Next0 + where + T: std::future::Future, + { + next: fn() -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)() + } + } +} diff --git a/compiler/ui_tests/reflection/tuples_are_supported/generated_app/Cargo.toml b/compiler/ui_tests/reflection/tuples_are_supported/generated_app/Cargo.toml new file mode 100644 index 000000000..b2117bcc1 --- /dev/null +++ b/compiler/ui_tests/reflection/tuples_are_supported/generated_app/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "application_1bd0738c" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_1bd0738c" + +[dependencies] +app_1bd0738c = { version = "0.1", path = "..", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/reflection/tuples_are_supported/generated_app/src/Cargo.toml b/compiler/ui_tests/reflection/tuples_are_supported/generated_app/src/Cargo.toml new file mode 100644 index 000000000..e4b467246 --- /dev/null +++ b/compiler/ui_tests/reflection/tuples_are_supported/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_1bd0738c" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_1bd0738c" diff --git a/compiler/ui_tests/reflection/tuples_are_supported/generated_app/src/lib.rs b/compiler/ui_tests/reflection/tuples_are_supported/generated_app/src/lib.rs new file mode 100644 index 000000000..c5e2d7f1b --- /dev/null +++ b/compiler/ui_tests/reflection/tuples_are_supported/generated_app/src/lib.rs @@ -0,0 +1,179 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState { + pub usize__isize_: (usize, isize), +} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + ) -> Result { + Ok(Self::_new().await) + } + async fn _new() -> crate::ApplicationState { + let v0 = app_1bd0738c::constructor_with_output_tuple(); + crate::ApplicationState { + usize__isize_: v0, + } + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => { + route_1::entrypoint(state.usize__isize_.clone()).await + } + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint(s_0: (usize, isize)) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1(s_0: (usize, isize)) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: (usize, isize)) -> pavex::Response { + let v1 = crate::route_1::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: (usize, isize)) -> pavex::Response { + let v1 = app_1bd0738c::handler(v0); + ::into_response(v1) + } + struct Next0 + where + T: std::future::Future, + { + s_0: (usize, isize), + next: fn((usize, isize)) -> T, + } + impl std::future::IntoFuture for Next0 + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} diff --git a/compiler/ui_tests/reflection/type_alias_are_supported/generated_app/Cargo.toml b/compiler/ui_tests/reflection/type_alias_are_supported/generated_app/Cargo.toml new file mode 100644 index 000000000..0b6dce9e0 --- /dev/null +++ b/compiler/ui_tests/reflection/type_alias_are_supported/generated_app/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "application_f8f62968" +version = "0.1.0" +edition = "2024" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_f8f62968" + +[dependencies] +app_f8f62968 = { version = "0.1", path = "..", default-features = false } +dep_f8f62968 = { version = "0.1", path = "../ephemeral_deps/dep", default-features = false } +http = { version = "1", default-features = false } +hyper = { version = "1", default-features = false } +matchit = { version = "0.9", default-features = false } +pavex = { version = "0.2", path = "../../../../../runtime/pavex", default-features = false } +serde = { version = "1", default-features = false } +thiserror = { version = "2", default-features = false } diff --git a/compiler/ui_tests/reflection/type_alias_are_supported/generated_app/src/Cargo.toml b/compiler/ui_tests/reflection/type_alias_are_supported/generated_app/src/Cargo.toml new file mode 100644 index 000000000..70af91727 --- /dev/null +++ b/compiler/ui_tests/reflection/type_alias_are_supported/generated_app/src/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "application_f8f62968" +version = "0.1.0" +edition = "2021" + +[package.metadata.px.generate] +generator_type = "cargo_workspace_binary" +generator_name = "app_f8f62968" diff --git a/compiler/ui_tests/reflection/type_alias_are_supported/generated_app/src/lib.rs b/compiler/ui_tests/reflection/type_alias_are_supported/generated_app/src/lib.rs new file mode 100644 index 000000000..8971f660e --- /dev/null +++ b/compiler/ui_tests/reflection/type_alias_are_supported/generated_app/src/lib.rs @@ -0,0 +1,252 @@ +//! Do NOT edit this code. +//! It was automatically generated by Pavex. +//! All manual edits will be lost next time the code is generated. +extern crate alloc; +struct ServerState { + router: Router, + application_state: ApplicationState, +} +#[derive(Debug, Clone, serde::Deserialize)] +pub struct ApplicationConfig {} +pub struct ApplicationState { + pub actual_type: dep_f8f62968::ActualType, + pub bool__char__u8_: (bool, char, u8), + pub generic_type_bool__bool_: dep_f8f62968::GenericType, + pub generic_type_bool__u8_: dep_f8f62968::GenericType, + pub generic_type_u8__u8_: dep_f8f62968::GenericType, + pub string: alloc::string::String, +} +impl ApplicationState { + pub async fn new( + _app_config: crate::ApplicationConfig, + v0: alloc::string::String, + v1: dep_f8f62968::GenericType, + ) -> Result { + Ok(Self::_new(v0, v1).await) + } + async fn _new( + v0: alloc::string::String, + v1: dep_f8f62968::GenericType, + ) -> crate::ApplicationState { + let v2 = dep_f8f62968::GenericType::new(); + let v3 = dep_f8f62968::GenericType::new(); + let v4 = app_f8f62968::constructor_with_output_tuple(); + let v5 = dep_f8f62968::ActualType::new(); + crate::ApplicationState { + actual_type: v5, + bool__char__u8_: v4, + generic_type_bool__bool_: v3, + generic_type_bool__u8_: v1, + generic_type_u8__u8_: v2, + string: v0, + } + } +} +#[derive(Debug, thiserror::Error)] +pub enum ApplicationStateError {} +pub fn run( + server_builder: pavex::server::Server, + application_state: ApplicationState, +) -> pavex::server::ServerHandle { + async fn handler( + request: http::Request, + connection_info: Option, + server_state: std::sync::Arc, + ) -> pavex::Response { + let (router, state) = (&server_state.router, &server_state.application_state); + router.route(request, connection_info, state).await + } + let router = Router::new(); + let server_state = std::sync::Arc::new(ServerState { + router, + application_state, + }); + server_builder.serve(handler, server_state) +} +struct Router { + router: matchit::Router, +} +impl Router { + /// Create a new router instance. + /// + /// This method is invoked once, when the server starts. + pub fn new() -> Self { + Self { router: Self::router() } + } + fn router() -> matchit::Router { + let mut router = matchit::Router::new(); + router.insert("/home", 0u32).unwrap(); + router + } + pub async fn route( + &self, + request: http::Request, + _connection_info: Option, + #[allow(unused)] + state: &ApplicationState, + ) -> pavex::Response { + let (request_head, _) = request.into_parts(); + let request_head: pavex::request::RequestHead = request_head.into(); + let Ok(matched_route) = self.router.at(&request_head.target.path()) else { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter( + vec![], + ) + .into(); + return route_0::entrypoint(&allowed_methods).await; + }; + match matched_route.value { + 0u32 => { + match &request_head.method { + &pavex::http::Method::GET => { + route_1::entrypoint( + state.bool__char__u8_.clone(), + &state.string, + &state.actual_type, + &state.generic_type_bool__bool_, + &state.generic_type_u8__u8_, + &state.generic_type_bool__u8_, + ) + .await + } + _ => { + let allowed_methods: pavex::router::AllowedMethods = pavex::router::MethodAllowList::from_iter([ + pavex::http::Method::GET, + ]) + .into(); + route_0::entrypoint(&allowed_methods).await + } + } + } + i => unreachable!("Unknown route id: {}", i), + } + } +} +pub mod route_0 { + pub async fn entrypoint<'a>( + s_0: &'a pavex::router::AllowedMethods, + ) -> pavex::Response { + let response = wrapping_0(s_0).await; + response + } + async fn stage_1<'a>(s_0: &'a pavex::router::AllowedMethods) -> pavex::Response { + let response = handler(s_0).await; + response + } + async fn wrapping_0(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = crate::route_0::Next0 { + s_0: v0, + next: stage_1, + }; + let v2 = pavex::middleware::Next::new(v1); + let v3 = pavex::middleware::wrap_noop(v2).await; + ::into_response(v3) + } + async fn handler(v0: &pavex::router::AllowedMethods) -> pavex::Response { + let v1 = pavex::router::default_fallback(v0).await; + ::into_response(v1) + } + struct Next0<'a, T> + where + T: std::future::Future, + { + s_0: &'a pavex::router::AllowedMethods, + next: fn(&'a pavex::router::AllowedMethods) -> T, + } + impl<'a, T> std::future::IntoFuture for Next0<'a, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0) + } + } +} +pub mod route_1 { + pub async fn entrypoint<'a, 'b, 'c, 'd, 'e>( + s_0: (bool, char, u8), + s_1: &'a alloc::string::String, + s_2: &'b dep_f8f62968::ActualType, + s_3: &'c dep_f8f62968::GenericType, + s_4: &'d dep_f8f62968::GenericType, + s_5: &'e dep_f8f62968::GenericType, + ) -> pavex::Response { + let response = wrapping_0(s_0, s_1, s_2, s_3, s_4, s_5).await; + response + } + async fn stage_1<'a, 'b, 'c, 'd, 'e>( + s_0: &'a alloc::string::String, + s_1: &'b dep_f8f62968::ActualType, + s_2: (bool, char, u8), + s_3: &'c dep_f8f62968::GenericType, + s_4: &'d dep_f8f62968::GenericType, + s_5: &'e dep_f8f62968::GenericType, + ) -> pavex::Response { + let response = handler(s_0, s_1, s_2, s_3, s_4, s_5).await; + response + } + async fn wrapping_0( + v0: (bool, char, u8), + v1: &alloc::string::String, + v2: &dep_f8f62968::ActualType, + v3: &dep_f8f62968::GenericType, + v4: &dep_f8f62968::GenericType, + v5: &dep_f8f62968::GenericType, + ) -> pavex::Response { + let v6 = crate::route_1::Next0 { + s_0: v1, + s_1: v2, + s_2: v0, + s_3: v3, + s_4: v4, + s_5: v5, + next: stage_1, + }; + let v7 = pavex::middleware::Next::new(v6); + let v8 = pavex::middleware::wrap_noop(v7).await; + ::into_response(v8) + } + async fn handler( + v0: &alloc::string::String, + v1: &dep_f8f62968::ActualType, + v2: (bool, char, u8), + v3: &dep_f8f62968::GenericType, + v4: &dep_f8f62968::GenericType, + v5: &dep_f8f62968::GenericType, + ) -> pavex::Response { + let v6 = app_f8f62968::mixed_generics(v0); + let v7 = dep_f8f62968::DoubleLifetimeType::new(v1, v0); + let v8 = app_f8f62968::handler_with_input_tuple(v2, v1, v3, &v7, v6, v4, v5); + ::into_response(v8) + } + struct Next0<'a, 'b, 'c, 'd, 'e, T> + where + T: std::future::Future, + { + s_0: &'a alloc::string::String, + s_1: &'b dep_f8f62968::ActualType, + s_2: (bool, char, u8), + s_3: &'c dep_f8f62968::GenericType, + s_4: &'d dep_f8f62968::GenericType, + s_5: &'e dep_f8f62968::GenericType, + next: fn( + &'a alloc::string::String, + &'b dep_f8f62968::ActualType, + (bool, char, u8), + &'c dep_f8f62968::GenericType, + &'d dep_f8f62968::GenericType, + &'e dep_f8f62968::GenericType, + ) -> T, + } + impl<'a, 'b, 'c, 'd, 'e, T> std::future::IntoFuture for Next0<'a, 'b, 'c, 'd, 'e, T> + where + T: std::future::Future, + { + type Output = pavex::Response; + type IntoFuture = T; + fn into_future(self) -> Self::IntoFuture { + (self.next)(self.s_0, self.s_1, self.s_2, self.s_3, self.s_4, self.s_5) + } + } +} diff --git a/compiler/ui_tests/workspace_hack/Cargo.toml b/compiler/ui_tests/workspace_hack/Cargo.toml index 818e26eda..af5b9a734 100644 --- a/compiler/ui_tests/workspace_hack/Cargo.toml +++ b/compiler/ui_tests/workspace_hack/Cargo.toml @@ -16,30 +16,42 @@ publish = false ### BEGIN HAKARI SECTION [dependencies] futures-core = { version = "0.3" } +getrandom = { version = "0.2", default-features = false, features = ["std"] } +log = { version = "0.4", default-features = false, features = ["std"] } memchr = { version = "2" } +once_cell = { version = "1" } pavex = { path = "../../../runtime/pavex" } percent-encoding = { version = "2" } proc-macro2 = { version = "1", features = ["span-locations"] } quote = { version = "1" } reqwest = { version = "0.12", features = ["json", "rustls-tls"] } +rustls = { version = "0.23", default-features = false, features = ["logging", "ring", "std", "tls12"] } serde = { version = "1", features = ["alloc", "derive", "rc"] } +serde_core = { version = "1", features = ["alloc", "rc"] } serde_json = { version = "1", features = ["raw_value", "unbounded_depth"] } smallvec = { version = "1", default-features = false, features = ["const_new", "serde"] } stable_deref_trait = { version = "1" } +subtle = { version = "2" } syn = { version = "2", features = ["extra-traits", "fold", "full", "visit", "visit-mut"] } tokio = { version = "1", features = ["full"] } [build-dependencies] futures-core = { version = "0.3" } +getrandom = { version = "0.2", default-features = false, features = ["std"] } +log = { version = "0.4", default-features = false, features = ["std"] } memchr = { version = "2" } +once_cell = { version = "1" } percent-encoding = { version = "2" } proc-macro2 = { version = "1", features = ["span-locations"] } quote = { version = "1" } reqwest = { version = "0.12", features = ["json", "rustls-tls"] } +rustls = { version = "0.23", default-features = false, features = ["logging", "ring", "std", "tls12"] } serde = { version = "1", features = ["alloc", "derive", "rc"] } +serde_core = { version = "1", features = ["alloc", "rc"] } serde_json = { version = "1", features = ["raw_value", "unbounded_depth"] } smallvec = { version = "1", default-features = false, features = ["const_new", "serde"] } stable_deref_trait = { version = "1" } +subtle = { version = "2" } syn = { version = "2", features = ["extra-traits", "fold", "full", "visit", "visit-mut"] } tokio = { version = "1", features = ["full"] } diff --git a/examples/realworld/server_sdk/Cargo.toml b/examples/realworld/server_sdk/Cargo.toml index b08e57d9a..8406698e0 100644 --- a/examples/realworld/server_sdk/Cargo.toml +++ b/examples/realworld/server_sdk/Cargo.toml @@ -18,7 +18,7 @@ biscotti = { version = "0.4", default-features = false } http = { version = "1", default-features = false } hyper = { version = "1", default-features = false } jsonwebtoken = { version = "8", default-features = false } -matchit = { version = "0.8", default-features = false } +matchit = { version = "0.9", default-features = false } pavex = { version = "0.2", path = "../../../runtime/pavex", default-features = false } pavex_tracing = { version = "0.2", path = "../../../runtime/pavex_tracing", default-features = false } serde = { version = "1", default-features = false } diff --git a/examples/starter/server_sdk/Cargo.toml b/examples/starter/server_sdk/Cargo.toml index 08e953da4..809989e5d 100644 --- a/examples/starter/server_sdk/Cargo.toml +++ b/examples/starter/server_sdk/Cargo.toml @@ -19,7 +19,7 @@ clippy = { all = "allow" } app = { version = "0.1", path = "../app", default-features = false } http = { version = "1", default-features = false } hyper = { version = "1", default-features = false } -matchit = { version = "0.8", default-features = false } +matchit = { version = "0.9", default-features = false } pavex = { version = "0.2", path = "../../../runtime/pavex", default-features = false } pavex_tracing = { version = "0.2", path = "../../../runtime/pavex_tracing", default-features = false } serde = { version = "1", default-features = false } diff --git a/px_workspace_hack/Cargo.toml b/px_workspace_hack/Cargo.toml index 7d10e2bad..ba6c65b47 100644 --- a/px_workspace_hack/Cargo.toml +++ b/px_workspace_hack/Cargo.toml @@ -26,7 +26,7 @@ clap_builder = { version = "4", default-features = false, features = ["color", " console = { version = "0.16" } crossbeam-utils = { version = "0.8" } crypto-common = { version = "0.1", default-features = false, features = ["getrandom", "std"] } -darling_core = { version = "0.21", default-features = false, features = ["suggestions"] } +darling_core = { version = "0.23", default-features = false, features = ["suggestions"] } digest = { version = "0.10", features = ["mac", "oid", "std"] } either = { version = "1", features = ["serde", "use_std"] } fastrand = { version = "2" } @@ -60,12 +60,11 @@ percent-encoding = { version = "2" } petgraph = { version = "0.8", default-features = false, features = ["graphmap", "stable_graph", "std"] } proc-macro2 = { version = "1", features = ["span-locations"] } quote = { version = "1" } -rand = { version = "0.8" } rand_core = { version = "0.6", default-features = false, features = ["std"] } regex-automata = { version = "0.4", default-features = false, features = ["dfa-build", "dfa-onepass", "hybrid", "meta", "nfa", "perf", "std", "unicode"] } regex-syntax = { version = "0.8" } reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] } -rustls-pki-types = { version = "1", features = ["std"] } +rustls-pki-types = { version = "1", default-features = false, features = ["std"] } semver = { version = "1", features = ["serde"] } serde = { version = "1", features = ["alloc", "derive", "rc"] } serde_core = { version = "1", features = ["alloc", "rc"] } @@ -85,8 +84,7 @@ syn = { version = "2", features = ["extra-traits", "fold", "full", "visit", "vis textwrap = { version = "0.16" } time = { version = "0.3", features = ["formatting", "local-offset", "macros", "parsing"] } tokio = { version = "1", features = ["fs", "io-util", "macros", "net", "rt-multi-thread", "sync", "time"] } -toml-274715c4dabd11b0 = { package = "toml", version = "0.9", features = ["preserve_order"] } -toml-c38e5c1d305a1b54 = { package = "toml", version = "0.8", features = ["preserve_order"] } +toml = { version = "0.9", features = ["preserve_order"] } toml_datetime = { version = "0.7", features = ["serde"] } toml_parser = { version = "1" } toml_writer = { version = "1" } @@ -107,7 +105,7 @@ clap_builder = { version = "4", default-features = false, features = ["color", " console = { version = "0.16" } crossbeam-utils = { version = "0.8" } crypto-common = { version = "0.1", default-features = false, features = ["getrandom", "std"] } -darling_core = { version = "0.21", default-features = false, features = ["suggestions"] } +darling_core = { version = "0.23", default-features = false, features = ["suggestions"] } digest = { version = "0.10", features = ["mac", "oid", "std"] } either = { version = "1", features = ["serde", "use_std"] } fastrand = { version = "2" } @@ -141,12 +139,11 @@ percent-encoding = { version = "2" } petgraph = { version = "0.8", default-features = false, features = ["graphmap", "stable_graph", "std"] } proc-macro2 = { version = "1", features = ["span-locations"] } quote = { version = "1" } -rand = { version = "0.8" } rand_core = { version = "0.6", default-features = false, features = ["std"] } regex-automata = { version = "0.4", default-features = false, features = ["dfa-build", "dfa-onepass", "hybrid", "meta", "nfa", "perf", "std", "unicode"] } regex-syntax = { version = "0.8" } reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] } -rustls-pki-types = { version = "1", features = ["std"] } +rustls-pki-types = { version = "1", default-features = false, features = ["std"] } semver = { version = "1", features = ["serde"] } serde = { version = "1", features = ["alloc", "derive", "rc"] } serde_core = { version = "1", features = ["alloc", "rc"] } @@ -168,8 +165,7 @@ syn = { version = "2", features = ["extra-traits", "fold", "full", "visit", "vis textwrap = { version = "0.16" } time = { version = "0.3", features = ["formatting", "local-offset", "macros", "parsing"] } tokio = { version = "1", features = ["fs", "io-util", "macros", "net", "rt-multi-thread", "sync", "time"] } -toml-274715c4dabd11b0 = { package = "toml", version = "0.9", features = ["preserve_order"] } -toml-c38e5c1d305a1b54 = { package = "toml", version = "0.8", features = ["preserve_order"] } +toml = { version = "0.9", features = ["preserve_order"] } toml_datetime = { version = "0.7", features = ["serde"] } toml_parser = { version = "1" } toml_writer = { version = "1" } diff --git a/runtime/pavex_macros/src/utils/px_stripper.rs b/runtime/pavex_macros/src/utils/px_stripper.rs index fb7d03120..aebf6ab43 100644 --- a/runtime/pavex_macros/src/utils/px_stripper.rs +++ b/runtime/pavex_macros/src/utils/px_stripper.rs @@ -1,6 +1,6 @@ use syn::{ - Attribute, Field, FieldValue, FnArg, ImplItemFn, ItemEnum, ItemImpl, ItemMod, - ItemStruct, ItemTrait, TraitItem, TraitItemFn, Variant, + Attribute, Field, FieldValue, FnArg, ImplItemFn, ItemEnum, ItemImpl, ItemMod, ItemStruct, + ItemTrait, TraitItem, TraitItemFn, Variant, visit_mut::{self, VisitMut}, }; diff --git a/typos.toml b/typos.toml index 4f620026f..4e1f4ba61 100644 --- a/typos.toml +++ b/typos.toml @@ -3,4 +3,4 @@ extend-words = { befores = "befores" } extend-ignore-words-re = ["\\b[a-zA-Z]{2}\\b"] [files] -extend-exclude = ["**/expectations/*", "diagnostics.dot"] +extend-exclude = ["**/expectations/*", "**/generated_app/**", "diagnostics.dot"]