diff --git a/Cargo.lock b/Cargo.lock
index 9985c792d..152417d56 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -770,18 +770,18 @@ dependencies = [
[[package]]
name = "cranelift-bforest"
-version = "0.97.1"
+version = "0.98.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c289b8eac3a97329a524e953b5fd68a8416ca629e1a37287f12d9e0760aadbc"
+checksum = "1380172556902242d32f78ed08c98aac4f5952aef22d3684aed5c66a5db0a6fc"
dependencies = [
"cranelift-entity",
]
[[package]]
name = "cranelift-codegen"
-version = "0.97.1"
+version = "0.98.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7bf07ba80f53fa7f7dc97b11087ea867f7ae4621cfca21a909eca92c0b96c7d9"
+checksum = "037cca234e1ad0766fdfe43b527ec14e100414b4ccf4bb614977aa9754958f57"
dependencies = [
"bumpalo",
"cranelift-bforest",
@@ -800,42 +800,42 @@ dependencies = [
[[package]]
name = "cranelift-codegen-meta"
-version = "0.97.1"
+version = "0.98.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "40a7ca088173130c5c033e944756e3e441fbf3f637f32b4f6eb70252580c6dd4"
+checksum = "d375e6afa8b9a304999ea8cf58424414b8e55e004571265a4f0826eba8b74f18"
dependencies = [
"cranelift-codegen-shared",
]
[[package]]
name = "cranelift-codegen-shared"
-version = "0.97.1"
+version = "0.98.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0114095ec7d2fbd658ed100bd007006360bc2530f57c6eee3d3838869140dbf9"
+checksum = "ca590e72ccb8da963def6e36460cce4412032b1f03c31d1a601838d305abdc39"
[[package]]
name = "cranelift-control"
-version = "0.97.1"
+version = "0.98.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d56031683a55a949977e756d21826eb17a1f346143a1badc0e120a15615cd38"
+checksum = "9d2d38eea4373639f4b6236a40f69820fed16c5511093cd3783bf8491a93d9cf"
dependencies = [
"arbitrary",
]
[[package]]
name = "cranelift-entity"
-version = "0.97.1"
+version = "0.98.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6565198b5684367371e2b946ceca721eb36965e75e3592fad12fc2e15f65d7b"
+checksum = "5e3173c1434af23c00e4964722cf93ca8f0e6287289bf5d52110597c3ba2ea09"
dependencies = [
"serde",
]
[[package]]
name = "cranelift-frontend"
-version = "0.97.1"
+version = "0.98.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "25f28cc44847c8b98cb921e6bfc0f7b228f4d27519376fea724d181da91709a6"
+checksum = "aec4a3a33825062eccf6eec73e852c8773220f6e4798925e19696562948beb1f"
dependencies = [
"cranelift-codegen",
"log",
@@ -845,15 +845,15 @@ dependencies = [
[[package]]
name = "cranelift-isle"
-version = "0.97.1"
+version = "0.98.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "80b658177e72178c438f7de5d6645c56d97af38e17fcb0b500459007b4e05cc5"
+checksum = "5146b5cea4b21095a021d964b0174cf6ff5530f83e8d0a822683c7559e360b66"
[[package]]
name = "cranelift-native"
-version = "0.97.1"
+version = "0.98.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf1c7de7221e6afcc5e13ced3b218faab3bc65b47eac67400046a05418aecd6a"
+checksum = "21cec3717ce554d3936b2101aa8eae1a2a410bd6da0f4df698a4b008fe9cf1e9"
dependencies = [
"cranelift-codegen",
"libc",
@@ -862,9 +862,9 @@ dependencies = [
[[package]]
name = "cranelift-wasm"
-version = "0.97.1"
+version = "0.98.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "76b0d28ebe8edb6b503630c489aa4669f1e2d13b97bec7271a0fcb0e159be3ad"
+checksum = "d7fd2f9f1bf29ce6639ae2f477a2fe20bad0bd09289df13efeb890e8e4b9f807"
dependencies = [
"cranelift-codegen",
"cranelift-entity",
@@ -3750,9 +3750,9 @@ dependencies = [
[[package]]
name = "regalloc2"
-version = "0.9.1"
+version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "12513beb38dd35aab3ac5f5b89fd0330159a0dc21d5309d75073011bbc8032b0"
+checksum = "5b4dcbd3a2ae7fb94b5813fa0e957c6ab51bf5d0a8ee1b69e0c2d0f1e6eb8485"
dependencies = [
"hashbrown 0.13.2",
"log",
@@ -5611,9 +5611,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasi-cap-std-sync"
-version = "10.0.1"
+version = "11.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "291862f1014dd7e674f93b263d57399de4dd1907ea37e74cf7d36454536ba2f0"
+checksum = "dc0fb9a3b1143c8f549b64d707aef869d134fb681f17fb316f0d796537b670ef"
dependencies = [
"anyhow",
"async-trait",
@@ -5635,9 +5635,9 @@ dependencies = [
[[package]]
name = "wasi-common"
-version = "10.0.1"
+version = "11.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3b422ae2403cae9ca603864272a402cf5001dd6fef8632e090e00c4fb475741b"
+checksum = "41512a0523d86be06d7cf606e1bafd0238948b237ce832179f85dfdbce217e1a"
dependencies = [
"anyhow",
"bitflags 1.3.2",
@@ -5782,9 +5782,9 @@ dependencies = [
[[package]]
name = "wasmrs"
-version = "0.13.0"
+version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94eaf073a819835e7bf712f6afbc8f3f04790cf6e57fd48b86e3ceac1f1c5582"
+checksum = "d9e639ca1fefefe446ed77443865dd2298ed5a22e22992944e2b03d931cf11ab"
dependencies = [
"bytes 1.4.0",
"crossbeam-channel",
@@ -5804,9 +5804,9 @@ dependencies = [
[[package]]
name = "wasmrs-codec"
-version = "0.13.0"
+version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "20f90276d9d3c49951c3073b2845ac3dc2cee446722ea4904bb768419c36b6be"
+checksum = "aa033a409e0a05d24013fdf15becafaba5e13c3eee1706dd687e63ff6e5aa2e2"
dependencies = [
"heapless",
"rmp-serde",
@@ -5816,9 +5816,9 @@ dependencies = [
[[package]]
name = "wasmrs-frames"
-version = "0.13.0"
+version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff7f452a1908fb0f2d08db7752b9dc69bdeea647fa1841f469ef3ad98815956c"
+checksum = "5379743c49fe234b5191beb98c9891ce6f90df2358f442d124bc3b10857ff74c"
dependencies = [
"bytes 1.4.0",
"serde",
@@ -5826,9 +5826,9 @@ dependencies = [
[[package]]
name = "wasmrs-guest"
-version = "0.13.0"
+version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d50bc90ea73c739b11440c0e15674a4b8c197a0f1c120bd0ab5930f5d699eccd"
+checksum = "c80fe87a96b758f19ee3c96bffcbd14549affc32a7811dfccb8f0e2acd119616"
dependencies = [
"bytes 1.4.0",
"cfg-if",
@@ -5846,9 +5846,9 @@ dependencies = [
[[package]]
name = "wasmrs-host"
-version = "0.13.0"
+version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "893d9df34fc322f708164af52fdbd7a0a3a853808f99c9e91c87dab58915eeaf"
+checksum = "e65e784317f0230060b69f4ed340bb41ec93cd08af4fd074d347da806457b573"
dependencies = [
"bytes 1.4.0",
"dashmap",
@@ -5867,9 +5867,9 @@ dependencies = [
[[package]]
name = "wasmrs-runtime"
-version = "0.13.0"
+version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "86a76568a0617b94230c08566e0e4dc1bdd4e953bb8f73ef3617f29cc025bb3a"
+checksum = "be63ea5457fca88c949665f1dcf0752842777baa762af5d6d053aa8a8576cb3d"
dependencies = [
"bytes 1.4.0",
"crossbeam-channel",
@@ -5886,9 +5886,9 @@ dependencies = [
[[package]]
name = "wasmrs-rx"
-version = "0.13.0"
+version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85a7878f17e23c775cb6cbf40c66651076b3bc483ffe5396a4b17874d2114a35"
+checksum = "5b2ae214a4ff7272c6d4f718626f9a4a85d239be37c8059e7952ec32b99189d5"
dependencies = [
"async-trait",
"bytes 1.4.0",
@@ -5905,9 +5905,9 @@ dependencies = [
[[package]]
name = "wasmrs-wasmtime"
-version = "0.13.0"
+version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e37873388158d075e51a75323815ec1fcc03b18509bc2ba462394c71f58ffc9"
+checksum = "cabd9acf03dd9a9273a3b785e9e6db98ad3f342716cfee43947d375da761d17d"
dependencies = [
"anyhow",
"bytes 1.4.0",
@@ -5927,9 +5927,9 @@ dependencies = [
[[package]]
name = "wasmtime"
-version = "10.0.1"
+version = "11.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd02b992d828b91efaf2a7499b21205fe4ab3002e401e3fe0f227aaeb4001d93"
+checksum = "0b1f817f2ca5070983c71f1205fbab5848c9073df7f4e1af9fdceb4cc4a1b8e5"
dependencies = [
"anyhow",
"async-trait",
@@ -5965,18 +5965,18 @@ dependencies = [
[[package]]
name = "wasmtime-asm-macros"
-version = "10.0.1"
+version = "11.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "284466ef356ce2d909bc0ad470b60c4d0df5df2de9084457e118131b3c779b92"
+checksum = "0f82fbfda4610e9225238c62574ecded8e9d6ad3a12f387ac45819ecad5c3f9b"
dependencies = [
"cfg-if",
]
[[package]]
name = "wasmtime-cache"
-version = "10.0.1"
+version = "11.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "efc78cfe1a758d1336f447a47af6ec05e0df2c03c93440d70faf80e17fbb001e"
+checksum = "b4f5b87f1ed383d6c219c04467ab6ae87990d6c2815d5a990138990a7fcbab95"
dependencies = [
"anyhow",
"base64 0.21.2",
@@ -5994,9 +5994,9 @@ dependencies = [
[[package]]
name = "wasmtime-component-macro"
-version = "10.0.1"
+version = "11.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8e916103436a6d84faa4c2083e2e98612a323c2cc6147ec419124f67c764c9c"
+checksum = "e27b96c540c78e12b60025fcbc0ba8a55bff1b32885a5e8eae2df765a6bc97ac"
dependencies = [
"anyhow",
"proc-macro2",
@@ -6009,15 +6009,15 @@ dependencies = [
[[package]]
name = "wasmtime-component-util"
-version = "10.0.1"
+version = "11.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f20a5135ec5ef01080e674979b02d6fa5eebaa2b0c2d6660513ee9956a1bf624"
+checksum = "0928fe66c22bf8887e2fb524b7647308b8ce836a333af8504e4f1d80b8ea849f"
[[package]]
name = "wasmtime-cranelift"
-version = "10.0.1"
+version = "11.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e1aa99cbf3f8edb5ad8408ba380f5ab481528ecd8a5053acf758e006d6727fd"
+checksum = "b659f6e58662d1131f250339acd03aa49377f9351474282699985b79ca4d4a7c"
dependencies = [
"anyhow",
"cranelift-codegen",
@@ -6038,9 +6038,9 @@ dependencies = [
[[package]]
name = "wasmtime-cranelift-shared"
-version = "10.0.1"
+version = "11.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cce31fd55978601acc103acbb8a26f81c89a6eae12d3a1c59f34151dfa609484"
+checksum = "74171de083bf2ecb716c507900f825e2b858346c714fbf48f4763ea760f998a8"
dependencies = [
"anyhow",
"cranelift-codegen",
@@ -6054,9 +6054,9 @@ dependencies = [
[[package]]
name = "wasmtime-environ"
-version = "10.0.1"
+version = "11.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41f9e58e0ee7d43ff13e75375c726b16bce022db798d3a099a65eeaa7d7a544b"
+checksum = "b124cbac1a3e04a744c76b3f77919343ef16dc4c818a2406dd7b689b16a54639"
dependencies = [
"anyhow",
"cranelift-entity",
@@ -6076,9 +6076,9 @@ dependencies = [
[[package]]
name = "wasmtime-fiber"
-version = "10.0.1"
+version = "11.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "14309cbdf2c395258b124a24757c727403070c0465a28bcc780c4f82f4bca5ff"
+checksum = "f92ffb8869395c63100ffefbd71cf9489e7e9218e63a3798dcfe93fa8945f9cf"
dependencies = [
"cc",
"cfg-if",
@@ -6089,9 +6089,9 @@ dependencies = [
[[package]]
name = "wasmtime-jit"
-version = "10.0.1"
+version = "11.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f0f2eaeb01bb67266416507829bd8e0bb60278444e4cbd048e280833ebeaa02"
+checksum = "90ff15f426c2378f32ffb6d9b4370e3504231492e93f6968e8b5102c3256bbc4"
dependencies = [
"addr2line 0.19.0",
"anyhow",
@@ -6115,9 +6115,9 @@ dependencies = [
[[package]]
name = "wasmtime-jit-debug"
-version = "10.0.1"
+version = "11.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f42e59d62542bfb73ce30672db7eaf4084a60b434b688ac4f05b287d497de082"
+checksum = "c549e219102426aa1f90bd18e56a3195ed1e696c318abb3f501c1f4924b530ac"
dependencies = [
"object 0.30.4",
"once_cell",
@@ -6126,9 +6126,9 @@ dependencies = [
[[package]]
name = "wasmtime-jit-icache-coherence"
-version = "10.0.1"
+version = "11.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b49ceb7e2105a8ebe5614d7bbab6f6ef137a284e371633af60b34925493081f"
+checksum = "1cf02fedda287a409cff80ad40a7c6c0f0771e99b0cd5e2b79d9cb7ecdc1b2f4"
dependencies = [
"cfg-if",
"libc",
@@ -6137,9 +6137,9 @@ dependencies = [
[[package]]
name = "wasmtime-runtime"
-version = "10.0.1"
+version = "11.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a5de4762421b0b2b19e02111ca403632852b53e506e03b4b227ffb0fbfa63c2"
+checksum = "fc38c6229a5d3b8a2528eb33eb11d3e7ebf570259c7cd2f01e8668fe783ea443"
dependencies = [
"anyhow",
"cc",
@@ -6164,9 +6164,9 @@ dependencies = [
[[package]]
name = "wasmtime-types"
-version = "10.0.1"
+version = "11.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dcbb7c138f797192f46afdd3ec16f85ef007c3bb45fa8e5174031f17b0be4c4a"
+checksum = "768f6c5e7afc3a02eff2753196741db8e5ac5faf26a1e2204d7341b30a637c6f"
dependencies = [
"cranelift-entity",
"serde",
@@ -6176,9 +6176,9 @@ dependencies = [
[[package]]
name = "wasmtime-wasi"
-version = "10.0.1"
+version = "11.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "01686e859249d4dffe3d7ce9957ae35bcf4161709dfafd165ee136bd54d179f1"
+checksum = "ff7bb52cc5f9f3878cb012c5e42296e2fbb96e5407301b1e8e7007deec8dca9c"
dependencies = [
"anyhow",
"async-trait",
@@ -6203,9 +6203,9 @@ dependencies = [
[[package]]
name = "wasmtime-winch"
-version = "10.0.1"
+version = "11.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "60160d8f7d2b301790730dac8ff25156c61d4fed79481e7074c21dd1283cfe2f"
+checksum = "b2249faeb887b8b7e7b1797c460ac76160654aea3b8d5842093a771d77fc3819"
dependencies = [
"anyhow",
"cranelift-codegen",
@@ -6220,9 +6220,9 @@ dependencies = [
[[package]]
name = "wasmtime-wit-bindgen"
-version = "10.0.1"
+version = "11.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3334b0466a4d340de345cda83474d1d2c429770c3d667877971407672bc618a"
+checksum = "84a4a005a6a2d5faa7cd953d389da8ae979cb571fe40edec7769649d8c98d874"
dependencies = [
"anyhow",
"heck 0.4.1",
@@ -6380,6 +6380,7 @@ name = "wick-component"
version = "0.15.0"
dependencies = [
"anyhow",
+ "async-recursion",
"bytes 1.4.0",
"chrono",
"flow-component",
@@ -6397,6 +6398,7 @@ dependencies = [
"wasmrs-runtime",
"wasmrs-rx",
"wick-logger",
+ "wick-operation",
"wick-packet",
]
@@ -6685,6 +6687,18 @@ dependencies = [
"wick-xdg",
]
+[[package]]
+name = "wick-operation"
+version = "0.1.0"
+dependencies = [
+ "proc-macro-crate",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.25",
+ "tokio",
+ "wick-logger",
+]
+
[[package]]
name = "wick-package"
version = "0.2.0"
@@ -6734,6 +6748,7 @@ dependencies = [
"wasmrs-codec",
"wasmrs-frames",
"wasmrs-guest",
+ "wasmrs-runtime",
"wasmrs-rx",
"wick-interface-types",
]
@@ -6918,9 +6933,9 @@ dependencies = [
[[package]]
name = "wiggle"
-version = "10.0.1"
+version = "11.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea93d31f59f2b2fa4196990b684771500072d385eaac12587c63db2bc185d705"
+checksum = "a89f0d9c91096db5e250cb803500bddfdd65ae3268a9e09283b75d3b513ede7a"
dependencies = [
"anyhow",
"async-trait",
@@ -6933,9 +6948,9 @@ dependencies = [
[[package]]
name = "wiggle-generate"
-version = "10.0.1"
+version = "11.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7df96ee6bea595fabf0346c08c553f684b08e88fad6fdb125e6efde047024f7b"
+checksum = "12b5552356799612587de885e02b7e7e7d39e41657af1ddb985d18fbe5ac1642"
dependencies = [
"anyhow",
"heck 0.4.1",
@@ -6948,9 +6963,9 @@ dependencies = [
[[package]]
name = "wiggle-macro"
-version = "10.0.1"
+version = "11.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8649011a011ecca6197c4db6ee630735062ba20595ea56ce58529b3b1c20aa2f"
+checksum = "2ca58f5cfecefaec28b09bfb6197a52dbd24df4656154bd377a166f1031d9b17"
dependencies = [
"proc-macro2",
"quote",
@@ -7004,9 +7019,9 @@ dependencies = [
[[package]]
name = "winch-codegen"
-version = "0.8.1"
+version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "525fdd0d4e82d1bd3083bd87e8ca8014abfbdc5bf290d1d5371dac440d351e89"
+checksum = "21de111a36e8f367416862fdf6f10caa411cc07a6e21b614eedbf9388c2a3dc9"
dependencies = [
"anyhow",
"cranelift-codegen",
diff --git a/Cargo.toml b/Cargo.toml
index 8e71a4791..3fbe0db79 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,20 +7,9 @@ members = [
"crates/components/*",
"crates/bins/*",
"crates/wick/*",
- "tests/*"
-]
-exclude = [
- "crates/wick/wick-rpc/codegen",
- "crates/integration/test-baseline-component",
- "crates/integration/test-cli-trigger-component",
- "crates/integration/test-cli-with-db",
- "crates/integration/test-http-trigger-component",
- "tests/template",
- "tests/testdata",
- "examples/http/middleware/request",
- "examples/http/wasm-http-call/wasm-component",
- "examples/cli/cli-maker",
+ "tests/*",
]
+exclude = ["crates/wick/wick-rpc/codegen", "tests/template", "tests/testdata"]
[profile.release-with-debug]
inherits = "release"
@@ -45,6 +34,7 @@ wick-host = { path = "./crates/wick/wick-host", version = "0.4.0" }
wick-interface-types = { path = "./crates/wick/wick-interface-types", version = "0.15.0" }
wick-invocation-server = { path = "./crates/wick/wick-invocation-server", version = "0.1.0" }
wick-oci-utils = { path = "./crates/wick/wick-oci-utils", version = "0.3.0", default-features = false }
+wick-operation = { path = "./crates/wick/wick-operation", version = "0.1.0", default-features = false }
wick-package = { path = "./crates/wick/wick-package", version = "0.2.0" }
wick-packet = { path = "./crates/wick/wick-packet", version = "0.15.0", default-features = false }
wick-settings = { path = "./crates/wick/wick-settings", version = "0.1.0" }
@@ -74,24 +64,24 @@ wick-interface-cli = { path = "./crates/interfaces/wick-interface-cli", version
wick-sql = { path = "./crates/components/wick-sql", version = "0.1.0" }
wick-http-client = { path = "./crates/components/wick-http-client", version = "0.1.0" }
# wasmtime (must align with version in wasmrs)
-wasmtime = { version = "10.0.1", default-features = false, features = [
+wasmtime = { version = "11.0", default-features = false, features = [
"cache",
"jitdump",
"parallel-compilation",
"cranelift",
- "vtune"
+ "vtune",
] }
-wasmtime-wasi = { version = "10.0.1", features = ["sync"] }
-wasi-common = { version = "10.0.1" }
+wasmtime-wasi = { version = "11.0", features = ["sync"] }
+wasi-common = { version = "11.0" }
# wasmrs
-wasmrs = { version = "0.13.0" }
-wasmrs-codec = { version = "0.13.0" }
-wasmrs-frames = { version = "0.13.0" }
-wasmrs-guest = { version = "0.13.0" }
-wasmrs-host = { version = "0.13.0" }
-wasmrs-runtime = { version = "0.13.0" }
-wasmrs-rx = { version = "0.13.0" }
-wasmrs-wasmtime = { version = "0.13.0" }
+wasmrs = { version = "0.14.0" }
+wasmrs-codec = { version = "0.14.0" }
+wasmrs-frames = { version = "0.14.0" }
+wasmrs-guest = { version = "0.14.0" }
+wasmrs-host = { version = "0.14.0" }
+wasmrs-runtime = { version = "0.14.0" }
+wasmrs-rx = { version = "0.14.0" }
+wasmrs-wasmtime = { version = "0.14.0" }
#
# Other
#
diff --git a/Justfile b/Justfile
index 16ee8d632..87f77d669 100644
--- a/Justfile
+++ b/Justfile
@@ -8,6 +8,12 @@ rustup := `command -v rustup >/dev/null && echo true || echo false`
# use #!{{python}} to ensure that the python path is correct across platforms.
python := if os() == 'windows' { 'python' } else { '/usr/bin/env python3' }
+# The wick repository
+repository := "https://github.com/candlecorp/wick"
+
+# The root directory of this project
+wick_root := justfile_directory()
+
set dotenv-load
set positional-arguments
set export
@@ -70,7 +76,7 @@ wick-tests:
just _wick-db-tests
# Run tests suitable for CI
-ci-tests: wasm
+ci-tests: install-dev wasm
just unit-tests
# Run unit, integration, and slow tests
@@ -145,6 +151,18 @@ rustdoc:
mkdir -p docs/static/rustdoc/
rsync -av --delete --exclude=".*" target/doc/ docs/static/rustdoc/
+# Quickly generate a new rust WebAssembly example
+new-rust-example name path="examples/components":
+ echo "Generating new rust example: {{name}}"
+ echo "Note: This is optimized for macOS, if it breaks on your platform, please open an issue at {{repository}}"
+ cd {{path}} && cargo generate -p {{wick_root}}/templates/rust --name {{name}}
+
+ RELATIVE=$(realpath --relative-to={{wick_root}}/{{path}}/{{name}} {{wick_root}}); \
+ sed -E -i '' "s,([A-Za-z0-9_-]*) = { git = \\\"{{repository}}.git\\\",\\1 = { path = \\\"$RELATIVE/crates/wick/\\1\\\",g" "{{wick_root}}/{{path}}/{{name}}/Cargo.toml"; \
+ sed -E -i '' "s,wick := \\\"wick\\\",wick := \\\"cargo run --manifest-path=$RELATIVE/Cargo.toml -p wick-cli --\\\",g" "{{wick_root}}/{{path}}/{{name}}/justfile";
+
+ echo "New rust example generated at {{path}}/{{name}}"
+
##################################
### Private, dependency tasks. ###
##################################
@@ -191,6 +209,7 @@ _run-wasm-task task:
"crates/integration/test-cli-trigger-component",
"crates/integration/test-cli-with-db",
"examples/http/middleware/request",
+ "examples/components/wasi-fs",
"examples/http/wasm-http-call/wasm-component",
]
for dir in wasm:
@@ -209,6 +228,7 @@ _wick-http-tests:
_wick-component-tests:
cargo run -p wick-cli -- test ./examples/components/hello-world.wick
cargo run -p wick-cli -- test ./examples/components/composite-db-import.wick
+ DIR=./examples/components/wasi-fs/ cargo run -p wick-cli -- test ./examples/components/wasi-fs/component.wick
# Run component-codegen unit tests
_codegen-tests:
diff --git a/crates/bins/wick/src/commands/invoke.rs b/crates/bins/wick/src/commands/invoke.rs
index 89f5fee88..fc8221f1d 100644
--- a/crates/bins/wick/src/commands/invoke.rs
+++ b/crates/bins/wick/src/commands/invoke.rs
@@ -16,9 +16,6 @@ use crate::wick_host::build_component_host;
#[clap(rename_all = "kebab-case")]
#[group(skip)]
pub(crate) struct Options {
- #[clap(flatten)]
- wasi: crate::wasm::WasiOptions,
-
#[clap(flatten)]
pub(crate) oci: crate::oci::Options,
diff --git a/crates/bins/wick/src/commands/serve.rs b/crates/bins/wick/src/commands/serve.rs
index 0ed6fc475..5527e47e2 100644
--- a/crates/bins/wick/src/commands/serve.rs
+++ b/crates/bins/wick/src/commands/serve.rs
@@ -17,9 +17,6 @@ pub(crate) struct Options {
#[clap(flatten)]
pub(crate) oci: crate::oci::Options,
- #[clap(flatten)]
- wasi: crate::wasm::WasiOptions,
-
/// The path or OCI URL to a wick manifest or wasm file.
#[clap(action)]
pub(crate) location: String,
diff --git a/crates/bins/wick/src/commands/test.rs b/crates/bins/wick/src/commands/test.rs
index b6d1cc91e..bce768760 100644
--- a/crates/bins/wick/src/commands/test.rs
+++ b/crates/bins/wick/src/commands/test.rs
@@ -22,9 +22,6 @@ pub(crate) struct Options {
#[clap(flatten)]
pub(crate) oci: crate::oci::Options,
- #[clap(flatten)]
- wasi: crate::wasm::WasiOptions,
-
/// Turn on info logging.
#[clap(long = "info", action)]
pub(crate) info: bool,
diff --git a/crates/bins/wick/src/commands/wasm/sign.rs b/crates/bins/wick/src/commands/wasm/sign.rs
index b70bf0075..6c034c333 100644
--- a/crates/bins/wick/src/commands/wasm/sign.rs
+++ b/crates/bins/wick/src/commands/wasm/sign.rs
@@ -57,7 +57,7 @@ pub(crate) async fn handle(
source_file.read_to_end(&mut buf).unwrap();
let (account, subject) = get_module_keys(
- Some(opts.source.clone()),
+ interface.name().map(|s| s.as_str()),
opts.common.directory,
opts.common.signer,
opts.common.subject,
diff --git a/crates/bins/wick/src/keys.rs b/crates/bins/wick/src/keys.rs
index 44c63103d..257c7242f 100644
--- a/crates/bins/wick/src/keys.rs
+++ b/crates/bins/wick/src/keys.rs
@@ -65,39 +65,39 @@ fn get_key_home() -> PathBuf {
}
pub(crate) async fn get_module_keys(
- subject_file: Option,
+ name: Option<&str>,
directory: Option,
signer_key: Option,
subject_key: Option,
) -> Result<(KeyPair, KeyPair)> {
let account_keys = match signer_key {
Some(seed) => KeyPair::from_seed(&seed)?,
- None => get_or_create(subject_file.clone(), directory.clone(), KeyPairType::Account).await?,
+ None => get_or_create(name, directory.clone(), KeyPairType::Account).await?,
};
let subject_keys = match subject_key {
Some(seed) => KeyPair::from_seed(&seed)?,
- None => get_or_create(subject_file, directory, KeyPairType::Module).await?,
+ None => get_or_create(name, directory, KeyPairType::Module).await?,
};
Ok((account_keys, subject_keys))
}
pub(crate) async fn get_or_create(
- subject: Option,
+ name: Option<&str>,
directory: Option,
kp_type: KeyPairType,
) -> Result {
- if subject.is_none() {
- return Err(anyhow!("Keypair path or string not supplied."));
+ if name.is_none() {
+ return Err(anyhow!("Component name must be supplied to generate signing keys."));
}
- let module = subject.unwrap();
+ let name = name.unwrap();
let dir = directory.map_or_else(get_key_home, |dir| dir);
let module_name = match kp_type {
KeyPairType::Account => std::env::var("USER").unwrap_or_else(|_| "user".to_owned()),
- _ => PathBuf::from(module).file_stem().unwrap().to_str().unwrap().to_owned(),
+ _ => PathBuf::from(name).file_stem().unwrap().to_str().unwrap().to_owned(),
};
let path = format!(
diff --git a/crates/bins/wick/src/wasm.rs b/crates/bins/wick/src/wasm.rs
index aea0906b2..fcf329622 100644
--- a/crates/bins/wick/src/wasm.rs
+++ b/crates/bins/wick/src/wasm.rs
@@ -1,8 +1,5 @@
use std::str::FromStr;
-use clap::Args;
-use wick_config::config::components::Permissions;
-
#[derive(Clone, Debug)]
struct StringPair(String, String);
@@ -15,17 +12,3 @@ impl FromStr for StringPair {
.ok_or_else(|| anyhow!("WASI directories need to be string pairs split by a colon, e.g. /to/dir:/from/dir"))
}
}
-
-#[derive(Debug, Clone, Args)]
-pub(crate) struct WasiOptions {
- /// Directories to expose to the WASM module via WASI. Ignored if loading a manifest.
- #[clap(long = "dirs", value_parser)]
- wasi_dir: Vec,
-}
-
-impl From for Permissions {
- fn from(opts: WasiOptions) -> Self {
- let dirs = opts.wasi_dir.into_iter().map(|v| (v.0, v.1)).collect();
- Self::new(dirs)
- }
-}
diff --git a/crates/components/wick-http-client/src/component.rs b/crates/components/wick-http-client/src/component.rs
index c376f4db7..aa720e2e7 100644
--- a/crates/components/wick-http-client/src/component.rs
+++ b/crates/components/wick-http-client/src/component.rs
@@ -57,7 +57,6 @@ impl HttpClientComponent {
) -> Result {
validate(&config, resolver)?;
let addr: UrlResource = resolver(config.resource())
- .ok_or_else(|| ComponentError::message(&format!("Could not resolve resource ID {}", config.resource())))?
.and_then(|r| r.try_resource())
.map_err(ComponentError::new)?
.into();
diff --git a/crates/components/wick-sql/src/common.rs b/crates/components/wick-sql/src/common.rs
index 3558dd2c9..cdaa1e542 100644
--- a/crates/components/wick-sql/src/common.rs
+++ b/crates/components/wick-sql/src/common.rs
@@ -33,10 +33,7 @@ pub(crate) fn gen_signature(
}
pub(crate) fn convert_url_resource(resolver: &Resolver, id: &str) -> Result {
- let addr = resolver(id)
- .ok_or_else(|| Error::ResourceNotFound(id.to_owned()))?
- .and_then(|r| r.try_resource())
- .map_err(Error::InvalidResource)?;
+ let addr = resolver(id).and_then(|r| r.try_resource())?;
let resource: UrlResource = addr.into();
resource.url().value().cloned().ok_or(Error::InvalidResourceConfig)
diff --git a/crates/components/wick-sql/src/error.rs b/crates/components/wick-sql/src/error.rs
index faf0cecda..1c14524ef 100644
--- a/crates/components/wick-sql/src/error.rs
+++ b/crates/components/wick-sql/src/error.rs
@@ -67,14 +67,11 @@ pub enum Error {
#[error(transparent)]
ComponentError(wick_packet::Error),
- #[error("Could not resolve resource: {0}")]
- ResourceNotFound(String),
-
#[error("Database connection not initialized")]
Uninitialized,
- #[error("Invalid resource passed to component: {0}")]
- InvalidResource(ManifestError),
+ #[error(transparent)]
+ Configuration(#[from] ManifestError),
#[error("Resource valid but its value could not be retrieved")]
InvalidResourceConfig,
diff --git a/crates/integration/test-baseline-component/Cargo.toml b/crates/integration/test-baseline-component/Cargo.toml
index efe2cd3b4..002198870 100644
--- a/crates/integration/test-baseline-component/Cargo.toml
+++ b/crates/integration/test-baseline-component/Cargo.toml
@@ -24,8 +24,11 @@ wick-component = { path = "../../wick/wick-component", features = ["datetime"] }
serde = { version = "1", features = ["derive"] }
async-trait = "0.1"
seeded-random = { path = "../../misc/seeded-random", default-features = false, features = [
- "uuid"
+ "uuid",
] }
[build-dependencies]
wick-component-codegen = { path = "../../wick/wick-component-codegen" }
+
+# Including this section keeps this crate out of a workspace without needing to alter the workspace.
+[workspace]
diff --git a/crates/integration/test-baseline-component/src/lib.rs b/crates/integration/test-baseline-component/src/lib.rs
index 3d43617f2..69d12aa57 100644
--- a/crates/integration/test-baseline-component/src/lib.rs
+++ b/crates/integration/test-baseline-component/src/lib.rs
@@ -13,7 +13,7 @@ use wick::*;
#[cfg_attr(target_family = "wasm",async_trait::async_trait(?Send))]
#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait(Send))]
-impl AddOperation for Component {
+impl add::Operation for Component {
type Error = String;
type Outputs = add::Outputs;
type Config = add::Config;
@@ -34,7 +34,7 @@ impl AddOperation for Component {
}
(Err(err), _) | (_, Err(err)) => {
println!("op:add: received error, propagating forward");
- outputs.output.error(format!("Error adding numbers: {}", err));
+ outputs.output.error(&format!("Error adding numbers: {}", err));
}
}
}
@@ -46,7 +46,7 @@ impl AddOperation for Component {
#[cfg_attr(target_family = "wasm",async_trait::async_trait(?Send))]
#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait(Send))]
-impl PowerOperation for Component {
+impl power::Operation for Component {
type Error = String;
type Outputs = power::Outputs;
type Config = power::Config;
@@ -68,7 +68,7 @@ impl PowerOperation for Component {
#[cfg_attr(target_family = "wasm",async_trait::async_trait(?Send))]
#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait(Send))]
-impl ErrorOperation for Component {
+impl error::Operation for Component {
type Error = String;
type Outputs = error::Outputs;
type Config = error::Config;
@@ -92,7 +92,7 @@ impl ErrorOperation for Component {
#[cfg_attr(target_family = "wasm",async_trait::async_trait(?Send))]
#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait(Send))]
-impl UuidOperation for Component {
+impl uuid::Operation for Component {
type Error = String;
type Outputs = uuid::Outputs;
type Config = uuid::Config;
@@ -108,7 +108,7 @@ impl UuidOperation for Component {
#[cfg_attr(target_family = "wasm",async_trait::async_trait(?Send))]
#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait(Send))]
-impl ValidateOperation for Component {
+impl validate::Operation for Component {
type Error = String;
type Outputs = validate::Outputs;
type Config = validate::Config;
@@ -123,10 +123,10 @@ impl ValidateOperation for Component {
if password.len() < MINIMUM_LENGTH {
println!("Too short!");
- outputs.output.error(LengthError::TooShort.to_string());
+ outputs.output.error(&LengthError::TooShort.to_string());
} else if password.len() > MAXIMUM_LENGTH {
println!("Too long!!");
- outputs.output.error(LengthError::TooLong.to_string());
+ outputs.output.error(&LengthError::TooLong.to_string());
} else {
println!("Just right!");
outputs.output.send(&password);
@@ -167,7 +167,7 @@ static MAXIMUM_LENGTH: usize = 512;
#[cfg_attr(target_family = "wasm",async_trait::async_trait(?Send))]
#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait(Send))]
-impl StrftimeOperation for Component {
+impl strftime::Operation for Component {
type Error = String;
type Outputs = strftime::Outputs;
type Config = strftime::Config;
diff --git a/crates/integration/test-cli-trigger-component/Cargo.toml b/crates/integration/test-cli-trigger-component/Cargo.toml
index 1dbec5706..a21e1ce7f 100644
--- a/crates/integration/test-cli-trigger-component/Cargo.toml
+++ b/crates/integration/test-cli-trigger-component/Cargo.toml
@@ -27,3 +27,6 @@ anyhow = "1.0"
[build-dependencies]
wick-component-codegen = { path = "../../wick/wick-component-codegen" }
+
+# Including this section keeps this crate out of a workspace without needing to alter the workspace.
+[workspace]
diff --git a/crates/integration/test-cli-trigger-component/src/lib.rs b/crates/integration/test-cli-trigger-component/src/lib.rs
index 8631d45e0..a8c1e70b9 100644
--- a/crates/integration/test-cli-trigger-component/src/lib.rs
+++ b/crates/integration/test-cli-trigger-component/src/lib.rs
@@ -13,7 +13,7 @@ use wick::*;
#[cfg_attr(target_family = "wasm",async_trait::async_trait(?Send))]
#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
-impl MainOperation for Component {
+impl main::Operation for Component {
type Error = anyhow::Error;
type Outputs = main::Outputs;
type Config = main::Config;
diff --git a/crates/integration/test-cli-with-db/Cargo.toml b/crates/integration/test-cli-with-db/Cargo.toml
index 500226cac..76055ae67 100644
--- a/crates/integration/test-cli-with-db/Cargo.toml
+++ b/crates/integration/test-cli-with-db/Cargo.toml
@@ -29,3 +29,6 @@ console = "0.15"
[build-dependencies]
wick-component-codegen = { path = "../../wick/wick-component-codegen" }
+
+# Including this section keeps this crate out of a workspace without needing to alter the workspace.
+[workspace]
diff --git a/crates/integration/test-cli-with-db/src/lib.rs b/crates/integration/test-cli-with-db/src/lib.rs
index 1060b6ffa..5ffd23a5c 100644
--- a/crates/integration/test-cli-with-db/src/lib.rs
+++ b/crates/integration/test-cli-with-db/src/lib.rs
@@ -13,7 +13,7 @@ use wick::*;
#[cfg_attr(target_family = "wasm",async_trait::async_trait(?Send))]
#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
-impl MainOperation for Component {
+impl main::Operation for Component {
type Error = Box;
type Outputs = main::Outputs;
type Config = main::Config;
diff --git a/crates/integration/test-http-trigger-component/Cargo.toml b/crates/integration/test-http-trigger-component/Cargo.toml
index e0528edc8..54186fe07 100644
--- a/crates/integration/test-http-trigger-component/Cargo.toml
+++ b/crates/integration/test-http-trigger-component/Cargo.toml
@@ -29,3 +29,6 @@ serde_json = "1.0.94"
[build-dependencies]
wick-component-codegen = { path = "../../wick/wick-component-codegen" }
+
+# Including this section keeps this crate out of a workspace without needing to alter the workspace.
+[workspace]
diff --git a/crates/integration/test-http-trigger-component/src/lib.rs b/crates/integration/test-http-trigger-component/src/lib.rs
index 10e4e807c..c3a247378 100644
--- a/crates/integration/test-http-trigger-component/src/lib.rs
+++ b/crates/integration/test-http-trigger-component/src/lib.rs
@@ -23,7 +23,7 @@ struct Response {
#[cfg_attr(target_family = "wasm",async_trait::async_trait(?Send))]
#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
-impl HttpHandlerOperation for Component {
+impl http_handler::Operation for Component {
type Error = Box;
type Outputs = http_handler::Outputs;
type Config = http_handler::Config;
diff --git a/crates/wick/wick-component-codegen/src/generate.rs b/crates/wick/wick-component-codegen/src/generate.rs
index a2119e144..18b3d0892 100644
--- a/crates/wick/wick-component-codegen/src/generate.rs
+++ b/crates/wick/wick-component-codegen/src/generate.rs
@@ -75,11 +75,13 @@ fn gen_trait_fns<'a>(
quote! {
#[doc = #desc]
pub mod #op_name {
+ #[allow(unused)]
use super::*;
#op_config
#op_output
+ #trait_sig
}
- #trait_sig
+
}
})
.collect_vec()
@@ -146,7 +148,7 @@ fn codegen(wick_config: WickConfiguration, gen_config: &mut config::Config) -> R
pub(crate) use wick_component::*;
#[allow(unused)]
- pub(crate) type WickStream = wick_component::wasmrs_rx::BoxFlux>;
+ pub(crate) use wick_component::WickStream;
pub use wick_component::flow_component::Context;
#init
diff --git a/crates/wick/wick-component-codegen/src/generate/expand_type.rs b/crates/wick/wick-component-codegen/src/generate/expand_type.rs
index 0d961de49..58cb85dfc 100644
--- a/crates/wick/wick-component-codegen/src/generate/expand_type.rs
+++ b/crates/wick/wick-component-codegen/src/generate/expand_type.rs
@@ -14,7 +14,7 @@ pub(super) fn expand_type(
ty: &wick_interface_types::Type,
) -> TokenStream {
if config.raw && dir != Direction::Out {
- return quote! { wick_component::packet::Packet };
+ return quote! { wick_component::wick_packet::Packet };
}
match ty {
wick_interface_types::Type::Bool => quote! { bool },
@@ -60,7 +60,7 @@ pub(super) fn expand_type(
#[allow(deprecated)]
wick_interface_types::Type::Link { .. } => {
config.add_dep(Dependency::WickComponent);
- quote! {wick_component::packet::ComponentReference}
+ quote! {wick_component::wick_packet::ComponentReference}
}
wick_interface_types::Type::Datetime => {
config.add_dep(Dependency::Chrono);
diff --git a/crates/wick/wick-component-codegen/src/generate/templates/imported_components.rs b/crates/wick/wick-component-codegen/src/generate/templates/imported_components.rs
index ac0b74577..f181531f4 100644
--- a/crates/wick/wick-component-codegen/src/generate/templates/imported_components.rs
+++ b/crates/wick/wick-component-codegen/src/generate/templates/imported_components.rs
@@ -43,6 +43,7 @@ pub(crate) fn imported_components(config: &mut Config, required: Vec TokenStream {
let outputs_name = id(&op_outputs_name(op));
- let broadcast_err_statements = op.outputs().iter().map(|i| {
- let field_name = id(&snake(&i.name));
- quote! {
- self.#field_name.error(&err);
- }
- });
-
- let broadcast_open_statements = op.outputs().iter().map(|output| {
- let name = &output.name;
- let field_name = id(&snake(name));
-
- quote! {
- self.#field_name.open_bracket();
- }
- });
-
- let broadcast_close_statements = op.outputs().iter().map(|output| {
- let name = &output.name;
- let field_name = id(&snake(name));
-
- quote! {
- self.#field_name.close_bracket();
- }
- });
let output_port_fields = op
.outputs()
@@ -44,6 +20,16 @@ pub(crate) fn op_outputs(config: &mut config::Config, op: &OperationSignature) -
quote! {pub(crate) #port_field_name: wick_packet::Output<#port_type>}
})
.collect_vec();
+
+ let output_port_fields_mut = op
+ .outputs()
+ .iter()
+ .map(|i| {
+ let port_field_name = id(&snake(&i.name));
+ quote! {&mut self.#port_field_name}
+ })
+ .collect_vec();
+
let output_ports_new = op
.outputs()
.iter()
@@ -59,6 +45,20 @@ pub(crate) fn op_outputs(config: &mut config::Config, op: &OperationSignature) -
})
.collect_vec();
+ let single_output_impl = if op.outputs().len() == 1 {
+ let output = op.outputs().first().unwrap();
+ let name = id(&snake(output.name()));
+ Some(quote! {
+ impl wick_component::SingleOutput for #outputs_name {
+ fn single_output(&mut self) -> &mut dyn wick_packet::Port {
+ &mut self.#name
+ }
+ }
+ })
+ } else {
+ None
+ };
+
let outputs = f::gen_if(
config.output_structs,
|| {
@@ -73,27 +73,21 @@ pub(crate) fn op_outputs(config: &mut config::Config, op: &OperationSignature) -
#(#output_port_fields,)*
}
+ impl wick_component::Broadcast for #outputs_name {
+ fn outputs_mut(&mut self) -> wick_packet::OutputIterator<'_>{
+ wick_packet::OutputIterator::new(vec![#(#output_port_fields_mut),*])
+ }
+ }
+
+ #single_output_impl
+
+
impl #outputs_name {
pub fn new(channel: wasmrs_rx::FluxChannel) -> Self {
Self {
#(#output_ports_new,)*
}
}
-
- #[allow(unused)]
- pub fn broadcast_open(&mut self) {
- #(#broadcast_open_statements)*
- }
-
- #[allow(unused)]
- pub fn broadcast_close(&mut self) {
- #(#broadcast_close_statements)*
- }
-
- #[allow(unused)]
- pub fn broadcast_err(&mut self, err: impl AsRef) {
- #(#broadcast_err_statements)*
- }
}},
);
diff --git a/crates/wick/wick-component-codegen/src/generate/templates/provided_struct.rs b/crates/wick/wick-component-codegen/src/generate/templates/provided_struct.rs
index 019c8649a..ef976da94 100644
--- a/crates/wick/wick-component-codegen/src/generate/templates/provided_struct.rs
+++ b/crates/wick/wick-component-codegen/src/generate/templates/provided_struct.rs
@@ -28,6 +28,7 @@ pub(crate) fn provided_struct(_config: &Config, required: &[BoundInterface]) ->
#[allow(unused)]
#[cfg(target_family = "wasm")]
mod provided_wasm {
+ #[allow(unused)]
use super::*;
pub(crate) struct Provided {
#(#fields),*
diff --git a/crates/wick/wick-component-codegen/src/generate/templates/trait_signature.rs b/crates/wick/wick-component-codegen/src/generate/templates/trait_signature.rs
index c6cffa9c1..79bef1419 100644
--- a/crates/wick/wick-component-codegen/src/generate/templates/trait_signature.rs
+++ b/crates/wick/wick-component-codegen/src/generate/templates/trait_signature.rs
@@ -9,7 +9,7 @@ use crate::generate::ids::*;
use crate::generate::{config, f, Direction};
pub(crate) fn trait_signature(config: &mut config::Config, op: &OperationSignature) -> TokenStream {
- let trait_name = id(&format!("{}Operation", &pascal(op.name())));
+ let trait_name = id("Operation");
let impl_name = id(&snake(op.name()));
let inputs = op
diff --git a/crates/wick/wick-component-codegen/src/generate/templates/wrapper_fn.rs b/crates/wick/wick-component-codegen/src/generate/templates/wrapper_fn.rs
index 8d2ac65b8..3bd8ca617 100644
--- a/crates/wick/wick-component-codegen/src/generate/templates/wrapper_fn.rs
+++ b/crates/wick/wick-component-codegen/src/generate/templates/wrapper_fn.rs
@@ -63,6 +63,7 @@ pub(crate) fn gen_wrapper_fn(config: &mut config::Config, component: &Ident, op:
return;
}
};
+ use #impl_name::Operation;
if let Err(e) = #component::#impl_name(#(Box::pin(#inputs),)* outputs, config).await {
let _ = channel.send_result(
wick_packet::Packet::component_error(e.to_string()).into(),
diff --git a/crates/wick/wick-component-wasm/src/component.rs b/crates/wick/wick-component-wasm/src/component.rs
index 1fe6c1947..b9586e6c1 100644
--- a/crates/wick/wick-component-wasm/src/component.rs
+++ b/crates/wick/wick-component-wasm/src/component.rs
@@ -4,7 +4,7 @@ use std::sync::Arc;
use flow_component::{BoxFuture, Component, ComponentError, RuntimeCallback};
use tracing::Span;
use wasmrs_host::WasiParams;
-use wick_config::config::components::Permissions;
+use wick_config::config::Permissions;
use wick_config::FetchableAssetReference;
use wick_packet::{Entity, Invocation, PacketStream, RuntimeConfig};
@@ -72,7 +72,8 @@ impl WasmComponent {
span.in_scope(|| debug!(component=%ns, config=?config, "wasi enabled"));
builder = builder.wasi_params(permissions_to_wasi_params(&config));
} else {
- span.in_scope(|| debug!(component=%ns, "wasi disabled"));
+ span.in_scope(|| debug!(component=%ns, "wasi enabled with inherited STDIO only"));
+ builder = builder.wasi_params(WasiParams::default());
}
if let Some(callback) = options.callback {
diff --git a/crates/wick/wick-component-wasm/src/error.rs b/crates/wick/wick-component-wasm/src/error.rs
index 361832721..142602707 100644
--- a/crates/wick/wick-component-wasm/src/error.rs
+++ b/crates/wick/wick-component-wasm/src/error.rs
@@ -33,6 +33,9 @@ pub enum WasmComponentError {
#[error("WebAssembly engine failed: {0}")]
EngineFailure(String),
+ #[error(transparent)]
+ ContextInit(wasmrs_host::errors::Error),
+
#[error("Could not extract claims from component. Is it a signed WebAssembly module?")]
ClaimsExtraction,
diff --git a/crates/wick/wick-component-wasm/src/wasm_host.rs b/crates/wick/wick-component-wasm/src/wasm_host.rs
index af6919562..e10c97f07 100644
--- a/crates/wick/wick-component-wasm/src/wasm_host.rs
+++ b/crates/wick/wick-component-wasm/src/wasm_host.rs
@@ -161,7 +161,19 @@ impl WasmHost {
trace!(index, "wasmrs callback index");
}
let buffer_size: u32 = 5 * 1024 * 1024;
- let ctx = host.new_context(buffer_size, buffer_size).unwrap();
+ let ctx = match host.new_context(buffer_size, buffer_size) {
+ Ok(ctx) => ctx,
+ Err(e) => {
+ // wasmtime has junk errors so we need to parse the string to provide useful information.
+
+ let errstr = e.to_string();
+
+ if errstr.contains("wasi_snapshot") {
+ error!("wasi error initializing component, this may be because a component was compiled with wasi extensions that are not enabled in wick");
+ }
+ return Err(Error::ContextInit(e));
+ }
+ };
drop(_span);
Ok(Self {
diff --git a/crates/wick/wick-component/Cargo.toml b/crates/wick/wick-component/Cargo.toml
index 8359c0f60..a8f80f80e 100644
--- a/crates/wick/wick-component/Cargo.toml
+++ b/crates/wick/wick-component/Cargo.toml
@@ -22,6 +22,7 @@ json = []
[dependencies]
wick-packet = { workspace = true, default-features = false }
+wick-operation = { workspace = true }
flow-component = { workspace = true, default-features = false }
wasmrs = { workspace = true }
wasmrs-rx = { workspace = true }
@@ -33,6 +34,8 @@ serde_json = { workspace = true }
serde = { workspace = true }
chrono = { workspace = true, features = ["std"], optional = true }
bytes = { workspace = true, optional = true }
+async-recursion = { workspace = true }
+tracing = { workspace = true }
[target.'cfg(target_family = "wasm")'.dependencies]
wasmrs-guest = { workspace = true }
diff --git a/crates/wick/wick-component/src/adapters.rs b/crates/wick/wick-component/src/adapters.rs
new file mode 100644
index 000000000..854845172
--- /dev/null
+++ b/crates/wick/wick-component/src/adapters.rs
@@ -0,0 +1,14 @@
+/// Utility functions for binary operations (operations with two inputs).
+pub mod binary;
+/// Utility functions for unary operations (operations with one input).
+pub mod unary;
+
+use wick_packet::PacketPayload;
+
+/// Encode a [Result] type into a raw [PacketPayload]
+pub fn encode(val: Result) -> PacketPayload {
+ match val {
+ Ok(v) => PacketPayload::encode(v),
+ Err(e) => PacketPayload::err(e.to_string()),
+ }
+}
diff --git a/crates/wick/wick-component/src/adapters/binary.rs b/crates/wick/wick-component/src/adapters/binary.rs
new file mode 100644
index 000000000..eae0ead0c
--- /dev/null
+++ b/crates/wick/wick-component/src/adapters/binary.rs
@@ -0,0 +1,5 @@
+mod interleaved_pairs;
+mod paired_right_stream;
+
+pub use interleaved_pairs::interleaved_pairs;
+pub use paired_right_stream::paired_right_stream;
diff --git a/crates/wick/wick-component/src/adapters/binary/interleaved_pairs.rs b/crates/wick/wick-component/src/adapters/binary/interleaved_pairs.rs
new file mode 100644
index 000000000..00040e416
--- /dev/null
+++ b/crates/wick/wick-component/src/adapters/binary/interleaved_pairs.rs
@@ -0,0 +1,156 @@
+use tokio_stream::StreamExt;
+use wick_packet::Packet;
+
+use crate::adapters::encode;
+use crate::{
+ await_next_ok_or,
+ if_done_close_then,
+ make_substream_window,
+ propagate_if_error,
+ SingleOutput,
+ WickStream,
+};
+
+#[macro_export]
+/// This macro will generate the implementations for simple binary operations, operations that take two inputs, produce one output, and are largely want to remain ignorant of stream state.
+macro_rules! binary_interleaved_pairs {
+ ($name:ident) => {
+ #[async_trait::async_trait(?Send)]
+ impl $name::Operation for Component {
+ type Error = anyhow::Error;
+ type Outputs = $name::Outputs;
+ type Config = $name::Config;
+
+ async fn $name(
+ left: WickStream,
+ right: WickStream,
+ mut outputs: Self::Outputs,
+ ctx: Context,
+ ) -> Result<(), Self::Error> {
+ wick_component::binary::interleaved_pairs(left, right, &mut outputs, &ctx, $name).await?;
+
+ Ok(())
+ }
+ }
+ };
+}
+
+/// Operation helper for common binary operations that have one output.
+pub async fn interleaved_pairs<'c, LEFT, RIGHT, OUTPUT, CONTEXT, OUTPORT, F, E>(
+ left: WickStream,
+ right: WickStream,
+ outputs: &mut OUTPORT,
+ ctx: &'c CONTEXT,
+ func: F,
+) -> Result<(), E>
+where
+ CONTEXT: Clone + wasmrs_runtime::ConditionallySendSync,
+ F: Fn(LEFT, RIGHT, CONTEXT) -> Result
+
+
+
+| Field name | Type | Description | Required? | Shortform? |
+|------------|------|-------------|-----------|------------|
+| `resource` | `string`
|The resource ID of the volume.|Yes||
+| `path` | `string`
|The path to map it to in the component.|Yes||
+
+
+
--------
## ComponentKind
diff --git a/crates/wick/wick-config/json-schema/manifest.json b/crates/wick/wick-config/json-schema/manifest.json
index edb98ea94..b8ffda5c4 100644
--- a/crates/wick/wick-config/json-schema/manifest.json
+++ b/crates/wick/wick-config/json-schema/manifest.json
@@ -1549,6 +1549,13 @@
"description": "The path or OCI reference to the WebAssembly module",
"type": "string"
},
+ "volumes": {
+ "description": "Volumes to expose to the component.",
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/v1/ExposedVolume"
+ }
+ },
"with": {
"description": "Configuration necessary to provide when instantiating the component.",
"type": "array",
@@ -1568,6 +1575,25 @@
"ref"
]
},
+ "ExposedVolume": {
+ "$anchor": "#v1/ExposedVolume",
+ "additionalProperties": false,
+ "type": "object",
+ "properties": {
+ "resource": {
+ "description": "The resource ID of the volume.",
+ "type": "string"
+ },
+ "path": {
+ "description": "The path to map it to in the component.",
+ "type": "string"
+ }
+ },
+ "required": [
+ "resource",
+ "path"
+ ]
+ },
"ComponentKind": {
"oneOf": [
{
diff --git a/crates/wick/wick-config/json-schema/v1/manifest.json b/crates/wick/wick-config/json-schema/v1/manifest.json
index da71cfbce..b83935845 100644
--- a/crates/wick/wick-config/json-schema/v1/manifest.json
+++ b/crates/wick/wick-config/json-schema/v1/manifest.json
@@ -1135,6 +1135,14 @@
"type": "string"
},
+ "volumes": {
+ "description": "Volumes to expose to the component.",
+
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/v1/ExposedVolume"
+ }
+ },
"with": {
"description": "Configuration necessary to provide when instantiating the component.",
@@ -1155,6 +1163,25 @@
"required": ["ref"]
},
+ "ExposedVolume": {
+ "$anchor": "#v1/ExposedVolume",
+ "additionalProperties": false,
+ "type": "object",
+ "properties": {
+ "resource": {
+ "description": "The resource ID of the volume.",
+
+ "type": "string"
+ },
+ "path": {
+ "description": "The path to map it to in the component.",
+
+ "type": "string"
+ }
+ },
+ "required": ["resource", "path"]
+ },
+
"ComponentKind": {
"oneOf": [
{ "$ref": "#/$defs/v1/WasmComponentConfiguration" },
diff --git a/crates/wick/wick-config/src/config.rs b/crates/wick/wick-config/src/config.rs
index 25cc2a55f..0aee89ecb 100644
--- a/crates/wick/wick-config/src/config.rs
+++ b/crates/wick/wick-config/src/config.rs
@@ -5,6 +5,7 @@ pub(crate) mod common;
pub(crate) mod component_config;
/// Specific component-level configuration and types.
pub mod components;
+pub(crate) mod permissions;
pub(crate) mod test_config;
pub(crate) mod types_config;
@@ -15,6 +16,7 @@ pub use app_config::*;
use asset_container::Asset;
pub use common::*;
pub use component_config::*;
+pub use permissions::{Permissions, PermissionsBuilder};
use serde_json::Value;
pub use test_config::*;
use tokio::fs::read_to_string;
diff --git a/crates/wick/wick-config/src/config/app_config.rs b/crates/wick/wick-config/src/config/app_config.rs
index 664fb0a77..2408f0fd7 100644
--- a/crates/wick/wick-config/src/config/app_config.rs
+++ b/crates/wick/wick-config/src/config/app_config.rs
@@ -1,7 +1,6 @@
#![allow(missing_docs)] // delete when we move away from the `property` crate.
use std::collections::HashMap;
use std::path::{Path, PathBuf};
-pub(super) mod resources;
pub(super) mod triggers;
use asset_container::{AssetManager, Assets};
@@ -10,12 +9,12 @@ use wick_asset_reference::{AssetReference, FetchOptions};
use wick_interface_types::TypeDefinition;
use wick_packet::RuntimeConfig;
-pub use self::resources::*;
pub use self::triggers::*;
use super::common::component_definition::ComponentDefinition;
use super::common::package_definition::PackageConfig;
use super::components::TypesComponent;
use super::{ImportBinding, ImportDefinition};
+use crate::config::common::resources::*;
use crate::error::{ManifestError, ReferenceError};
use crate::import_cache::{setup_cache, ImportCache};
use crate::utils::{make_resolver, resolve, RwOption};
@@ -134,8 +133,8 @@ impl AppConfiguration {
}
/// Get the configuration item a binding points to.
- #[must_use]
- pub fn resolve_binding(&self, name: &str) -> Option> {
+
+ pub fn resolve_binding(&self, name: &str) -> Result {
let env = std::env::vars().collect();
resolve(
name,
@@ -284,16 +283,16 @@ pub enum OwnedConfigurationItem {
impl OwnedConfigurationItem {
/// Get the component definition or return an error.
- pub fn try_component(&self) -> Result {
+ pub fn try_component(self) -> Result {
match self {
- Self::Component(c) => Ok(c.clone()),
+ Self::Component(c) => Ok(c),
_ => Err(ManifestError::Reference(ReferenceError::Component)),
}
}
/// Get the resource definition or return an error.
- pub fn try_resource(&self) -> Result {
+ pub fn try_resource(self) -> Result {
match self {
- Self::Resource(c) => Ok(c.clone()),
+ Self::Resource(c) => Ok(c),
_ => Err(ManifestError::Reference(ReferenceError::Resource)),
}
}
diff --git a/crates/wick/wick-config/src/config/common.rs b/crates/wick/wick-config/src/config/common.rs
index 14c836107..2358dd392 100644
--- a/crates/wick/wick-config/src/config/common.rs
+++ b/crates/wick/wick-config/src/config/common.rs
@@ -2,6 +2,7 @@ pub(crate) mod bindings;
pub(crate) mod component_definition;
pub(crate) mod component_implementation;
pub(crate) mod error_behavior;
+pub(crate) mod exposed_resources;
pub(crate) mod glob;
pub(crate) mod host_definition;
pub(crate) mod http;
@@ -11,23 +12,38 @@ pub(crate) mod liquid_json_config;
pub(crate) mod metadata;
pub(crate) mod operation_definition;
pub(crate) mod package_definition;
+pub(crate) mod resources;
pub(crate) mod settings;
pub(crate) mod template_config;
-pub(crate) mod test_case;
+pub mod test_case;
-pub use self::bindings::*;
-pub use self::component_definition::*;
-pub use self::component_implementation::*;
-pub use self::error_behavior::*;
-pub use self::glob::*;
-pub use self::host_definition::*;
-pub use self::http::*;
-pub use self::import_definition::*;
-pub use self::interface::*;
-pub use self::liquid_json_config::*;
-pub use self::metadata::*;
-pub use self::operation_definition::*;
-pub use self::package_definition::*;
-pub use self::settings::*;
-pub use self::template_config::*;
-pub use self::test_case::*;
+pub use self::bindings::{BoundInterface, ImportBinding};
+pub use self::component_definition::{
+ ComponentDefinition,
+ ComponentOperationExpression,
+ ComponentOperationExpressionBuilder,
+ HighLevelComponent,
+};
+pub use self::component_implementation::{ComponentImplementation, ComponentKind};
+pub use self::error_behavior::ErrorBehavior;
+pub use self::exposed_resources::{ExposedVolume, ExposedVolumeBuilder};
+pub use self::glob::Glob;
+pub use self::host_definition::{HostConfig, HostConfigBuilder, HttpConfig, HttpConfigBuilder};
+pub use self::http::{Codec, HttpMethod};
+pub use self::import_definition::ImportDefinition;
+pub use self::interface::InterfaceDefinition;
+pub use self::liquid_json_config::LiquidJsonConfig;
+pub use self::metadata::{Metadata, MetadataBuilder};
+pub use self::operation_definition::{OperationDefinition, OperationDefinitionBuilder};
+pub use self::package_definition::{PackageConfig, PackageConfigBuilder, RegistryConfig, RegistryConfigBuilder};
+pub use self::resources::{
+ ResourceBinding,
+ ResourceBindingBuilder,
+ ResourceDefinition,
+ TcpPort,
+ UdpPort,
+ UrlResource,
+ Volume,
+};
+pub use self::settings::ExecutionSettings;
+pub use self::template_config::TemplateConfig;
diff --git a/crates/wick/wick-config/src/config/common/component_implementation.rs b/crates/wick/wick-config/src/config/common/component_implementation.rs
index 083912753..b6ceb9121 100644
--- a/crates/wick/wick-config/src/config/common/component_implementation.rs
+++ b/crates/wick/wick-config/src/config/common/component_implementation.rs
@@ -1,7 +1,6 @@
use wick_interface_types::OperationSignatures;
-use crate::config::components::WasmComponent;
-use crate::config::{self, ComponentDefinition, HighLevelComponent};
+use crate::config::{self};
#[derive(Debug, Clone, derive_asset_container::AssetManager, serde::Serialize)]
#[asset(asset(config::AssetReference))]
@@ -84,22 +83,3 @@ impl std::fmt::Display for ComponentKind {
}
}
}
-
-impl From for ComponentDefinition {
- fn from(implementation: ComponentImplementation) -> Self {
- match implementation {
- #[allow(deprecated)]
- ComponentImplementation::Wasm(wasm) => ComponentDefinition::Wasm(WasmComponent {
- reference: wasm.reference,
- config: Default::default(),
- permissions: Default::default(),
- provide: Default::default(),
- }),
- ComponentImplementation::Composite(_) => unimplemented!("Inline composite components are not yet supported."),
- ComponentImplementation::HttpClient(client) => {
- ComponentDefinition::HighLevelComponent(HighLevelComponent::HttpClient(client))
- }
- ComponentImplementation::Sql(c) => ComponentDefinition::HighLevelComponent(HighLevelComponent::Sql(c)),
- }
- }
-}
diff --git a/crates/wick/wick-config/src/config/common/exposed_resources.rs b/crates/wick/wick-config/src/config/common/exposed_resources.rs
new file mode 100644
index 000000000..8d4e26852
--- /dev/null
+++ b/crates/wick/wick-config/src/config/common/exposed_resources.rs
@@ -0,0 +1,11 @@
+#[derive(Debug, Clone, Builder, property::Property, serde::Serialize)]
+#[property(get(public), set(public), mut(public, suffix = "_mut"))]
+#[builder(setter(into))]
+
+/// Volumes to expose to a component and the internal paths they map to.
+pub struct ExposedVolume {
+ /// The resource ID of the volume.
+ pub(crate) resource: String,
+ /// The path to map it to in the component.
+ pub(crate) path: String,
+}
diff --git a/crates/wick/wick-config/src/config/app_config/resources.rs b/crates/wick/wick-config/src/config/common/resources.rs
similarity index 83%
rename from crates/wick/wick-config/src/config/app_config/resources.rs
rename to crates/wick/wick-config/src/config/common/resources.rs
index 4a5f6d09c..a69c4b85c 100644
--- a/crates/wick/wick-config/src/config/app_config/resources.rs
+++ b/crates/wick/wick-config/src/config/common/resources.rs
@@ -7,7 +7,22 @@ use wick_asset_reference::AssetReference;
use wick_packet::RuntimeConfig;
use crate::config::TemplateConfig;
-use crate::error::ManifestError;
+use crate::error::{ManifestError, ReferenceError};
+
+macro_rules! try_kind {
+ ($self:ident, $kind:ident) => {
+ match $self {
+ ResourceDefinition::$kind(v) => Ok(v),
+ _ => Err(
+ ReferenceError::ResourceType {
+ expected: ResourceKind::$kind,
+ actual: $self.kind(),
+ }
+ .into(),
+ ),
+ }
+ };
+}
#[derive(Debug, Clone, Builder, derive_asset_container::AssetManager, property::Property, serde::Serialize)]
#[asset(asset(AssetReference))]
@@ -33,6 +48,26 @@ impl ResourceBinding {
}
}
+/// A resource type.
+#[derive(Debug, Clone, Copy, PartialEq)]
+pub enum ResourceKind {
+ TcpPort,
+ UdpPort,
+ Url,
+ Volume,
+}
+
+impl std::fmt::Display for ResourceKind {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match self {
+ Self::TcpPort => write!(f, "TcpPort"),
+ Self::UdpPort => write!(f, "UdpPort"),
+ Self::Url => write!(f, "Url"),
+ Self::Volume => write!(f, "Volume"),
+ }
+ }
+}
+
#[derive(Debug, Clone, PartialEq, derive_asset_container::AssetManager, serde::Serialize)]
#[asset(asset(AssetReference))]
/// Normalized representation of a resource definition.
@@ -65,6 +100,32 @@ impl ResourceDefinition {
ResourceDefinition::Volume(v) => v.render_config(root_config, env),
}
}
+
+ #[must_use]
+ pub fn kind(&self) -> ResourceKind {
+ match self {
+ ResourceDefinition::TcpPort(_) => ResourceKind::TcpPort,
+ ResourceDefinition::UdpPort(_) => ResourceKind::UdpPort,
+ ResourceDefinition::Url(_) => ResourceKind::Url,
+ ResourceDefinition::Volume(_) => ResourceKind::Volume,
+ }
+ }
+
+ pub fn try_tcpport(self) -> Result {
+ try_kind!(self, TcpPort)
+ }
+
+ pub fn try_udpport(self) -> Result {
+ try_kind!(self, UdpPort)
+ }
+
+ pub fn try_url(self) -> Result {
+ try_kind!(self, Url)
+ }
+
+ pub fn try_volume(self) -> Result {
+ try_kind!(self, Volume)
+ }
}
impl From for TcpPort {
diff --git a/crates/wick/wick-config/src/config/component_config/wasm.rs b/crates/wick/wick-config/src/config/component_config/wasm.rs
index 0989ec11d..fa5bf9527 100644
--- a/crates/wick/wick-config/src/config/component_config/wasm.rs
+++ b/crates/wick/wick-config/src/config/component_config/wasm.rs
@@ -3,7 +3,7 @@ use std::borrow::Cow;
use wick_interface_types::{Field, OperationSignatures};
use crate::config::components::{ComponentConfig, OperationConfig};
-use crate::config::{self, OperationDefinition};
+use crate::config::{self, ExposedVolume, OperationDefinition};
use crate::utils::VecMapInto;
#[derive(Debug, Clone, derive_asset_container::AssetManager, Builder, property::Property, serde::Serialize)]
@@ -22,6 +22,12 @@ pub struct WasmComponentImplementation {
#[serde(skip_serializing_if = "Vec::is_empty")]
pub(crate) config: Vec,
+ /// Volumes to expose to the component and the paths they map to.
+ #[asset(skip)]
+ #[builder(default)]
+ #[serde(skip_serializing_if = "Vec::is_empty")]
+ pub(crate) volumes: Vec,
+
/// The operations defined by the component.
#[asset(skip)]
#[builder(default)]
diff --git a/crates/wick/wick-config/src/config/components/wasm.rs b/crates/wick/wick-config/src/config/components/wasm.rs
index d7834e37f..2a230d3fd 100644
--- a/crates/wick/wick-config/src/config/components/wasm.rs
+++ b/crates/wick/wick-config/src/config/components/wasm.rs
@@ -14,29 +14,8 @@ pub struct WasmComponent {
#[asset(skip)]
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) config: Option,
- /// Permissions for this collection
- #[asset(skip)]
- pub(crate) permissions: Permissions,
/// The components to provide to the referenced component.
#[asset(skip)]
#[serde(skip_serializing_if = "HashMap::is_empty")]
pub(crate) provide: HashMap,
}
-
-/// The permissions object for a collection
-#[derive(Debug, Default, Clone, PartialEq, serde::Serialize, serde::Deserialize, property::Property)]
-#[property(get(public), set(private), mut(disable))]
-pub struct Permissions {
- /// A map of directories (Note: TO -> FROM) to expose to the collection.
- #[serde(default)]
- #[serde(skip_serializing_if = "HashMap::is_empty")]
- pub(crate) dirs: HashMap,
-}
-
-impl Permissions {
- /// Create a new permissions object
- #[must_use]
- pub fn new(dirs: HashMap) -> Self {
- Self { dirs }
- }
-}
diff --git a/crates/wick/wick-config/src/config/permissions.rs b/crates/wick/wick-config/src/config/permissions.rs
new file mode 100644
index 000000000..1785483a4
--- /dev/null
+++ b/crates/wick/wick-config/src/config/permissions.rs
@@ -0,0 +1,20 @@
+use std::collections::HashMap;
+
+/// The set of validated privileges and permissions for a component.
+#[derive(Debug, Default, Clone, derive_builder::Builder, property::Property, PartialEq)]
+#[property(get(public), set(public), mut(public, suffix = "_mut"))]
+#[builder(setter(into))]
+
+pub struct Permissions {
+ /// A map of directories (TO -> FROM) to expose to the component.
+ #[builder(default)]
+ pub(crate) dirs: HashMap,
+}
+
+impl Permissions {
+ /// Create a new permissions object
+ #[must_use]
+ pub fn new(dirs: HashMap) -> Self {
+ Self { dirs }
+ }
+}
diff --git a/crates/wick/wick-config/src/config/test_config.rs b/crates/wick/wick-config/src/config/test_config.rs
index 7765b04e2..aef8e2a57 100644
--- a/crates/wick/wick-config/src/config/test_config.rs
+++ b/crates/wick/wick-config/src/config/test_config.rs
@@ -5,7 +5,7 @@ use std::path::{Path, PathBuf};
use asset_container::AssetManager;
use super::LiquidJsonConfig;
-use crate::config;
+use crate::config::test_case;
use crate::error::ManifestError;
#[derive(Debug, Clone, Builder, derive_asset_container::AssetManager, property::Property, serde::Serialize)]
@@ -39,7 +39,7 @@ pub struct TestConfiguration {
#[asset(skip)]
#[builder(default)]
#[serde(skip_serializing_if = "Vec::is_empty")]
- pub(crate) cases: Vec,
+ pub(crate) cases: Vec,
/// The environment this configuration has access to.
#[asset(skip)]
diff --git a/crates/wick/wick-config/src/error.rs b/crates/wick/wick-config/src/error.rs
index 5c61d2066..4eb1b53ff 100644
--- a/crates/wick/wick-config/src/error.rs
+++ b/crates/wick/wick-config/src/error.rs
@@ -3,6 +3,7 @@ use std::path::PathBuf;
use derive_builder::UninitializedFieldError;
use thiserror::Error;
+use crate::config::resources::ResourceKind;
use crate::config::{self};
// type BoxedSyncSendError = Box;
@@ -86,6 +87,10 @@ pub enum ManifestError {
#[error("Invalid authority: {0}")]
InvalidUrl(String),
+ /// Identifier not found.
+ #[error("Could not find definition for id '{0}'")]
+ IdNotFound(String),
+
/// Attempted to use configuration before it was renderable.
#[error("Could not render configuration template: {0}")]
ConfigurationTemplate(String),
@@ -108,7 +113,7 @@ pub enum ManifestError {
/// Error resolving reference.
#[error(transparent)]
- Reference(ReferenceError),
+ Reference(#[from] ReferenceError),
/// Error building a configuration
#[error(transparent)]
@@ -133,6 +138,15 @@ pub enum ReferenceError {
/// The referenced item was not a resource.
#[error("Referenced item is not a resource")]
Resource,
+
+ /// The resource was not the requested type.
+ #[error("Expected a resource of type {expected}, found type {actual}")]
+ ResourceType {
+ /// The expected resource type.
+ expected: ResourceKind,
+ /// The actual resource type.
+ actual: ResourceKind,
+ },
}
/// Errors generated when building a configuration.
#[derive(Error, Debug)]
diff --git a/crates/wick/wick-config/src/lib.rs b/crates/wick/wick-config/src/lib.rs
index 449def86b..ee77823f3 100644
--- a/crates/wick/wick-config/src/lib.rs
+++ b/crates/wick/wick-config/src/lib.rs
@@ -115,7 +115,7 @@ pub(crate) type Result = std::result::Result;
pub use wick_asset_reference::{normalize_path, AssetReference, FetchOptions, FetchableAssetReference};
/// The type associated with a resolver function.
-pub type Resolver = dyn Fn(&str) -> Option> + Send + Sync;
+pub type Resolver = dyn Fn(&str) -> Result + Send + Sync;
// Todo: flesh out per-component validation of configuration.
#[doc(hidden)]
diff --git a/crates/wick/wick-config/src/utils.rs b/crates/wick/wick-config/src/utils.rs
index bb507511f..6d81eb3c3 100644
--- a/crates/wick/wick-config/src/utils.rs
+++ b/crates/wick/wick-config/src/utils.rs
@@ -136,25 +136,25 @@ pub(crate) fn resolve(
resources: &HashMap,
runtime_config: Option<&RuntimeConfig>,
env: Option<&HashMap>,
-) -> Option> {
+) -> Result {
if let Some(import) = imports.get(name) {
match &import.kind {
ImportDefinition::Component(component) => {
let mut component = component.clone();
- return Some(match component.render_config(runtime_config, env) {
+ return match component.render_config(runtime_config, env) {
Ok(_) => Ok(OwnedConfigurationItem::Component(component)),
Err(e) => Err(e),
- });
+ };
}
ImportDefinition::Types(_) => todo!(),
}
}
if let Some(resource) = resources.get(name) {
let mut resource = resource.kind.clone();
- return Some(match resource.render_config(runtime_config, env) {
+ return match resource.render_config(runtime_config, env) {
Ok(_) => Ok(OwnedConfigurationItem::Resource(resource)),
Err(e) => Err(e),
- });
+ };
}
- None
+ Err(Error::IdNotFound(name.to_owned()))
}
diff --git a/crates/wick/wick-config/src/v0/conversions.rs b/crates/wick/wick-config/src/v0/conversions.rs
index 2069c7510..b80cb40f3 100644
--- a/crates/wick/wick-config/src/v0/conversions.rs
+++ b/crates/wick/wick-config/src/v0/conversions.rs
@@ -5,7 +5,6 @@ use flow_expression_parser::ast::{self, InstancePort, InstanceTarget};
use flow_expression_parser::parse_id;
use liquid_json::LiquidJsonValue;
use option_utils::OptionUtils;
-use serde_json::Value;
use crate::error::ManifestError;
use crate::utils::{opt_str_to_ipv4addr, VecTryMapInto};
@@ -71,7 +70,6 @@ impl TryFrom for config::ComponentDefinition {
#[allow(deprecated)]
crate::v0::CollectionKind::WaPC => config::ComponentDefinition::Wasm(config::components::WasmComponent {
reference: def.reference.clone().try_into()?,
- permissions: json_struct_to_permissions(def.data.as_ref().and_then(|v| v.get("wasi").cloned()))?,
config: def.data.map(Into::into),
provide: Default::default(),
}),
@@ -87,16 +85,6 @@ impl TryFrom for config::ComponentDefinition {
}
}
-fn json_struct_to_permissions(json_perms: Option) -> Result {
- let perms = if let Some(json_perms) = json_perms {
- serde_json::from_value(json_perms).map_err(crate::Error::Invalid)?
- } else {
- config::components::Permissions::default()
- };
-
- Ok(perms)
-}
-
impl TryFrom for config::FlowOperation {
type Error = ManifestError;
diff --git a/crates/wick/wick-config/src/v1.rs b/crates/wick/wick-config/src/v1.rs
index c9aa88066..19490097c 100644
--- a/crates/wick/wick-config/src/v1.rs
+++ b/crates/wick/wick-config/src/v1.rs
@@ -777,6 +777,11 @@ pub(crate) struct WasmComponentConfiguration {
#[serde(rename = "ref")]
pub(crate) reference: crate::v1::helpers::LocationReference,
+ /// Volumes to expose to the component.
+
+ #[serde(default)]
+ #[serde(skip_serializing_if = "Vec::is_empty")]
+ pub(crate) volumes: Vec,
/// Configuration necessary to provide when instantiating the component.
#[serde(default)]
@@ -789,6 +794,16 @@ pub(crate) struct WasmComponentConfiguration {
pub(crate) operations: Vec,
}
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+#[serde(deny_unknown_fields)]
+/// Volumes to expose to a component and the internal paths they map to.
+pub(crate) struct ExposedVolume {
+ /// The resource ID of the volume.
+ pub(crate) resource: String,
+ /// The path to map it to in the component.
+ pub(crate) path: String,
+}
+
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(deny_unknown_fields)]
#[serde(tag = "kind")]
diff --git a/crates/wick/wick-config/src/v1/conversions.rs b/crates/wick/wick-config/src/v1/conversions.rs
index ced1e5473..ef03297f5 100644
--- a/crates/wick/wick-config/src/v1/conversions.rs
+++ b/crates/wick/wick-config/src/v1/conversions.rs
@@ -255,6 +255,7 @@ impl TryFrom for WasmComponentImplementation {
reference: value.reference.try_into()?,
config: value.with.try_map_into()?,
operations: value.operations.try_map_into()?,
+ volumes: value.volumes.try_map_into()?,
})
}
}
@@ -310,6 +311,29 @@ impl TryFrom for v1::WasmComponentConfiguration {
operations: value.operations.try_map_into()?,
reference: value.reference.try_into()?,
with: value.config.try_map_into()?,
+ volumes: value.volumes.try_map_into()?,
+ })
+ }
+}
+
+impl TryFrom for config::ExposedVolume {
+ type Error = ManifestError;
+
+ fn try_from(value: v1::ExposedVolume) -> std::result::Result {
+ Ok(Self {
+ path: value.path,
+ resource: value.resource,
+ })
+ }
+}
+
+impl TryFrom for v1::ExposedVolume {
+ type Error = ManifestError;
+
+ fn try_from(value: config::ExposedVolume) -> std::result::Result {
+ Ok(Self {
+ path: value.path,
+ resource: value.resource,
})
}
}
@@ -1387,7 +1411,7 @@ impl TryFrom for test_case::TestPacket {
}
}
-impl TryFrom for config::PacketFlag {
+impl TryFrom for test_case::PacketFlag {
type Error = crate::Error;
fn try_from(value: v1::PacketFlags) -> Result {
Ok(match value {
@@ -1411,7 +1435,7 @@ impl TryFrom for config::PacketFlag {
}
}
-impl TryFrom for config::SuccessPayload {
+impl TryFrom for test_case::SuccessPayload {
type Error = crate::Error;
fn try_from(value: v1::SuccessPacket) -> Result {
let mut val = Self {
@@ -1430,7 +1454,7 @@ impl TryFrom for config::SuccessPayload {
}
}
-impl TryFrom for config::ErrorPayload {
+impl TryFrom for test_case::ErrorPayload {
type Error = crate::Error;
fn try_from(value: v1::ErrorPacket) -> Result {
let mut val = Self {
@@ -1450,7 +1474,7 @@ impl TryFrom for config::ErrorPayload {
}
}
-impl From for config::InherentConfig {
+impl From for test_case::InherentConfig {
fn from(value: v1::InherentData) -> Self {
Self {
seed: value.seed,
diff --git a/crates/wick/wick-operation/Cargo.toml b/crates/wick/wick-operation/Cargo.toml
new file mode 100644
index 000000000..ec0ef6227
--- /dev/null
+++ b/crates/wick/wick-operation/Cargo.toml
@@ -0,0 +1,22 @@
+[package]
+name = "wick-operation"
+version = "0.1.0"
+edition = "2021"
+authors = ["Jarrod Overson "]
+include = ["src/lib.rs", "README.md"]
+license = "Apache-2.0"
+repository = "https://github.com/candlecorp/wick"
+description = "Proc macro for generating operation implementations"
+
+[lib]
+proc-macro = true
+
+[dependencies]
+proc-macro2 = { workspace = true }
+quote = { workspace = true }
+syn = { workspace = true, features = ["full"] }
+proc-macro-crate = { workspace = true }
+
+[dev-dependencies]
+tokio = { workspace = true, features = ["macros", "rt-multi-thread"] }
+wick-logger = { workspace = true }
diff --git a/crates/wick/wick-operation/README.md b/crates/wick/wick-operation/README.md
new file mode 100644
index 000000000..b63dbfe4d
--- /dev/null
+++ b/crates/wick/wick-operation/README.md
@@ -0,0 +1,15 @@
+# wick-operation
+
+wick-operation is a crate that provides the `operation` proc macro exposed by the `wick-component` crate.
+
+## Usage
+
+```rust
+
+use wick_component::operation;
+
+#[operation(unary_simple)]
+fn my_operation(my_input: String) -> anyhow::Result {
+ // ...
+}
+```
diff --git a/crates/wick/wick-operation/src/lib.rs b/crates/wick/wick-operation/src/lib.rs
new file mode 100644
index 000000000..4bbb34294
--- /dev/null
+++ b/crates/wick/wick-operation/src/lib.rs
@@ -0,0 +1,165 @@
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+use proc_macro2::{Ident, Span};
+use proc_macro_crate::crate_name;
+use quote::{quote, ToTokens};
+use syn::parse::Parser;
+use syn::punctuated::Punctuated;
+use syn::token::PathSep;
+use syn::{parse_macro_input, FnArg, ItemFn, Meta, PathSegment, ReturnType, Token};
+
+enum Adapter {
+ BinaryInterleavedPairs,
+ BinaryPairedRightStream,
+ UnarySimple,
+}
+
+impl Adapter {
+ fn from_segments(s: &Punctuated) -> Option {
+ let mut s = s.iter().rev();
+ let last = s.next()?.ident.to_string();
+ match last.as_str() {
+ "binary_interleaved_pairs" => Some(Adapter::BinaryInterleavedPairs),
+ "binary_paired_right_stream" => Some(Adapter::BinaryPairedRightStream),
+ "unary_simple" => Some(Adapter::UnarySimple),
+ _ => None,
+ }
+ }
+
+ fn available_adapters() -> Vec {
+ vec![
+ Adapter::BinaryInterleavedPairs,
+ Adapter::BinaryPairedRightStream,
+ Adapter::UnarySimple,
+ ]
+ }
+}
+
+impl std::fmt::Display for Adapter {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match self {
+ Adapter::BinaryInterleavedPairs => write!(f, "binary_interleaved_pairs"),
+ Adapter::BinaryPairedRightStream => write!(f, "binary_paired_right_stream"),
+ Adapter::UnarySimple => write!(f, "unary_simple"),
+ }
+ }
+}
+
+impl ToTokens for Adapter {
+ fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
+ Ident::new(&self.to_string(), Span::call_site()).to_tokens(tokens)
+ }
+}
+
+#[proc_macro_attribute]
+pub fn operation(attr: TokenStream, item: TokenStream) -> TokenStream {
+ let parser = Punctuated::::parse_terminated;
+ let args = match parser.parse2(attr.into()) {
+ Ok(args) => args,
+ Err(e) => panic!("{}", e),
+ };
+
+ let input = parse_macro_input!(item as ItemFn);
+
+ let args = args.into_iter().collect::>();
+
+ let adapter = match args.as_slice() {
+ [Meta::Path(path)] => Adapter::from_segments(&path.segments),
+ _ => {
+ panic!(
+ "unsupported attributes supplied: {}, available adapters are {}",
+ quote! { args },
+ Adapter::available_adapters()
+ .iter()
+ .map(|a| a.to_string())
+ .collect::>()
+ .join(", ")
+ );
+ }
+ }
+ .unwrap_or_else(|| {
+ panic!(
+ "unsupported attributes supplied: {}, available adapters are {}",
+ quote! { args },
+ Adapter::available_adapters()
+ .iter()
+ .map(|a| a.to_string())
+ .collect::>()
+ .join(", ")
+ )
+ });
+ let _ = crate_name("wick-component").expect("wick-component needs to be added in `Cargo.toml`");
+
+ expand_wrapper(adapter, &input)
+}
+
+/// Emit code for a wrapper function around a test function.
+fn expand_wrapper(adapter: Adapter, wrappee: &ItemFn) -> TokenStream {
+ let attrs = &wrappee.attrs;
+ let async_ = &wrappee.sig.asyncness;
+ let fn_body = &wrappee.block;
+ let fn_name = &wrappee.sig.ident;
+ let fn_arg_types_outer = &wrappee
+ .sig
+ .inputs
+ .iter()
+ .cloned()
+ .map(|mut arg| {
+ if let FnArg::Typed(pat) = &mut arg {
+ #[allow(clippy::single_match)]
+ match pat.pat.as_mut() {
+ syn::Pat::Ident(id) => {
+ id.mutability = None;
+ }
+ _ => {}
+ }
+ }
+ arg
+ })
+ .collect::>();
+ let fn_arg_types = &wrappee.sig.inputs.iter().collect::>();
+ let fn_arg_names = &wrappee
+ .sig
+ .inputs
+ .iter()
+ .filter_map(|arg| {
+ if let FnArg::Typed(pat) = arg {
+ match pat.pat.as_ref() {
+ syn::Pat::Ident(id) => Some(&id.ident),
+ _ => None,
+ }
+ } else {
+ None
+ }
+ })
+ .collect::>();
+
+ let fn_return = match &wrappee.sig.output {
+ ReturnType::Default => quote! {()},
+ ReturnType::Type(_, type_) => quote! {#type_},
+ };
+ let fn_wrapper_name = Ident::new(&format!("real_{}", fn_name), Span::call_site());
+
+ let (async_, await_) = if async_.is_some() {
+ (Some(quote! {async}), Some(quote! {.await}))
+ } else {
+ (None, None)
+ };
+
+ let result = quote! {
+ wick_component::#adapter !(#fn_name);
+
+ #(#attrs)*
+ fn #fn_name(#(#fn_arg_types_outer),*) -> std::pin::Pin + 'static>> {
+ Box::pin(async move { #fn_wrapper_name(#(#fn_arg_names),*)#await_ })
+ }
+
+ #async_ fn #fn_wrapper_name(#(#fn_arg_types),*) -> #fn_return {
+ #fn_body
+ }
+
+ };
+
+ result.into()
+}
diff --git a/crates/wick/wick-packet/Cargo.toml b/crates/wick/wick-packet/Cargo.toml
index efb252db2..d45be77e5 100644
--- a/crates/wick/wick-packet/Cargo.toml
+++ b/crates/wick/wick-packet/Cargo.toml
@@ -32,6 +32,7 @@ serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
thiserror = { workspace = true }
wasmrs = { workspace = true }
+wasmrs-runtime = { workspace = true }
wasmrs-frames = { workspace = true, features = ["derive_serde"] }
wasmrs-rx = { workspace = true }
wasmrs-codec = { workspace = true }
diff --git a/crates/wick/wick-packet/src/lib.rs b/crates/wick/wick-packet/src/lib.rs
index bfc5dadaa..4ad240fcb 100644
--- a/crates/wick/wick-packet/src/lib.rs
+++ b/crates/wick/wick-packet/src/lib.rs
@@ -118,7 +118,7 @@ pub use inherent::InherentData;
#[cfg(feature = "invocation")]
pub use invocation::Invocation;
pub use metadata::{Flags, WickMetadata, CLOSE_BRACKET, DONE_FLAG, OPEN_BRACKET};
-pub use output::Output;
+pub use output::{Output, OutputIterator, Port, ValuePort};
pub use packet::{from_raw_wasmrs, from_wasmrs, packetstream_to_wasmrs, Packet, PacketError, PacketPayload};
pub use packet_stream::{into_packet, PacketSender, PacketStream};
pub use stream_map::StreamMap;
diff --git a/crates/wick/wick-packet/src/output.rs b/crates/wick/wick-packet/src/output.rs
index 04e77d862..33ef57ce8 100644
--- a/crates/wick/wick-packet/src/output.rs
+++ b/crates/wick/wick-packet/src/output.rs
@@ -1,8 +1,9 @@
use tracing::warn;
use wasmrs::{PayloadError, RawPayload};
+use wasmrs_runtime::ConditionallySend;
use wasmrs_rx::{FluxChannel, Observer};
-use crate::Packet;
+use crate::{Packet, PacketPayload};
pub struct Output
where
@@ -19,30 +20,54 @@ impl std::fmt::Debug for Output<()> {
}
}
-impl Output
+pub trait Port: ConditionallySend {
+ fn send_packet(&mut self, value: Packet);
+
+ fn send_raw_payload(&mut self, value: PacketPayload) {
+ self.send_packet(Packet::new_for_port(self.name(), value, 0));
+ }
+
+ fn name(&self) -> &str;
+
+ fn open_bracket(&mut self) {
+ self.send_packet(Packet::open_bracket(self.name()));
+ }
+
+ fn close_bracket(&mut self) {
+ self.send_packet(Packet::close_bracket(self.name()));
+ }
+
+ fn done(&mut self) {
+ self.send_packet(Packet::done(self.name()));
+ }
+
+ fn error(&mut self, err: &str) {
+ self.send_packet(Packet::err(self.name(), err));
+ }
+}
+
+pub trait ValuePort: Port
where
T: serde::Serialize,
{
- pub fn new(name: impl AsRef, channel: FluxChannel) -> Self {
- Self {
- channel,
- name: name.as_ref().to_owned(),
- _phantom: Default::default(),
- }
+ fn send(&mut self, value: &T) {
+ self.send_packet(Packet::encode(self.name(), value));
}
- pub fn send(&mut self, value: &T) {
- self.send_raw(Packet::encode(&self.name, value));
- }
-
- pub fn send_result(&mut self, value: Result) {
+ fn send_result(&mut self, value: Result) {
match value {
Ok(value) => self.send(&value),
- Err(err) => self.error(err.to_string()),
+ Err(err) => self.error(err.to_string().as_str()),
}
}
+}
- pub fn send_raw(&mut self, value: Packet) {
+impl Port for Output
+where
+ T: serde::Serialize + ConditionallySend,
+{
+ fn send_packet(&mut self, value: Packet) {
+ let value = value.set_port(&self.name);
if let Err(e) = self.channel.send_result(value.into()) {
warn!(
port = self.name,
@@ -52,19 +77,52 @@ where
};
}
- pub fn open_bracket(&mut self) {
- self.send_raw(Packet::open_bracket(&self.name));
+ fn name(&self) -> &str {
+ &self.name
}
+}
- pub fn close_bracket(&mut self) {
- self.send_raw(Packet::close_bracket(&self.name));
+impl ValuePort for Output where T: serde::Serialize + ConditionallySend {}
+
+impl Output
+where
+ T: serde::Serialize,
+{
+ pub fn new(name: impl AsRef, channel: FluxChannel) -> Self {
+ Self {
+ channel,
+ name: name.as_ref().to_owned(),
+ _phantom: Default::default(),
+ }
}
+}
- pub fn done(&mut self) {
- self.send_raw(Packet::done(&self.name));
+/// Iterator over a mutable set of output ports
+#[must_use]
+pub struct OutputIterator<'a> {
+ outputs: Vec<&'a mut dyn Port>,
+}
+
+impl<'a> std::fmt::Debug for OutputIterator<'a> {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ f.debug_struct("OutputIterator")
+ .field("outputs", &self.outputs.iter().map(|a| a.name()).collect::>())
+ .finish()
}
+}
+impl<'a> OutputIterator<'a> {
+ /// Create a new [OutputIterator]
+ pub fn new(outputs: Vec<&'a mut dyn Port>) -> Self {
+ Self { outputs }
+ }
+}
+
+impl<'a> IntoIterator for OutputIterator<'a> {
+ type Item = &'a mut dyn Port;
+
+ type IntoIter = std::vec::IntoIter;
- pub fn error(&mut self, err: impl AsRef) {
- self.send_raw(Packet::err(&self.name, err));
+ fn into_iter(self) -> Self::IntoIter {
+ self.outputs.into_iter()
}
}
diff --git a/crates/wick/wick-packet/src/packet.rs b/crates/wick/wick-packet/src/packet.rs
index c8de2ceb0..14da970ef 100644
--- a/crates/wick/wick-packet/src/packet.rs
+++ b/crates/wick/wick-packet/src/packet.rs
@@ -120,10 +120,7 @@ impl Packet {
/// Encode a value into a [Packet] for the given port.
pub fn encode(port: impl AsRef, data: T) -> Self {
- match wasmrs_codec::messagepack::serialize(&data) {
- Ok(bytes) => Self::new_for_port(port, PacketPayload::Ok(Some(bytes.into())), 0),
- Err(err) => Self::new_for_port(port, PacketPayload::Err(PacketError::new(err.to_string())), 0),
- }
+ Self::new_for_port(port, PacketPayload::encode(data), 0)
}
/// Get the flags for this packet.
@@ -267,6 +264,14 @@ impl PacketPayload {
Self::Err(PacketError::new(err))
}
+ /// Encode a value into a [PacketPayload]
+ pub fn encode(data: T) -> Self {
+ match wasmrs_codec::messagepack::serialize(&data) {
+ Ok(bytes) => PacketPayload::Ok(Some(bytes.into())),
+ Err(err) => PacketPayload::err(err.to_string()),
+ }
+ }
+
/// Try to deserialize a [Packet] into the target type
pub fn decode(self) -> Result {
match self {
@@ -284,6 +289,10 @@ impl PacketPayload {
}
}
+ pub fn err(msg: impl AsRef) -> Self {
+ Self::Err(PacketError::new(msg))
+ }
+
/// Partially process a [Packet] as [Type].
pub fn type_wrapper(self, sig: Type) -> Result {
let val = match sig {
diff --git a/crates/wick/wick-runtime/src/components.rs b/crates/wick/wick-runtime/src/components.rs
index d260afc68..ddce617fb 100644
--- a/crates/wick/wick-runtime/src/components.rs
+++ b/crates/wick/wick-runtime/src/components.rs
@@ -14,8 +14,15 @@ use tracing::Instrument;
use uuid::Uuid;
use wick_component_wasm::component::{ComponentSetupBuilder, WasmComponent};
use wick_component_wasm::error::LinkError;
-use wick_config::config::components::{ManifestComponent, Permissions};
-use wick_config::config::{BoundInterface, Metadata, ResourceDefinition, WasmComponentImplementation};
+use wick_config::config::components::ManifestComponent;
+use wick_config::config::{
+ BoundInterface,
+ Metadata,
+ Permissions,
+ PermissionsBuilder,
+ ResourceDefinition,
+ WasmComponentImplementation,
+};
use wick_config::{AssetReference, FetchOptions, Resolver, WickConfiguration};
use wick_packet::validation::expect_configuration_matches;
use wick_packet::{Entity, Invocation, RuntimeConfig};
@@ -39,14 +46,14 @@ type ComponentInitResult = std::result::Result;
pub(crate) async fn init_wasm_component(
reference: &AssetReference,
- permissions: Option,
namespace: String,
opts: ChildInit,
+ permissions: Option,
provided: HashMap,
) -> ComponentInitResult {
opts
.span
- .in_scope(|| trace!(namespace = %namespace, ?opts, "registering wasm component"));
+ .in_scope(|| trace!(namespace = %namespace, ?opts, ?permissions, "registering wasm component"));
let mut options = FetchOptions::default();
options
@@ -57,7 +64,7 @@ pub(crate) async fn init_wasm_component(
let setup = ComponentSetupBuilder::default()
.engine(WASMTIME_ENGINE.clone())
.permissions(permissions)
- .config(opts.config)
+ .config(opts.root_config)
.callback(Some(make_link_callback(opts.runtime_id)))
.provided(provided)
.build()
@@ -76,9 +83,10 @@ pub(crate) async fn init_wasm_impl_component(
kind: &WasmComponentImplementation,
namespace: String,
opts: ChildInit,
+ permissions: Option,
provided: HashMap,
) -> ComponentInitResult {
- init_wasm_component(kind.reference(), None, namespace, opts, provided).await
+ init_wasm_component(kind.reference(), namespace, opts, permissions, provided).await
}
pub(crate) fn make_link_callback(engine_id: Uuid) -> Arc {
@@ -109,7 +117,7 @@ pub(crate) fn make_link_callback(engine_id: Uuid) -> Arc {
pub(crate) async fn init_manifest_component(
kind: &ManifestComponent,
id: String,
- mut opts: ChildInit,
+ opts: ChildInit,
) -> ComponentInitResult {
let span = opts.span.clone();
span.in_scope(|| trace!(namespace = %id, ?opts, "registering wick component"));
@@ -123,25 +131,46 @@ pub(crate) async fn init_manifest_component(
let mut builder = WickConfiguration::fetch(kind.reference().path()?.to_string_lossy(), options)
.instrument(span.clone())
.await?;
- builder.set_root_config(opts.config.clone());
+ builder.set_root_config(opts.root_config.clone());
let manifest = builder.finish()?.try_component_config()?;
+ let requires = manifest.requires();
+ let provided =
+ generate_provides(requires, kind.provide()).map_err(|e| EngineError::ComponentInit(id.clone(), e.to_string()))?;
+ init_component_implementation(&manifest, id, opts, provided).await
+}
+
+pub(crate) async fn init_component_implementation(
+ manifest: &ComponentConfiguration,
+ id: String,
+ mut opts: ChildInit,
+ provided: HashMap,
+) -> ComponentInitResult {
+ let span = opts.span.clone();
span.in_scope(|| {
debug!(%id,"validating configuration for wick component");
- expect_configuration_matches(&id, opts.config.as_ref(), manifest.config()).map_err(EngineError::Setup)
+ expect_configuration_matches(&id, opts.root_config.as_ref(), manifest.config()).map_err(EngineError::Setup)
})?;
let rng = Random::from_seed(opts.rng_seed);
opts.rng_seed = rng.seed();
let uuid = rng.uuid();
- let requires = manifest.requires();
let metadata = manifest.metadata();
- let provided =
- generate_provides(requires, kind.provide()).map_err(|e| EngineError::ComponentInit(id.clone(), e.to_string()))?;
-
match manifest.component() {
config::ComponentImplementation::Wasm(wasmimpl) => {
- let comp = init_wasm_impl_component(wasmimpl, id.clone(), opts, provided).await?;
+ let mut dirs = HashMap::new();
+ for volume in wasmimpl.volumes() {
+ let resource = (opts.resolver)(volume.resource())?.try_resource()?.try_volume()?;
+ dirs.insert(volume.path().to_owned(), resource.path()?.to_string_lossy().to_string());
+ }
+ let perms = if !dirs.is_empty() {
+ let mut perms = PermissionsBuilder::default();
+ perms.dirs(dirs);
+ Some(perms.build().unwrap())
+ } else {
+ None
+ };
+ let comp = init_wasm_impl_component(wasmimpl, id.clone(), opts, perms, provided).await?;
let signed_sig = comp.component().signature();
let manifest_sig = manifest.signature()?;
span.in_scope(|| {
@@ -155,7 +184,7 @@ pub(crate) async fn init_manifest_component(
Ok(comp)
}
config::ComponentImplementation::Composite(_) => {
- let _engine = init_child(uuid, manifest, Some(id.clone()), opts).await?;
+ let _engine = init_child(uuid, manifest.clone(), Some(id.clone()), opts).await?;
let component = Arc::new(engine_component::EngineComponent::new(uuid));
let service = NativeComponentService::new(component);
@@ -164,7 +193,7 @@ pub(crate) async fn init_manifest_component(
config::ComponentImplementation::Sql(c) => {
init_hlc_component(
id,
- opts.config.clone(),
+ opts.root_config.clone(),
metadata.cloned(),
wick_config::config::HighLevelComponent::Sql(c.clone()),
manifest.resolver(),
@@ -174,7 +203,7 @@ pub(crate) async fn init_manifest_component(
config::ComponentImplementation::HttpClient(c) => {
init_hlc_component(
id,
- opts.config.clone(),
+ opts.root_config.clone(),
metadata.cloned(),
wick_config::config::HighLevelComponent::HttpClient(c.clone()),
manifest.resolver(),
@@ -217,10 +246,7 @@ pub(crate) async fn init_hlc_component(
) -> ComponentInitResult {
let comp: Box = match component {
config::HighLevelComponent::Sql(comp) => {
- let url = resolver(comp.resource())
- .ok_or_else(|| EngineError::ComponentInit("sql or azure-sql".to_owned(), "no resource found".to_owned()))??
- .try_resource()
- .unwrap();
+ let url = resolver(comp.resource())?.try_resource()?;
let scheme = match &url {
ResourceDefinition::Url(url) => url.url().value_unchecked().scheme(),
_ => {
diff --git a/crates/wick/wick-runtime/src/runtime_service.rs b/crates/wick/wick-runtime/src/runtime_service.rs
index 52eff70c0..1be53811d 100644
--- a/crates/wick/wick-runtime/src/runtime_service.rs
+++ b/crates/wick/wick-runtime/src/runtime_service.rs
@@ -14,11 +14,10 @@ use once_cell::sync::Lazy;
use parking_lot::Mutex;
use utils::{assert_constraints, instantiate_import};
use uuid::Uuid;
-use wick_config::config::{ComponentDefinition, ComponentImplementation};
+use wick_config::config::ComponentImplementation;
-use self::utils::instantiate_component;
-use crate::components::make_link_callback;
use crate::components::validation::expect_signature_match;
+use crate::components::{init_component_implementation, make_link_callback};
use crate::dev::prelude::*;
type ServiceMap = HashMap>;
@@ -55,26 +54,28 @@ impl RuntimeService {
config.extends()
} else {
// Instantiate the non-composite component as an exposed, standalone component.
+
let component_init = init.child_init(init.manifest.root_config().cloned());
- let def: ComponentDefinition = init.manifest.component().clone().into();
span.in_scope(|| debug!(%ns,options=?component_init,"instantiating component"));
- if let Some(main_component) = instantiate_component(ns.clone(), &def, component_init).await? {
- let reported_sig = main_component.component().signature();
- let manifest_sig = init.manifest.signature()?;
-
- expect_signature_match(
- init.manifest.source(),
- reported_sig,
- init.manifest.source(),
- &manifest_sig,
- )?;
- main_component.expose();
- components
- .add(main_component)
- .map_err(|e| EngineError::InterpreterInit(manifest_source.clone(), Box::new(e)))?;
- }
+ let main_component =
+ init_component_implementation(&init.manifest, ns.clone(), component_init, Default::default()).await?;
+ let reported_sig = main_component.component().signature();
+ let manifest_sig = init.manifest.signature()?;
+
+ expect_signature_match(
+ init.manifest.source(),
+ reported_sig,
+ init.manifest.source(),
+ &manifest_sig,
+ )?;
+ main_component.expose();
+
+ components
+ .add(main_component)
+ .map_err(|e| EngineError::InterpreterInit(manifest_source.clone(), Box::new(e)))?;
+
&[]
};
diff --git a/crates/wick/wick-runtime/src/runtime_service/child_init.rs b/crates/wick/wick-runtime/src/runtime_service/child_init.rs
index feb9485f0..4815e87d6 100644
--- a/crates/wick/wick-runtime/src/runtime_service/child_init.rs
+++ b/crates/wick/wick-runtime/src/runtime_service/child_init.rs
@@ -17,7 +17,7 @@ pub(crate) struct ChildInit {
pub(crate) runtime_id: Uuid,
pub(crate) allow_latest: bool,
pub(crate) allowed_insecure: Vec,
- pub(crate) config: Option,
+ pub(crate) root_config: Option,
pub(crate) resolver: Box,
#[allow(unused)]
pub(crate) span: Span,
@@ -30,7 +30,7 @@ impl std::fmt::Debug for ChildInit {
.field("runtime_id", &self.runtime_id)
.field("allow_latest", &self.allow_latest)
.field("allowed_insecure", &self.allowed_insecure)
- .field("config", &self.config)
+ .field("root_config", &self.root_config)
.finish()
}
}
diff --git a/crates/wick/wick-runtime/src/runtime_service/init.rs b/crates/wick/wick-runtime/src/runtime_service/init.rs
index f0272e637..6dd6171f6 100644
--- a/crates/wick/wick-runtime/src/runtime_service/init.rs
+++ b/crates/wick/wick-runtime/src/runtime_service/init.rs
@@ -46,11 +46,11 @@ impl ServiceInit {
}
}
- pub(super) fn child_init(&self, config: Option) -> ChildInit {
+ pub(super) fn child_init(&self, root_config: Option) -> ChildInit {
ChildInit {
rng_seed: self.rng.seed(),
runtime_id: self.id,
- config,
+ root_config,
allow_latest: self.allow_latest,
allowed_insecure: self.allowed_insecure.clone(),
resolver: self.manifest.resolver(),
diff --git a/crates/wick/wick-runtime/src/runtime_service/utils.rs b/crates/wick/wick-runtime/src/runtime_service/utils.rs
index e019d7a16..1e8b5b297 100644
--- a/crates/wick/wick-runtime/src/runtime_service/utils.rs
+++ b/crates/wick/wick-runtime/src/runtime_service/utils.rs
@@ -52,12 +52,12 @@ pub(crate) async fn instantiate_import(
opts.span.in_scope(|| debug!(?binding, ?opts, "instantiating import"));
let id = binding.id().to_owned();
match binding.kind() {
- config::ImportDefinition::Component(c) => instantiate_component(id, c, opts).await,
+ config::ImportDefinition::Component(c) => instantiate_imported_component(id, c, opts).await,
config::ImportDefinition::Types(_) => Ok(None),
}
}
-pub(crate) async fn instantiate_component(
+pub(crate) async fn instantiate_imported_component(
id: String,
kind: &ComponentDefinition,
opts: ChildInit,
@@ -65,20 +65,13 @@ pub(crate) async fn instantiate_component(
match kind {
#[allow(deprecated)]
config::ComponentDefinition::Wasm(def) => Ok(Some(
- init_wasm_component(
- def.reference(),
- Some(def.permissions().clone()),
- id,
- opts,
- Default::default(),
- )
- .await?,
+ init_wasm_component(def.reference(), id, opts, None, Default::default()).await?,
)),
config::ComponentDefinition::Manifest(def) => Ok(Some(init_manifest_component(def, id, opts).await?)),
config::ComponentDefinition::Reference(_) => unreachable!(),
config::ComponentDefinition::GrpcUrl(_) => todo!(), // CollectionKind::GrpcUrl(v) => initialize_grpc_collection(v, namespace).await,
config::ComponentDefinition::HighLevelComponent(hlc) => {
- init_hlc_component(id, opts.config.clone(), None, hlc.clone(), opts.resolver)
+ init_hlc_component(id, opts.root_config.clone(), None, hlc.clone(), opts.resolver)
.await
.map(Some)
}
diff --git a/crates/wick/wick-runtime/src/triggers.rs b/crates/wick/wick-runtime/src/triggers.rs
index 768b3573a..5e5fb28b3 100644
--- a/crates/wick/wick-runtime/src/triggers.rs
+++ b/crates/wick/wick-runtime/src/triggers.rs
@@ -74,15 +74,8 @@ pub(crate) fn resolve_or_import_component(
if let ComponentDefinition::Reference(cref) = operation.component() {
let _assert = app_config
.resolve_binding(cref.id())
- .ok_or_else(|| {
- RuntimeError::InitializationFailed(format!("Could not find a component by the name of {}", cref.id()))
- })?
.map_err(|e| {
- RuntimeError::InitializationFailed(format!(
- "Could not render configuration for component {}: error was {}",
- cref.id(),
- e
- ))
+ RuntimeError::InitializationFailed(format!("Error initializing component {}: error was {}", cref.id(), e))
})?
.try_component()
.map_err(|e| RuntimeError::ReferenceError(cref.id().to_owned(), e))?;
@@ -102,15 +95,8 @@ pub(crate) fn resolve_ref(
let def = if let ComponentDefinition::Reference(cref) = component {
app_config
.resolve_binding(cref.id())
- .ok_or_else(|| {
- RuntimeError::InitializationFailed(format!("Could not find a component by the name of {}", cref.id()))
- })?
.map_err(|e| {
- RuntimeError::InitializationFailed(format!(
- "Could not render configuration for component {}: error was {}",
- cref.id(),
- e
- ))
+ RuntimeError::InitializationFailed(format!("Error initializing component {}: error was {}", cref.id(), e))
})?
.try_component()
.map_err(|e| RuntimeError::ReferenceError(cref.id().to_owned(), e))?
diff --git a/crates/wick/wick-test/src/test_group.rs b/crates/wick/wick-test/src/test_group.rs
index e592f06e5..2f388f800 100644
--- a/crates/wick/wick-test/src/test_group.rs
+++ b/crates/wick/wick-test/src/test_group.rs
@@ -1,6 +1,6 @@
use flow_component::SharedComponent;
use tap_harness::TestRunner;
-use wick_config::config::TestCase;
+use wick_config::config::test_case::TestCase;
use wick_packet::RuntimeConfig;
use crate::{run_test, TestError, UnitTest};
diff --git a/crates/wick/wick-test/src/unit_test.rs b/crates/wick/wick-test/src/unit_test.rs
index b9237a895..a0dc3c215 100644
--- a/crates/wick/wick-test/src/unit_test.rs
+++ b/crates/wick/wick-test/src/unit_test.rs
@@ -2,7 +2,7 @@ use std::collections::{HashMap, HashSet, VecDeque};
use std::time::{SystemTime, UNIX_EPOCH};
use serde_value::Value;
-use wick_config::config::TestCase;
+use wick_config::config::test_case::TestCase;
use wick_packet::{InherentData, Packet, PacketStream, RuntimeConfig};
use crate::error::AssertionFailure;
diff --git a/crates/wick/wick-test/src/utils.rs b/crates/wick/wick-test/src/utils.rs
index 8fbb5227c..03e16b191 100644
--- a/crates/wick/wick-test/src/utils.rs
+++ b/crates/wick/wick-test/src/utils.rs
@@ -1,7 +1,8 @@
use std::collections::HashMap;
use wasmrs_codec::messagepack;
-use wick_config::config::{LiquidJsonConfig, PacketFlag, TestPacket};
+use wick_config::config::test_case::{PacketFlag, TestPacket};
+use wick_config::config::LiquidJsonConfig;
use wick_packet::{
InherentData,
Packet,
diff --git a/crates/wick/wick-test/tests/done_tolerance.rs b/crates/wick/wick-test/tests/done_tolerance.rs
index 926288c6a..20bf59812 100644
--- a/crates/wick/wick-test/tests/done_tolerance.rs
+++ b/crates/wick/wick-test/tests/done_tolerance.rs
@@ -5,7 +5,8 @@ use anyhow::Result;
use flow_component::{Component, RuntimeCallback, SharedComponent};
use serde_json::json;
use tokio_stream::StreamExt;
-use wick_config::config::{TestCaseBuilder, TestConfigurationBuilder, TestPacket};
+use wick_config::config::test_case::{TestCaseBuilder, TestPacket};
+use wick_config::config::TestConfigurationBuilder;
use wick_interface_types::{component, ComponentSignature};
use wick_packet::{Invocation, Packet, PacketStream, RuntimeConfig};
use wick_test::{ComponentFactory, TestSuite};
diff --git a/docs/content/configuration/reference/v1.md b/docs/content/configuration/reference/v1.md
index c86c18be7..8c0a52844 100644
--- a/docs/content/configuration/reference/v1.md
+++ b/docs/content/configuration/reference/v1.md
@@ -732,11 +732,29 @@ Any one of the following types:
| Field name | Type | Description | Required? | Shortform? |
|------------|------|-------------|-----------|------------|
| `kind` | `string` | must be `"wick/component/wasmrs@v1"` | Yes | || `ref` | [`LocationReference`](#locationreference)
|The path or OCI reference to the WebAssembly module|Yes||
+| `volumes` | [`ExposedVolume`](#exposedvolume)[]
|Volumes to expose to the component.|||
| `with` | [`Field`](#field)[]
|Configuration necessary to provide when instantiating the component.|||
| `operations` | [`OperationDefinition`](#operationdefinition)[]
|A list of operations implemented by the WebAssembly module.|||
+--------
+
+## ExposedVolume
+
+
+
Volumes to expose to a component and the internal paths they map to.
+
+
+
+
+| Field name | Type | Description | Required? | Shortform? |
+|------------|------|-------------|-----------|------------|
+| `resource` | `string`
|The resource ID of the volume.|Yes||
+| `path` | `string`
|The path to map it to in the component.|Yes||
+
+
+
--------
## ComponentKind
diff --git a/examples/components/wasi-fs/.cargo/config b/examples/components/wasi-fs/.cargo/config
new file mode 100644
index 000000000..e69de29bb
diff --git a/examples/components/wasi-fs/.gitignore b/examples/components/wasi-fs/.gitignore
new file mode 100644
index 000000000..82448ccd9
--- /dev/null
+++ b/examples/components/wasi-fs/.gitignore
@@ -0,0 +1,2 @@
+/target
+/build
diff --git a/examples/components/wasi-fs/.vscode/settings.json b/examples/components/wasi-fs/.vscode/settings.json
new file mode 100644
index 000000000..1cd2bd528
--- /dev/null
+++ b/examples/components/wasi-fs/.vscode/settings.json
@@ -0,0 +1,6 @@
+{
+ "rust-analyzer.cargo.target": "wasm32-unknown-unknown",
+ "extensions": [
+ "CandleCorp.wick-development-framework"
+ ]
+}
\ No newline at end of file
diff --git a/examples/components/wasi-fs/Cargo.lock b/examples/components/wasi-fs/Cargo.lock
new file mode 100644
index 000000000..2b5c819d4
--- /dev/null
+++ b/examples/components/wasi-fs/Cargo.lock
@@ -0,0 +1,2745 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "addr2line"
+version = "0.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3"
+dependencies = [
+ "gimli",
+]
+
+[[package]]
+name = "adler"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
+
+[[package]]
+name = "aho-corasick"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "android-tzdata"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
+
+[[package]]
+name = "android_system_properties"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "anyhow"
+version = "1.0.72"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854"
+
+[[package]]
+name = "anymap2"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d301b3b94cb4b2f23d7917810addbbaff90738e0ca2be692bd027e70d7e0330c"
+
+[[package]]
+name = "asset-container"
+version = "0.2.0"
+dependencies = [
+ "bitflags 2.3.3",
+ "futures 0.3.28",
+ "thiserror",
+]
+
+[[package]]
+name = "async-recursion"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0e97ce7de6cf12de5d7226c73f5ba9811622f4db3a5b91b55c53e987e5f91cba"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.27",
+]
+
+[[package]]
+name = "async-trait"
+version = "0.1.72"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.27",
+]
+
+[[package]]
+name = "atomic-polyfill"
+version = "0.1.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3ff7eb3f316534d83a8a2c3d1674ace8a5a71198eba31e2e2b597833f699b28"
+dependencies = [
+ "critical-section",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+
+[[package]]
+name = "backtrace"
+version = "0.3.68"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12"
+dependencies = [
+ "addr2line",
+ "cc",
+ "cfg-if",
+ "libc",
+ "miniz_oxide",
+ "object",
+ "rustc-demangle",
+]
+
+[[package]]
+name = "base64"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
+
+[[package]]
+name = "base64"
+version = "0.21.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d"
+
+[[package]]
+name = "base64-serde"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ba368df5de76a5bea49aaf0cf1b39ccfbbef176924d1ba5db3e4135216cbe3c7"
+dependencies = [
+ "base64 0.21.2",
+ "serde",
+]
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "bitflags"
+version = "2.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42"
+
+[[package]]
+name = "block-buffer"
+version = "0.10.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
+name = "bumpalo"
+version = "3.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1"
+
+[[package]]
+name = "byteorder"
+version = "1.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
+
+[[package]]
+name = "bytes"
+version = "0.4.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c"
+dependencies = [
+ "byteorder",
+ "iovec",
+]
+
+[[package]]
+name = "bytes"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "cc"
+version = "1.0.79"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "check_keyword"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e4d532198271d4fb82f944bd25527e760a6cfc966c7d592525e092d4c6a4f787"
+
+[[package]]
+name = "chrono"
+version = "0.4.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5"
+dependencies = [
+ "android-tzdata",
+ "iana-time-zone",
+ "num-traits",
+ "serde",
+ "winapi",
+]
+
+[[package]]
+name = "core-foundation-sys"
+version = "0.8.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
+
+[[package]]
+name = "cpufeatures"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "crc32fast"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "critical-section"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52"
+
+[[package]]
+name = "crossbeam-channel"
+version = "0.5.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200"
+dependencies = [
+ "cfg-if",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.8.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "crypto-common"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
+dependencies = [
+ "generic-array",
+ "typenum",
+]
+
+[[package]]
+name = "darling"
+version = "0.14.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850"
+dependencies = [
+ "darling_core 0.14.4",
+ "darling_macro 0.14.4",
+]
+
+[[package]]
+name = "darling"
+version = "0.20.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e"
+dependencies = [
+ "darling_core 0.20.3",
+ "darling_macro 0.20.3",
+]
+
+[[package]]
+name = "darling_core"
+version = "0.14.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0"
+dependencies = [
+ "fnv",
+ "ident_case",
+ "proc-macro2",
+ "quote",
+ "strsim",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "darling_core"
+version = "0.20.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621"
+dependencies = [
+ "fnv",
+ "ident_case",
+ "proc-macro2",
+ "quote",
+ "strsim",
+ "syn 2.0.27",
+]
+
+[[package]]
+name = "darling_macro"
+version = "0.14.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e"
+dependencies = [
+ "darling_core 0.14.4",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "darling_macro"
+version = "0.20.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5"
+dependencies = [
+ "darling_core 0.20.3",
+ "quote",
+ "syn 2.0.27",
+]
+
+[[package]]
+name = "dashmap"
+version = "5.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6943ae99c34386c84a470c499d3414f66502a41340aa895406e0d2e4a207b91d"
+dependencies = [
+ "cfg-if",
+ "hashbrown 0.14.0",
+ "lock_api",
+ "once_cell",
+ "parking_lot_core",
+]
+
+[[package]]
+name = "derive-asset-container"
+version = "0.2.0"
+dependencies = [
+ "asset-container",
+ "proc-macro2",
+ "quote",
+ "structmeta",
+ "syn 2.0.27",
+]
+
+[[package]]
+name = "derive_builder"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8"
+dependencies = [
+ "derive_builder_macro",
+]
+
+[[package]]
+name = "derive_builder_core"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f"
+dependencies = [
+ "darling 0.14.4",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "derive_builder_macro"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e"
+dependencies = [
+ "derive_builder_core",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "digest"
+version = "0.10.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
+dependencies = [
+ "block-buffer",
+ "crypto-common",
+ "subtle",
+]
+
+[[package]]
+name = "dirs"
+version = "4.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
+dependencies = [
+ "dirs-sys 0.3.7",
+]
+
+[[package]]
+name = "dirs"
+version = "5.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225"
+dependencies = [
+ "dirs-sys 0.4.1",
+]
+
+[[package]]
+name = "dirs-sys"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
+dependencies = [
+ "libc",
+ "redox_users",
+ "winapi",
+]
+
+[[package]]
+name = "dirs-sys"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
+dependencies = [
+ "libc",
+ "option-ext",
+ "redox_users",
+ "windows-sys",
+]
+
+[[package]]
+name = "doc-comment"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
+
+[[package]]
+name = "either"
+version = "1.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
+
+[[package]]
+name = "encoding_rs"
+version = "0.8.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "equivalent"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
+
+[[package]]
+name = "filetime"
+version = "0.2.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5cbc844cecaee9d4443931972e1289c8ff485cb4cc2767cb03ca139ed6885153"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "redox_syscall 0.2.16",
+ "windows-sys",
+]
+
+[[package]]
+name = "flate2"
+version = "1.0.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743"
+dependencies = [
+ "crc32fast",
+ "miniz_oxide",
+]
+
+[[package]]
+name = "flow-component"
+version = "0.5.0"
+dependencies = [
+ "anyhow",
+ "futures 0.3.28",
+ "liquid-json",
+ "seeded-random",
+ "serde",
+ "serde_json",
+ "tracing",
+ "wick-interface-types",
+ "wick-packet",
+]
+
+[[package]]
+name = "flow-expression-parser"
+version = "0.5.0"
+dependencies = [
+ "liquid-json",
+ "nom",
+ "once_cell",
+ "parking_lot",
+ "regex",
+ "seeded-random",
+ "serde",
+ "serde_json",
+ "thiserror",
+ "uuid",
+]
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
+name = "form_urlencoded"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652"
+dependencies = [
+ "percent-encoding",
+]
+
+[[package]]
+name = "futures"
+version = "0.1.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678"
+
+[[package]]
+name = "futures"
+version = "0.3.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "futures-executor",
+ "futures-io",
+ "futures-sink",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-channel"
+version = "0.3.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2"
+dependencies = [
+ "futures-core",
+ "futures-sink",
+]
+
+[[package]]
+name = "futures-core"
+version = "0.3.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c"
+
+[[package]]
+name = "futures-executor"
+version = "0.3.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0"
+dependencies = [
+ "futures-core",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-io"
+version = "0.3.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964"
+
+[[package]]
+name = "futures-macro"
+version = "0.3.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.27",
+]
+
+[[package]]
+name = "futures-sink"
+version = "0.3.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e"
+
+[[package]]
+name = "futures-task"
+version = "0.3.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65"
+
+[[package]]
+name = "futures-util"
+version = "0.3.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533"
+dependencies = [
+ "futures 0.1.31",
+ "futures-channel",
+ "futures-core",
+ "futures-io",
+ "futures-macro",
+ "futures-sink",
+ "futures-task",
+ "memchr",
+ "pin-project-lite",
+ "pin-utils",
+ "slab",
+ "tokio-io",
+]
+
+[[package]]
+name = "generic-array"
+version = "0.14.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
+dependencies = [
+ "typenum",
+ "version_check",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.2.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi",
+]
+
+[[package]]
+name = "getset"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e45727250e75cc04ff2846a66397da8ef2b3db8e40e0cef4df67950a07621eb9"
+dependencies = [
+ "proc-macro-error",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "gimli"
+version = "0.27.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e"
+
+[[package]]
+name = "glob"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
+
+[[package]]
+name = "h2"
+version = "0.3.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049"
+dependencies = [
+ "bytes 1.4.0",
+ "fnv",
+ "futures-core",
+ "futures-sink",
+ "futures-util",
+ "http",
+ "indexmap 1.9.3",
+ "slab",
+ "tokio",
+ "tokio-util",
+ "tracing",
+]
+
+[[package]]
+name = "hash32"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67"
+dependencies = [
+ "byteorder",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+
+[[package]]
+name = "hashbrown"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
+
+[[package]]
+name = "heapless"
+version = "0.7.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743"
+dependencies = [
+ "atomic-polyfill",
+ "hash32",
+ "rustc_version",
+ "spin 0.9.8",
+ "stable_deref_trait",
+]
+
+[[package]]
+name = "heck"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
+
+[[package]]
+name = "hermit-abi"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b"
+
+[[package]]
+name = "hex"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
+
+[[package]]
+name = "hmac"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
+dependencies = [
+ "digest",
+]
+
+[[package]]
+name = "http"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482"
+dependencies = [
+ "bytes 1.4.0",
+ "fnv",
+ "itoa",
+]
+
+[[package]]
+name = "http-auth"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5430cacd7a1f9a02fbeb350dfc81a0e5ed42d81f3398cb0ba184017f85bdcfbc"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "http-body"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
+dependencies = [
+ "bytes 1.4.0",
+ "http",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "httparse"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
+
+[[package]]
+name = "httpdate"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
+
+[[package]]
+name = "hyper"
+version = "0.14.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468"
+dependencies = [
+ "bytes 1.4.0",
+ "futures-channel",
+ "futures-core",
+ "futures-util",
+ "h2",
+ "http",
+ "http-body",
+ "httparse",
+ "httpdate",
+ "itoa",
+ "pin-project-lite",
+ "socket2",
+ "tokio",
+ "tower-service",
+ "tracing",
+ "want",
+]
+
+[[package]]
+name = "hyper-rustls"
+version = "0.24.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97"
+dependencies = [
+ "futures-util",
+ "http",
+ "hyper",
+ "rustls",
+ "tokio",
+ "tokio-rustls",
+]
+
+[[package]]
+name = "iana-time-zone"
+version = "0.1.57"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613"
+dependencies = [
+ "android_system_properties",
+ "core-foundation-sys",
+ "iana-time-zone-haiku",
+ "js-sys",
+ "wasm-bindgen",
+ "windows",
+]
+
+[[package]]
+name = "iana-time-zone-haiku"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "ident_case"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
+
+[[package]]
+name = "idna"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c"
+dependencies = [
+ "unicode-bidi",
+ "unicode-normalization",
+]
+
+[[package]]
+name = "indexmap"
+version = "1.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
+dependencies = [
+ "autocfg",
+ "hashbrown 0.12.3",
+ "serde",
+]
+
+[[package]]
+name = "indexmap"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d"
+dependencies = [
+ "equivalent",
+ "hashbrown 0.14.0",
+]
+
+[[package]]
+name = "iovec"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "ipnet"
+version = "2.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6"
+
+[[package]]
+name = "itertools"
+version = "0.10.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "itoa"
+version = "1.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
+
+[[package]]
+name = "js-sys"
+version = "0.3.64"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a"
+dependencies = [
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "jwt"
+version = "0.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6204285f77fe7d9784db3fdc449ecce1a0114927a51d5a41c4c7a292011c015f"
+dependencies = [
+ "base64 0.13.1",
+ "crypto-common",
+ "digest",
+ "hmac",
+ "serde",
+ "serde_json",
+ "sha2",
+]
+
+[[package]]
+name = "kstring"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec3066350882a1cd6d950d055997f379ac37fd39f81cd4d8ed186032eb3c5747"
+dependencies = [
+ "serde",
+ "static_assertions",
+]
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "libc"
+version = "0.2.147"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
+
+[[package]]
+name = "liquid"
+version = "0.26.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "69f68ae1011499ae2ef879f631891f21c78e309755f4a5e483c4a8f12e10b609"
+dependencies = [
+ "doc-comment",
+ "liquid-core",
+ "liquid-derive",
+ "liquid-lib",
+ "serde",
+]
+
+[[package]]
+name = "liquid-core"
+version = "0.26.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79e0724dfcaad5cfb7965ea0f178ca0870b8d7315178f4a7179f5696f7f04d5f"
+dependencies = [
+ "anymap2",
+ "itertools",
+ "kstring",
+ "liquid-derive",
+ "num-traits",
+ "pest",
+ "pest_derive",
+ "regex",
+ "serde",
+ "time",
+]
+
+[[package]]
+name = "liquid-derive"
+version = "0.26.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc2fb41a9bb4257a3803154bdf7e2df7d45197d1941c9b1a90ad815231630721"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.27",
+]
+
+[[package]]
+name = "liquid-json"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4d2ca2e69be23a333da932de11a7e9384a34388484fa1e6397b96677e3e5b8bd"
+dependencies = [
+ "base64 0.21.2",
+ "liquid",
+ "liquid-core",
+ "liquid-lib",
+ "once_cell",
+ "regex",
+ "serde",
+ "serde_json",
+ "thiserror",
+]
+
+[[package]]
+name = "liquid-lib"
+version = "0.26.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2a17e273a6fb1fb6268f7a5867ddfd0bd4683c7e19b51084f3d567fad4348c0"
+dependencies = [
+ "itertools",
+ "liquid-core",
+ "once_cell",
+ "percent-encoding",
+ "regex",
+ "time",
+ "unicode-segmentation",
+]
+
+[[package]]
+name = "lock_api"
+version = "0.4.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16"
+dependencies = [
+ "autocfg",
+ "scopeguard",
+]
+
+[[package]]
+name = "log"
+version = "0.4.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
+
+[[package]]
+name = "memchr"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
+
+[[package]]
+name = "mime"
+version = "0.3.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
+
+[[package]]
+name = "minimal-lexical"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
+
+[[package]]
+name = "miniz_oxide"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
+dependencies = [
+ "adler",
+]
+
+[[package]]
+name = "mio"
+version = "0.8.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
+dependencies = [
+ "libc",
+ "wasi",
+ "windows-sys",
+]
+
+[[package]]
+name = "nom"
+version = "7.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
+dependencies = [
+ "memchr",
+ "minimal-lexical",
+]
+
+[[package]]
+name = "normpath"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec60c60a693226186f5d6edf073232bfb6464ed97eb22cf3b01c1e8198fd97f5"
+dependencies = [
+ "windows-sys",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "num_cpus"
+version = "1.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
+dependencies = [
+ "hermit-abi",
+ "libc",
+]
+
+[[package]]
+name = "object"
+version = "0.31.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "oci-distribution"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2ac5b780ce1bd6c3c2ff72a3013f4b2d56d53ae03b20d424e99d2f6556125138"
+dependencies = [
+ "futures 0.3.28",
+ "futures-util",
+ "http",
+ "http-auth",
+ "jwt",
+ "lazy_static",
+ "olpc-cjson",
+ "regex",
+ "reqwest",
+ "serde",
+ "serde_json",
+ "sha2",
+ "thiserror",
+ "tokio",
+ "tokio-util",
+ "tracing",
+ "unicase",
+]
+
+[[package]]
+name = "olpc-cjson"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d637c9c15b639ccff597da8f4fa968300651ad2f1e968aefc3b4927a6fb2027a"
+dependencies = [
+ "serde",
+ "serde_json",
+ "unicode-normalization",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.18.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
+
+[[package]]
+name = "option-ext"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
+
+[[package]]
+name = "option-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1800ff62dcf34d7de2c7b7c84e3107a19708578441bd998eaddadb1134a4b007"
+
+[[package]]
+name = "ordered-float"
+version = "2.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7940cf2ca942593318d07fcf2596cdca60a85c9e7fab408a5e21a4f9dcd40d87"
+dependencies = [
+ "num-traits",
+]
+
+[[package]]
+name = "parking_lot"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
+dependencies = [
+ "lock_api",
+ "parking_lot_core",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.9.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "redox_syscall 0.3.5",
+ "smallvec",
+ "windows-targets",
+]
+
+[[package]]
+name = "paste"
+version = "1.0.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
+
+[[package]]
+name = "percent-encoding"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
+
+[[package]]
+name = "pest"
+version = "2.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d2d1d55045829d65aad9d389139882ad623b33b904e7c9f1b10c5b8927298e5"
+dependencies = [
+ "thiserror",
+ "ucd-trie",
+]
+
+[[package]]
+name = "pest_derive"
+version = "2.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f94bca7e7a599d89dea5dfa309e217e7906c3c007fb9c3299c40b10d6a315d3"
+dependencies = [
+ "pest",
+ "pest_generator",
+]
+
+[[package]]
+name = "pest_generator"
+version = "2.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "99d490fe7e8556575ff6911e45567ab95e71617f43781e5c05490dc8d75c965c"
+dependencies = [
+ "pest",
+ "pest_meta",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.27",
+]
+
+[[package]]
+name = "pest_meta"
+version = "2.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2674c66ebb4b4d9036012091b537aae5878970d6999f81a265034d85b136b341"
+dependencies = [
+ "once_cell",
+ "pest",
+ "sha2",
+]
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57"
+
+[[package]]
+name = "pin-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+
+[[package]]
+name = "ppv-lite86"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
+
+[[package]]
+name = "prettyplease"
+version = "0.2.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c64d9ba0963cdcea2e1b2230fbae2bab30eb25a174be395c41e764bfb65dd62"
+dependencies = [
+ "proc-macro2",
+ "syn 2.0.27",
+]
+
+[[package]]
+name = "proc-macro-crate"
+version = "1.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919"
+dependencies = [
+ "once_cell",
+ "toml_edit",
+]
+
+[[package]]
+name = "proc-macro-error"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
+dependencies = [
+ "proc-macro-error-attr",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro-error-attr"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.66"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "property"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "889bff6ebe76dbef2685598944997eb7f15c9854a2e34db853a51c6ac158b9d5"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "rand"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
+dependencies = [
+ "libc",
+ "rand_chacha",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
+dependencies = [
+ "ppv-lite86",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
+dependencies = [
+ "getrandom",
+]
+
+[[package]]
+name = "redox_syscall"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
+dependencies = [
+ "bitflags 1.3.2",
+]
+
+[[package]]
+name = "redox_syscall"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
+dependencies = [
+ "bitflags 1.3.2",
+]
+
+[[package]]
+name = "redox_users"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
+dependencies = [
+ "getrandom",
+ "redox_syscall 0.2.16",
+ "thiserror",
+]
+
+[[package]]
+name = "regex"
+version = "1.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-automata",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2"
+
+[[package]]
+name = "reqwest"
+version = "0.11.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55"
+dependencies = [
+ "base64 0.21.2",
+ "bytes 1.4.0",
+ "encoding_rs",
+ "futures-core",
+ "futures-util",
+ "h2",
+ "http",
+ "http-body",
+ "hyper",
+ "hyper-rustls",
+ "ipnet",
+ "js-sys",
+ "log",
+ "mime",
+ "once_cell",
+ "percent-encoding",
+ "pin-project-lite",
+ "rustls",
+ "rustls-pemfile",
+ "serde",
+ "serde_json",
+ "serde_urlencoded",
+ "tokio",
+ "tokio-rustls",
+ "tokio-util",
+ "tower-service",
+ "url",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "wasm-streams",
+ "web-sys",
+ "webpki-roots",
+ "winreg",
+]
+
+[[package]]
+name = "ring"
+version = "0.16.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
+dependencies = [
+ "cc",
+ "libc",
+ "once_cell",
+ "spin 0.5.2",
+ "untrusted",
+ "web-sys",
+ "winapi",
+]
+
+[[package]]
+name = "rmp"
+version = "0.8.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f9860a6cc38ed1da53456442089b4dfa35e7cedaa326df63017af88385e6b20"
+dependencies = [
+ "byteorder",
+ "num-traits",
+ "paste",
+]
+
+[[package]]
+name = "rmp-serde"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bffea85eea980d8a74453e5d02a8d93028f3c34725de143085a844ebe953258a"
+dependencies = [
+ "byteorder",
+ "rmp",
+ "serde",
+]
+
+[[package]]
+name = "rustc-demangle"
+version = "0.1.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
+
+[[package]]
+name = "rustc_version"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
+dependencies = [
+ "semver",
+]
+
+[[package]]
+name = "rustls"
+version = "0.21.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79ea77c539259495ce8ca47f53e66ae0330a8819f67e23ac96ca02f50e7b7d36"
+dependencies = [
+ "log",
+ "ring",
+ "rustls-webpki",
+ "sct",
+]
+
+[[package]]
+name = "rustls-pemfile"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2"
+dependencies = [
+ "base64 0.21.2",
+]
+
+[[package]]
+name = "rustls-webpki"
+version = "0.101.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "15f36a6828982f422756984e47912a7a51dcbc2a197aa791158f8ca61cd8204e"
+dependencies = [
+ "ring",
+ "untrusted",
+]
+
+[[package]]
+name = "ryu"
+version = "1.0.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
+
+[[package]]
+name = "scopeguard"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
+
+[[package]]
+name = "sct"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
+dependencies = [
+ "ring",
+ "untrusted",
+]
+
+[[package]]
+name = "seeded-random"
+version = "0.3.0"
+dependencies = [
+ "parking_lot",
+ "rand",
+ "rand_chacha",
+ "uuid",
+]
+
+[[package]]
+name = "semver"
+version = "1.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918"
+
+[[package]]
+name = "serde"
+version = "1.0.175"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d25439cd7397d044e2748a6fe2432b5e85db703d6d097bd014b3c0ad1ebff0b"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde-value"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c"
+dependencies = [
+ "ordered-float",
+ "serde",
+]
+
+[[package]]
+name = "serde-with-expand-env"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "888d884a3be3a209308d0b66f1918ff18f60e93db837259e53ea7d8dd14e7e98"
+dependencies = [
+ "serde",
+ "shellexpand 2.1.2",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.175"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b23f7ade6f110613c0d63858ddb8b94c1041f550eab58a16b371bdf2c9c80ab4"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.27",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.103"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d03b412469450d4404fe8499a268edd7f8b79fecb074b0d812ad64ca21f4031b"
+dependencies = [
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "serde_repr"
+version = "0.1.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e168eaaf71e8f9bd6037feb05190485708e019f4fd87d161b3c0a0d37daf85e5"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.27",
+]
+
+[[package]]
+name = "serde_urlencoded"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
+dependencies = [
+ "form_urlencoded",
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "serde_with"
+version = "3.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "21e47d95bc83ed33b2ecf84f4187ad1ab9685d18ff28db000c99deac8ce180e3"
+dependencies = [
+ "base64 0.21.2",
+ "chrono",
+ "hex",
+ "indexmap 1.9.3",
+ "serde",
+ "serde_json",
+ "serde_with_macros",
+ "time",
+]
+
+[[package]]
+name = "serde_with_macros"
+version = "3.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ea3cee93715c2e266b9338b7544da68a9f24e227722ba482bd1c024367c77c65"
+dependencies = [
+ "darling 0.20.3",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.27",
+]
+
+[[package]]
+name = "serde_yaml"
+version = "0.9.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a49e178e4452f45cb61d0cd8cebc1b0fafd3e41929e996cef79aa3aca91f574"
+dependencies = [
+ "indexmap 2.0.0",
+ "itoa",
+ "ryu",
+ "serde",
+ "unsafe-libyaml",
+]
+
+[[package]]
+name = "sha2"
+version = "0.10.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "digest",
+]
+
+[[package]]
+name = "sha256"
+version = "1.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "386f700b0c798d92ac20a53342c240ff9d58030c3b845fbaeb92eead3a774792"
+dependencies = [
+ "async-trait",
+ "bytes 1.4.0",
+ "hex",
+ "sha2",
+ "tokio",
+]
+
+[[package]]
+name = "shellexpand"
+version = "2.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ccc8076840c4da029af4f87e4e8daeb0fca6b87bbb02e10cb60b791450e11e4"
+dependencies = [
+ "dirs 4.0.0",
+]
+
+[[package]]
+name = "shellexpand"
+version = "3.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da03fa3b94cc19e3ebfc88c4229c49d8f08cdbd1228870a45f0ffdf84988e14b"
+dependencies = [
+ "dirs 5.0.1",
+]
+
+[[package]]
+name = "slab"
+version = "0.4.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "smallvec"
+version = "1.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
+
+[[package]]
+name = "socket2"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662"
+dependencies = [
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "spin"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
+
+[[package]]
+name = "spin"
+version = "0.9.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
+dependencies = [
+ "lock_api",
+]
+
+[[package]]
+name = "stable_deref_trait"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
+
+[[package]]
+name = "static_assertions"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
+
+[[package]]
+name = "strsim"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
+
+[[package]]
+name = "structmeta"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78ad9e09554f0456d67a69c1584c9798ba733a5b50349a6c0d0948710523922d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "structmeta-derive",
+ "syn 2.0.27",
+]
+
+[[package]]
+name = "structmeta-derive"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a60bcaff7397072dca0017d1db428e30d5002e00b6847703e2e42005c95fbe00"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.27",
+]
+
+[[package]]
+name = "subtle"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
+
+[[package]]
+name = "syn"
+version = "1.0.109"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "tar"
+version = "0.4.39"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec96d2ffad078296368d46ff1cb309be1c23c513b4ab0e22a45de0185275ac96"
+dependencies = [
+ "filetime",
+ "libc",
+ "xattr",
+]
+
+[[package]]
+name = "thiserror"
+version = "1.0.44"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.44"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.27",
+]
+
+[[package]]
+name = "time"
+version = "0.3.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59e399c068f43a5d116fedaf73b203fa4f9c519f17e2b34f63221d3792f81446"
+dependencies = [
+ "itoa",
+ "serde",
+ "time-core",
+ "time-macros",
+]
+
+[[package]]
+name = "time-core"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb"
+
+[[package]]
+name = "time-macros"
+version = "0.2.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96ba15a897f3c86766b757e5ac7221554c6750054d74d5b28844fce5fb36a6c4"
+dependencies = [
+ "time-core",
+]
+
+[[package]]
+name = "tinyvec"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
+dependencies = [
+ "tinyvec_macros",
+]
+
+[[package]]
+name = "tinyvec_macros"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
+
+[[package]]
+name = "tokio"
+version = "1.29.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da"
+dependencies = [
+ "autocfg",
+ "backtrace",
+ "bytes 1.4.0",
+ "libc",
+ "mio",
+ "num_cpus",
+ "pin-project-lite",
+ "socket2",
+ "tokio-macros",
+ "windows-sys",
+]
+
+[[package]]
+name = "tokio-io"
+version = "0.1.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674"
+dependencies = [
+ "bytes 0.4.12",
+ "futures 0.1.31",
+ "log",
+]
+
+[[package]]
+name = "tokio-macros"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.27",
+]
+
+[[package]]
+name = "tokio-rustls"
+version = "0.24.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
+dependencies = [
+ "rustls",
+ "tokio",
+]
+
+[[package]]
+name = "tokio-stream"
+version = "0.1.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842"
+dependencies = [
+ "futures-core",
+ "pin-project-lite",
+ "tokio",
+]
+
+[[package]]
+name = "tokio-util"
+version = "0.7.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d"
+dependencies = [
+ "bytes 1.4.0",
+ "futures-core",
+ "futures-io",
+ "futures-sink",
+ "pin-project-lite",
+ "tokio",
+ "tracing",
+]
+
+[[package]]
+name = "toml_datetime"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"
+
+[[package]]
+name = "toml_edit"
+version = "0.19.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a"
+dependencies = [
+ "indexmap 2.0.0",
+ "toml_datetime",
+ "winnow",
+]
+
+[[package]]
+name = "tower-service"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
+
+[[package]]
+name = "tracing"
+version = "0.1.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
+dependencies = [
+ "cfg-if",
+ "log",
+ "pin-project-lite",
+ "tracing-attributes",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-attributes"
+version = "0.1.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.27",
+]
+
+[[package]]
+name = "tracing-core"
+version = "0.1.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a"
+dependencies = [
+ "once_cell",
+]
+
+[[package]]
+name = "try-lock"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
+
+[[package]]
+name = "typenum"
+version = "1.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
+
+[[package]]
+name = "ucd-trie"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9"
+
+[[package]]
+name = "unicase"
+version = "2.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
+dependencies = [
+ "version_check",
+]
+
+[[package]]
+name = "unicode-bidi"
+version = "0.3.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
+
+[[package]]
+name = "unicode-normalization"
+version = "0.1.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
+dependencies = [
+ "tinyvec",
+]
+
+[[package]]
+name = "unicode-segmentation"
+version = "1.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
+
+[[package]]
+name = "unsafe-libyaml"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f28467d3e1d3c6586d8f25fa243f544f5800fec42d97032474e17222c2b75cfa"
+
+[[package]]
+name = "untrusted"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
+
+[[package]]
+name = "url"
+version = "2.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb"
+dependencies = [
+ "form_urlencoded",
+ "idna",
+ "percent-encoding",
+]
+
+[[package]]
+name = "uuid"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d"
+dependencies = [
+ "getrandom",
+]
+
+[[package]]
+name = "version_check"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+
+[[package]]
+name = "want"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
+dependencies = [
+ "try-lock",
+]
+
+[[package]]
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
+[[package]]
+name = "wasi-fs"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "async-trait",
+ "serde",
+ "wick-component",
+ "wick-component-codegen",
+]
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.87"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342"
+dependencies = [
+ "cfg-if",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.87"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd"
+dependencies = [
+ "bumpalo",
+ "log",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.27",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-futures"
+version = "0.4.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03"
+dependencies = [
+ "cfg-if",
+ "js-sys",
+ "wasm-bindgen",
+ "web-sys",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.87"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.87"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.27",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.87"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
+
+[[package]]
+name = "wasm-streams"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6bbae3363c08332cadccd13b67db371814cd214c2524020932f0804b8cf7c078"
+dependencies = [
+ "futures-util",
+ "js-sys",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "web-sys",
+]
+
+[[package]]
+name = "wasmrs"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9e639ca1fefefe446ed77443865dd2298ed5a22e22992944e2b03d931cf11ab"
+dependencies = [
+ "bytes 1.4.0",
+ "crossbeam-channel",
+ "dashmap",
+ "futures 0.3.28",
+ "futures-executor",
+ "futures-util",
+ "parking_lot",
+ "pin-project-lite",
+ "tokio",
+ "tracing",
+ "wasmrs-codec",
+ "wasmrs-frames",
+ "wasmrs-runtime",
+ "wasmrs-rx",
+]
+
+[[package]]
+name = "wasmrs-codec"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa033a409e0a05d24013fdf15becafaba5e13c3eee1706dd687e63ff6e5aa2e2"
+dependencies = [
+ "heapless",
+ "rmp-serde",
+ "serde",
+ "wasmrs-frames",
+]
+
+[[package]]
+name = "wasmrs-frames"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5379743c49fe234b5191beb98c9891ce6f90df2358f442d124bc3b10857ff74c"
+dependencies = [
+ "bytes 1.4.0",
+ "serde",
+]
+
+[[package]]
+name = "wasmrs-guest"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c80fe87a96b758f19ee3c96bffcbd14549affc32a7811dfccb8f0e2acd119616"
+dependencies = [
+ "bytes 1.4.0",
+ "cfg-if",
+ "futures-executor",
+ "futures-util",
+ "serde",
+ "serde_json",
+ "tracing",
+ "wasmrs",
+ "wasmrs-codec",
+ "wasmrs-frames",
+ "wasmrs-runtime",
+ "wasmrs-rx",
+]
+
+[[package]]
+name = "wasmrs-runtime"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be63ea5457fca88c949665f1dcf0752842777baa762af5d6d053aa8a8576cb3d"
+dependencies = [
+ "bytes 1.4.0",
+ "crossbeam-channel",
+ "dashmap",
+ "futures 0.3.28",
+ "futures-executor",
+ "futures-util",
+ "parking_lot",
+ "pin-project-lite",
+ "tokio",
+ "tracing",
+ "wasmrs-frames",
+]
+
+[[package]]
+name = "wasmrs-rx"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b2ae214a4ff7272c6d4f718626f9a4a85d239be37c8059e7952ec32b99189d5"
+dependencies = [
+ "async-trait",
+ "bytes 1.4.0",
+ "crossbeam-channel",
+ "dashmap",
+ "futures 0.3.28",
+ "futures-executor",
+ "futures-util",
+ "parking_lot",
+ "pin-project-lite",
+ "tracing",
+ "wasmrs-runtime",
+]
+
+[[package]]
+name = "web-sys"
+version = "0.3.64"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b"
+dependencies = [
+ "js-sys",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "webpki"
+version = "0.22.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd"
+dependencies = [
+ "ring",
+ "untrusted",
+]
+
+[[package]]
+name = "webpki-roots"
+version = "0.22.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87"
+dependencies = [
+ "webpki",
+]
+
+[[package]]
+name = "wick-asset-reference"
+version = "0.3.0"
+dependencies = [
+ "asset-container",
+ "bytes 1.4.0",
+ "getset",
+ "normpath",
+ "parking_lot",
+ "serde",
+ "thiserror",
+ "tokio",
+ "tokio-stream",
+ "tracing",
+ "wick-oci-utils",
+]
+
+[[package]]
+name = "wick-component"
+version = "0.15.0"
+dependencies = [
+ "async-recursion",
+ "flow-component",
+ "paste",
+ "serde",
+ "serde_json",
+ "tokio-stream",
+ "tracing",
+ "wasmrs",
+ "wasmrs-codec",
+ "wasmrs-guest",
+ "wasmrs-runtime",
+ "wasmrs-rx",
+ "wick-operation",
+ "wick-packet",
+]
+
+[[package]]
+name = "wick-component-codegen"
+version = "0.4.0"
+dependencies = [
+ "anyhow",
+ "bitflags 2.3.3",
+ "check_keyword",
+ "derive_builder",
+ "heck",
+ "itertools",
+ "prettyplease",
+ "proc-macro2",
+ "quote",
+ "serde_json",
+ "syn 2.0.27",
+ "tokio",
+ "wick-config",
+ "wick-interface-types",
+]
+
+[[package]]
+name = "wick-config"
+version = "0.26.0"
+dependencies = [
+ "asset-container",
+ "derive-asset-container",
+ "derive_builder",
+ "flow-component",
+ "flow-expression-parser",
+ "glob",
+ "liquid-json",
+ "num-traits",
+ "option-utils",
+ "parking_lot",
+ "property",
+ "regex",
+ "serde",
+ "serde-value",
+ "serde-with-expand-env",
+ "serde_json",
+ "serde_with",
+ "serde_yaml",
+ "shellexpand 3.1.0",
+ "thiserror",
+ "tokio",
+ "tracing",
+ "url",
+ "wick-asset-reference",
+ "wick-interface-types",
+ "wick-packet",
+]
+
+[[package]]
+name = "wick-interface-types"
+version = "0.15.0"
+dependencies = [
+ "nom",
+ "serde",
+ "serde_json",
+ "serde_repr",
+ "serde_yaml",
+]
+
+[[package]]
+name = "wick-oci-utils"
+version = "0.3.0"
+dependencies = [
+ "bytes 1.4.0",
+ "derive_builder",
+ "flate2",
+ "getset",
+ "oci-distribution",
+ "once_cell",
+ "regex",
+ "serde",
+ "serde_json",
+ "serde_yaml",
+ "sha256",
+ "tar",
+ "thiserror",
+ "tokio",
+ "tracing",
+ "wick-xdg",
+]
+
+[[package]]
+name = "wick-operation"
+version = "0.1.0"
+dependencies = [
+ "proc-macro-crate",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.27",
+]
+
+[[package]]
+name = "wick-packet"
+version = "0.15.0"
+dependencies = [
+ "base64 0.21.2",
+ "base64-serde",
+ "bytes 1.4.0",
+ "chrono",
+ "liquid-json",
+ "parking_lot",
+ "pin-project-lite",
+ "seeded-random",
+ "serde",
+ "serde_json",
+ "thiserror",
+ "tokio-stream",
+ "tracing",
+ "url",
+ "wasmrs",
+ "wasmrs-codec",
+ "wasmrs-frames",
+ "wasmrs-guest",
+ "wasmrs-runtime",
+ "wasmrs-rx",
+ "wick-interface-types",
+]
+
+[[package]]
+name = "wick-xdg"
+version = "0.2.0"
+dependencies = [
+ "getset",
+ "thiserror",
+ "xdg",
+]
+
+[[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-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "windows"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.48.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
+
+[[package]]
+name = "winnow"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "25b5872fa2e10bd067ae946f927e726d7d603eaeb6e02fa6a350e0722d2b8c11"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "winreg"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "xattr"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d1526bbe5aaeb5eb06885f4d987bcdfa5e23187055de9b83fe00156a821fabc"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "xdg"
+version = "2.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546"
diff --git a/examples/components/wasi-fs/Cargo.toml b/examples/components/wasi-fs/Cargo.toml
new file mode 100644
index 000000000..be900ff66
--- /dev/null
+++ b/examples/components/wasi-fs/Cargo.toml
@@ -0,0 +1,28 @@
+[package]
+name = "wasi-fs"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+[profile.release]
+strip = "symbols"
+codegen-units = 1
+debug = false
+lto = true
+opt-level = "z"
+panic = "abort"
+
+[lib]
+crate-type = ["cdylib"]
+
+[dependencies]
+wick-component = { path = "../../../crates/wick/wick-component" }
+serde = { version = "1", features = ["derive"] }
+async-trait = "0.1"
+anyhow = { version = "1" }
+
+[build-dependencies]
+wick-component-codegen = { path = "../../../crates/wick/wick-component-codegen" }
+
+# Including this section keeps this crate out of a workspace without needing to alter the workspace.
+[workspace]
diff --git a/examples/components/wasi-fs/build.rs b/examples/components/wasi-fs/build.rs
new file mode 100644
index 000000000..fc2db2b44
--- /dev/null
+++ b/examples/components/wasi-fs/build.rs
@@ -0,0 +1,7 @@
+fn main() -> Result<(), Box> {
+ println!("cargo:rerun-if-changed=component.wick");
+ wick_component_codegen::configure()
+ .raw(true)
+ .generate("component.wick")?;
+ Ok(())
+}
diff --git a/examples/components/wasi-fs/component.wick b/examples/components/wasi-fs/component.wick
new file mode 100644
index 000000000..f63acbecf
--- /dev/null
+++ b/examples/components/wasi-fs/component.wick
@@ -0,0 +1,87 @@
+# yaml-language-server: $schema=https://github.com/candlecorp/wick/releases/download/nightly/schema.json
+---
+name: 'wasi-fs'
+kind: wick/component@v1
+metadata:
+ version: '0.0.1'
+resources:
+ - name: ROOT
+ resource:
+ kind: wick/resource/volume@v1
+ path: '{{ctx.root_config.root}}'
+component:
+ kind: wick/component/wasmrs@v1
+ ref: build/component.signed.wasm
+ volumes:
+ - resource: ROOT
+ path: /
+ with:
+ - name: root
+ type: string
+ operations:
+ - name: read_string
+ inputs:
+ - name: filename
+ type: string
+ outputs:
+ - name: output
+ type: string
+ - name: read_bytes
+ inputs:
+ - name: filename
+ type: string
+ outputs:
+ - name: output
+ type: bytes
+ - name: write_string
+ inputs:
+ - name: filename
+ type: string
+ - name: contents
+ type: string
+ outputs:
+ - name: bytes_written
+ type: int
+ # - name: write_bytes
+ # inputs:
+ # - name: filename
+ # type: string
+ # - name: contents
+ # type: bytes
+ # outputs:
+ # - name: bytes_written
+ # type: int
+tests:
+ - with:
+ root: '{{ctx.env.DIR}}'
+ cases:
+ - operation: read_string
+ inputs:
+ - name: filename
+ value: tests/testdata/file.txt
+ outputs:
+ - name: output
+ value: '# Hello World!'
+ - operation: read_bytes
+ inputs:
+ - name: filename
+ value: tests/testdata/file.txt
+ outputs:
+ - name: output
+ value: "{{'# Hello World!'| base64_encode}}"
+ - operation: write_string
+ inputs:
+ - name: filename
+ value: tests/testdata/custom.txt
+ - name: contents
+ value: "{{'now' | date: '%Y-%m-%d %H' }}"
+ outputs:
+ - name: bytes_written
+ value: 13
+ - operation: read_string
+ inputs:
+ - name: filename
+ value: tests/testdata/custom.txt
+ outputs:
+ - name: output
+ value: "{{'now' | date: '%Y-%m-%d %H' }}"
diff --git a/examples/components/wasi-fs/justfile b/examples/components/wasi-fs/justfile
new file mode 100644
index 000000000..58f80c18e
--- /dev/null
+++ b/examples/components/wasi-fs/justfile
@@ -0,0 +1,49 @@
+
+
+# The wick command to use for this project (usually just "wick" but can be a local path during development)
+wick := "cargo run --manifest-path=../../../Cargo.toml -p wick-cli --"
+
+# Get the crate name from the Cargo.toml file (this uses wick instead of {{wick}} due to justfile limitations)
+crate_name := `wick query -f Cargo.toml '.package.name'`
+# Convert crate name to snake case for rust naming conventions.
+project_name := snakecase(crate_name)
+
+# The target to build for release.
+build_target := "wasm32-wasi"
+# The target to build for debug (wasm32-wasi can give easy access to println & STDIO for debugging)
+debug_target := "wasm32-wasi"
+
+# Build and sign a WebAssembly component implementation
+build: setup
+ cargo build --release --target="{{build_target}}"
+ cp "./target/{{build_target}}/release/{{project_name}}.wasm" ./build/component.wasm
+ {{wick}} wasm sign ./build/component.wasm component.wick
+
+# Build a debug version of a WebAssembly component
+debug: setup
+ cargo +nightly build --target="{{debug_target}}"
+ cp "./target/{{debug_target}}/debug/{{project_name}}.wasm" ./build/component.wasm
+ {{wick}} wasm sign ./build/component.wasm component.wick
+
+# Echo variables used by this justfile
+debug-justfile:
+ @echo "Wick command: {{wick}}"
+ @echo "---"
+ @echo "Crate name: {{crate_name}}"
+ @echo "Crate name (rustified): {{project_name}}"
+ @echo "---"
+ @echo "Build target: {{build_target}}"
+ @echo "Debug target: {{debug_target}}"
+
+# Setup any environment needed for the build
+setup:
+ mkdir -p build
+
+# Run tests
+test: build
+ {{wick}} test component.wick
+
+# Clean the project directory
+clean:
+ cargo clean
+
diff --git a/examples/components/wasi-fs/src/lib copy.rs b/examples/components/wasi-fs/src/lib copy.rs
new file mode 100644
index 000000000..268bdf59d
--- /dev/null
+++ b/examples/components/wasi-fs/src/lib copy.rs
@@ -0,0 +1,49 @@
+mod wick {
+ wick_component::wick_import!();
+}
+use std::io::Write;
+
+use anyhow::bail;
+use wick::*;
+use wick_component::wick_packet::Packet;
+
+// simple_unary_operation!(read_string);
+
+#[wick_component::operation(unary::simple)]
+fn read_string(filename: &String) -> Result {
+ std::fs::read_to_string(filename)
+}
+
+// simple_unary_operation!(read_bytes);
+
+#[wick_component::operation(unary::simple)]
+fn read_bytes(filename: &String) -> Result {
+ std::fs::read(filename).map(Into::into)
+}
+
+// paired_right_stream!(write_string);
+
+// fn write_string(
+// filename: String,
+// contents: WickStream,
+// ) -> std::pin::Pin> + 'static>> {
+// Box::pin(async move { real_write_string(filename, contents).await })
+// }
+
+#[wick_component::operation(binary::paired_right_stream)]
+async fn real_write_string(filename: String, mut contents: WickStream) -> Result {
+ let mut file = std::fs::File::create(filename)?;
+ let mut size = 0;
+ while let Some(contents) = contents.next().await {
+ match contents {
+ Ok(string) => {
+ size += file.write(string.as_bytes())?;
+ }
+ Err(e) => {
+ bail!(e);
+ }
+ }
+ }
+
+ Ok(size as _)
+}
diff --git a/examples/components/wasi-fs/src/lib.rs b/examples/components/wasi-fs/src/lib.rs
new file mode 100644
index 000000000..b756f3a8f
--- /dev/null
+++ b/examples/components/wasi-fs/src/lib.rs
@@ -0,0 +1,38 @@
+mod wick {
+ wick_component::wick_import!();
+}
+use std::io::Write;
+
+use wick::*;
+
+#[wick_component::operation(unary_simple)]
+fn read_string(filename: String, _ctx: Context) -> Result {
+ std::fs::read_to_string(filename)
+}
+
+#[wick_component::operation(unary_simple)]
+fn read_bytes(filename: String, _ctx: Context) -> Result {
+ std::fs::read(filename).map(Into::into)
+}
+
+#[wick_component::operation(binary_paired_right_stream)]
+async fn write_string(
+ filename: String,
+ mut contents: WickStream,
+ _ctx: Context,
+) -> Result {
+ let mut file = std::fs::File::create(filename)?;
+ let mut size = 0;
+ while let Some(contents) = contents.next().await {
+ match contents {
+ Ok(string) => {
+ size += file.write(string.as_bytes())?;
+ }
+ Err(e) => {
+ anyhow::bail!(e);
+ }
+ }
+ }
+
+ Ok(size as _)
+}
diff --git a/examples/components/wasi-fs/tests/testdata/custom.txt b/examples/components/wasi-fs/tests/testdata/custom.txt
new file mode 100644
index 000000000..c61c79d30
--- /dev/null
+++ b/examples/components/wasi-fs/tests/testdata/custom.txt
@@ -0,0 +1 @@
+2023-07-26 22
\ No newline at end of file
diff --git a/examples/components/wasi-fs/tests/testdata/file.txt b/examples/components/wasi-fs/tests/testdata/file.txt
new file mode 100644
index 000000000..9d9c54f90
--- /dev/null
+++ b/examples/components/wasi-fs/tests/testdata/file.txt
@@ -0,0 +1 @@
+# Hello World!
\ No newline at end of file
diff --git a/examples/http/middleware/request/Cargo.lock b/examples/http/middleware/request/Cargo.lock
index 0624cf4df..5d76f7472 100644
--- a/examples/http/middleware/request/Cargo.lock
+++ b/examples/http/middleware/request/Cargo.lock
@@ -47,6 +47,17 @@ dependencies = [
"thiserror",
]
+[[package]]
+name = "async-recursion"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0e97ce7de6cf12de5d7226c73f5ba9811622f4db3a5b91b55c53e987e5f91cba"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.16",
+]
+
[[package]]
name = "async-trait"
version = "0.1.68"
@@ -314,7 +325,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc"
dependencies = [
"cfg-if",
- "hashbrown",
+ "hashbrown 0.12.3",
"lock_api",
"once_cell",
"parking_lot_core",
@@ -435,6 +446,12 @@ dependencies = [
"cfg-if",
]
+[[package]]
+name = "equivalent"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
+
[[package]]
name = "filetime"
version = "0.2.21"
@@ -476,13 +493,16 @@ dependencies = [
name = "flow-expression-parser"
version = "0.5.0"
dependencies = [
- "lazy_static",
"liquid-json",
"nom",
+ "once_cell",
+ "parking_lot",
"regex",
+ "seeded-random",
"serde",
"serde_json",
"thiserror",
+ "uuid",
]
[[package]]
@@ -648,7 +668,7 @@ dependencies = [
"futures-sink",
"futures-util",
"http",
- "indexmap",
+ "indexmap 1.9.3",
"slab",
"tokio",
"tokio-util",
@@ -670,6 +690,12 @@ version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+[[package]]
+name = "hashbrown"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
+
[[package]]
name = "heapless"
version = "0.7.16"
@@ -848,10 +874,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
dependencies = [
"autocfg",
- "hashbrown",
+ "hashbrown 0.12.3",
"serde",
]
+[[package]]
+name = "indexmap"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d"
+dependencies = [
+ "equivalent",
+ "hashbrown 0.14.0",
+]
+
[[package]]
name = "iovec"
version = "0.1.4"
@@ -1278,6 +1314,16 @@ dependencies = [
"syn 2.0.16",
]
+[[package]]
+name = "proc-macro-crate"
+version = "1.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919"
+dependencies = [
+ "once_cell",
+ "toml_edit",
+]
+
[[package]]
name = "proc-macro-error"
version = "1.0.4"
@@ -1586,6 +1632,7 @@ dependencies = [
"parking_lot",
"rand",
"rand_chacha",
+ "uuid",
]
[[package]]
@@ -1677,7 +1724,7 @@ dependencies = [
"base64 0.21.2",
"chrono",
"hex",
- "indexmap",
+ "indexmap 1.9.3",
"serde",
"serde_json",
"serde_with_macros",
@@ -1702,7 +1749,7 @@ version = "0.9.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9d684e3ec7de3bf5466b32bd75303ac16f0736426e5a4e0d6e489559ce1249c"
dependencies = [
- "indexmap",
+ "indexmap 1.9.3",
"itoa",
"ryu",
"serde",
@@ -2005,6 +2052,23 @@ dependencies = [
"tracing",
]
+[[package]]
+name = "toml_datetime"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"
+
+[[package]]
+name = "toml_edit"
+version = "0.19.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a"
+dependencies = [
+ "indexmap 2.0.0",
+ "toml_datetime",
+ "winnow",
+]
+
[[package]]
name = "tower-service"
version = "0.3.2"
@@ -2121,6 +2185,15 @@ dependencies = [
"percent-encoding",
]
+[[package]]
+name = "uuid"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d"
+dependencies = [
+ "getrandom",
+]
+
[[package]]
name = "version_check"
version = "0.9.4"
@@ -2224,9 +2297,9 @@ dependencies = [
[[package]]
name = "wasmrs"
-version = "0.13.0"
+version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94eaf073a819835e7bf712f6afbc8f3f04790cf6e57fd48b86e3ceac1f1c5582"
+checksum = "d9e639ca1fefefe446ed77443865dd2298ed5a22e22992944e2b03d931cf11ab"
dependencies = [
"bytes 1.4.0",
"crossbeam-channel",
@@ -2246,9 +2319,9 @@ dependencies = [
[[package]]
name = "wasmrs-codec"
-version = "0.13.0"
+version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "20f90276d9d3c49951c3073b2845ac3dc2cee446722ea4904bb768419c36b6be"
+checksum = "aa033a409e0a05d24013fdf15becafaba5e13c3eee1706dd687e63ff6e5aa2e2"
dependencies = [
"heapless",
"rmp-serde",
@@ -2258,9 +2331,9 @@ dependencies = [
[[package]]
name = "wasmrs-frames"
-version = "0.13.0"
+version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff7f452a1908fb0f2d08db7752b9dc69bdeea647fa1841f469ef3ad98815956c"
+checksum = "5379743c49fe234b5191beb98c9891ce6f90df2358f442d124bc3b10857ff74c"
dependencies = [
"bytes 1.4.0",
"serde",
@@ -2268,9 +2341,9 @@ dependencies = [
[[package]]
name = "wasmrs-guest"
-version = "0.13.0"
+version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d50bc90ea73c739b11440c0e15674a4b8c197a0f1c120bd0ab5930f5d699eccd"
+checksum = "c80fe87a96b758f19ee3c96bffcbd14549affc32a7811dfccb8f0e2acd119616"
dependencies = [
"bytes 1.4.0",
"cfg-if",
@@ -2288,9 +2361,9 @@ dependencies = [
[[package]]
name = "wasmrs-runtime"
-version = "0.13.0"
+version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "86a76568a0617b94230c08566e0e4dc1bdd4e953bb8f73ef3617f29cc025bb3a"
+checksum = "be63ea5457fca88c949665f1dcf0752842777baa762af5d6d053aa8a8576cb3d"
dependencies = [
"bytes 1.4.0",
"crossbeam-channel",
@@ -2307,9 +2380,9 @@ dependencies = [
[[package]]
name = "wasmrs-rx"
-version = "0.13.0"
+version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85a7878f17e23c775cb6cbf40c66651076b3bc483ffe5396a4b17874d2114a35"
+checksum = "5b2ae214a4ff7272c6d4f718626f9a4a85d239be37c8059e7952ec32b99189d5"
dependencies = [
"async-trait",
"bytes 1.4.0",
@@ -2362,6 +2435,7 @@ dependencies = [
"getset",
"normpath",
"parking_lot",
+ "serde",
"thiserror",
"tokio",
"tokio-stream",
@@ -2373,16 +2447,19 @@ dependencies = [
name = "wick-component"
version = "0.15.0"
dependencies = [
+ "async-recursion",
"flow-component",
"paste",
"serde",
"serde_json",
"tokio-stream",
+ "tracing",
"wasmrs",
"wasmrs-codec",
"wasmrs-guest",
"wasmrs-runtime",
"wasmrs-rx",
+ "wick-operation",
"wick-packet",
]
@@ -2471,6 +2548,16 @@ dependencies = [
"wick-xdg",
]
+[[package]]
+name = "wick-operation"
+version = "0.1.0"
+dependencies = [
+ "proc-macro-crate",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.16",
+]
+
[[package]]
name = "wick-packet"
version = "0.15.0"
@@ -2493,6 +2580,7 @@ dependencies = [
"wasmrs-codec",
"wasmrs-frames",
"wasmrs-guest",
+ "wasmrs-runtime",
"wasmrs-rx",
"wick-interface-types",
]
@@ -2669,6 +2757,15 @@ version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
+[[package]]
+name = "winnow"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "25b5872fa2e10bd067ae946f927e726d7d603eaeb6e02fa6a350e0722d2b8c11"
+dependencies = [
+ "memchr",
+]
+
[[package]]
name = "winreg"
version = "0.10.1"
diff --git a/examples/http/middleware/request/Cargo.toml b/examples/http/middleware/request/Cargo.toml
index 3f23d6cfe..035f7a6cd 100644
--- a/examples/http/middleware/request/Cargo.toml
+++ b/examples/http/middleware/request/Cargo.toml
@@ -23,3 +23,6 @@ anyhow = { version = "1" }
[build-dependencies]
wick-component-codegen = { path = "../../../../crates/wick/wick-component-codegen" }
+
+# Including this section keeps this crate out of a workspace without needing to alter the workspace.
+[workspace]
diff --git a/examples/http/middleware/request/src/lib.rs b/examples/http/middleware/request/src/lib.rs
index aa1386e39..02448d1a6 100644
--- a/examples/http/middleware/request/src/lib.rs
+++ b/examples/http/middleware/request/src/lib.rs
@@ -8,7 +8,7 @@ use wick::*;
use self::wick::types::http::{self, RequestMiddlewareResponse};
#[async_trait::async_trait(?Send)]
-impl RedirectOperation for Component {
+impl redirect::Operation for Component {
type Error = anyhow::Error;
type Outputs = redirect::Outputs;
type Config = redirect::Config;
@@ -49,7 +49,7 @@ thread_local! {
}
#[async_trait::async_trait(?Send)]
-impl CountOperation for Component {
+impl count::Operation for Component {
type Error = anyhow::Error;
type Outputs = count::Outputs;
type Config = count::Config;
diff --git a/examples/http/wasm-http-call/wasm-component/Cargo.lock b/examples/http/wasm-http-call/wasm-component/Cargo.lock
index bb95fd3c7..3a7c94bd1 100644
--- a/examples/http/wasm-http-call/wasm-component/Cargo.lock
+++ b/examples/http/wasm-http-call/wasm-component/Cargo.lock
@@ -53,6 +53,17 @@ dependencies = [
"thiserror",
]
+[[package]]
+name = "async-recursion"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0e97ce7de6cf12de5d7226c73f5ba9811622f4db3a5b91b55c53e987e5f91cba"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.18",
+]
+
[[package]]
name = "async-trait"
version = "0.1.68"
@@ -320,7 +331,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc"
dependencies = [
"cfg-if",
- "hashbrown",
+ "hashbrown 0.12.3",
"lock_api",
"once_cell",
"parking_lot_core",
@@ -441,6 +452,12 @@ dependencies = [
"cfg-if",
]
+[[package]]
+name = "equivalent"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
+
[[package]]
name = "filetime"
version = "0.2.21"
@@ -482,13 +499,16 @@ dependencies = [
name = "flow-expression-parser"
version = "0.5.0"
dependencies = [
- "lazy_static",
"liquid-json",
"nom",
+ "once_cell",
+ "parking_lot",
"regex",
+ "seeded-random",
"serde",
"serde_json",
"thiserror",
+ "uuid",
]
[[package]]
@@ -654,7 +674,7 @@ dependencies = [
"futures-sink",
"futures-util",
"http",
- "indexmap",
+ "indexmap 1.9.3",
"slab",
"tokio",
"tokio-util",
@@ -676,6 +696,12 @@ version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+[[package]]
+name = "hashbrown"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
+
[[package]]
name = "heapless"
version = "0.7.16"
@@ -854,10 +880,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
dependencies = [
"autocfg",
- "hashbrown",
+ "hashbrown 0.12.3",
"serde",
]
+[[package]]
+name = "indexmap"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d"
+dependencies = [
+ "equivalent",
+ "hashbrown 0.14.0",
+]
+
[[package]]
name = "iovec"
version = "0.1.4"
@@ -1270,6 +1306,16 @@ dependencies = [
"syn 2.0.18",
]
+[[package]]
+name = "proc-macro-crate"
+version = "1.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919"
+dependencies = [
+ "once_cell",
+ "toml_edit",
+]
+
[[package]]
name = "proc-macro-error"
version = "1.0.4"
@@ -1546,6 +1592,7 @@ dependencies = [
"parking_lot",
"rand",
"rand_chacha",
+ "uuid",
]
[[package]]
@@ -1637,7 +1684,7 @@ dependencies = [
"base64 0.21.2",
"chrono",
"hex",
- "indexmap",
+ "indexmap 1.9.3",
"serde",
"serde_json",
"serde_with_macros",
@@ -1662,7 +1709,7 @@ version = "0.9.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9d684e3ec7de3bf5466b32bd75303ac16f0736426e5a4e0d6e489559ce1249c"
dependencies = [
- "indexmap",
+ "indexmap 1.9.3",
"itoa",
"ryu",
"serde",
@@ -1965,6 +2012,23 @@ dependencies = [
"tracing",
]
+[[package]]
+name = "toml_datetime"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"
+
+[[package]]
+name = "toml_edit"
+version = "0.19.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a"
+dependencies = [
+ "indexmap 2.0.0",
+ "toml_datetime",
+ "winnow",
+]
+
[[package]]
name = "tower-service"
version = "0.3.2"
@@ -2081,6 +2145,15 @@ dependencies = [
"percent-encoding",
]
+[[package]]
+name = "uuid"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d"
+dependencies = [
+ "getrandom",
+]
+
[[package]]
name = "version_check"
version = "0.9.4"
@@ -2195,9 +2268,9 @@ dependencies = [
[[package]]
name = "wasmrs"
-version = "0.13.0"
+version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94eaf073a819835e7bf712f6afbc8f3f04790cf6e57fd48b86e3ceac1f1c5582"
+checksum = "d9e639ca1fefefe446ed77443865dd2298ed5a22e22992944e2b03d931cf11ab"
dependencies = [
"bytes 1.4.0",
"crossbeam-channel",
@@ -2217,9 +2290,9 @@ dependencies = [
[[package]]
name = "wasmrs-codec"
-version = "0.13.0"
+version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "20f90276d9d3c49951c3073b2845ac3dc2cee446722ea4904bb768419c36b6be"
+checksum = "aa033a409e0a05d24013fdf15becafaba5e13c3eee1706dd687e63ff6e5aa2e2"
dependencies = [
"heapless",
"rmp-serde",
@@ -2229,9 +2302,9 @@ dependencies = [
[[package]]
name = "wasmrs-frames"
-version = "0.13.0"
+version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff7f452a1908fb0f2d08db7752b9dc69bdeea647fa1841f469ef3ad98815956c"
+checksum = "5379743c49fe234b5191beb98c9891ce6f90df2358f442d124bc3b10857ff74c"
dependencies = [
"bytes 1.4.0",
"serde",
@@ -2239,9 +2312,9 @@ dependencies = [
[[package]]
name = "wasmrs-guest"
-version = "0.13.0"
+version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d50bc90ea73c739b11440c0e15674a4b8c197a0f1c120bd0ab5930f5d699eccd"
+checksum = "c80fe87a96b758f19ee3c96bffcbd14549affc32a7811dfccb8f0e2acd119616"
dependencies = [
"bytes 1.4.0",
"cfg-if",
@@ -2259,9 +2332,9 @@ dependencies = [
[[package]]
name = "wasmrs-runtime"
-version = "0.13.0"
+version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "86a76568a0617b94230c08566e0e4dc1bdd4e953bb8f73ef3617f29cc025bb3a"
+checksum = "be63ea5457fca88c949665f1dcf0752842777baa762af5d6d053aa8a8576cb3d"
dependencies = [
"bytes 1.4.0",
"crossbeam-channel",
@@ -2278,9 +2351,9 @@ dependencies = [
[[package]]
name = "wasmrs-rx"
-version = "0.13.0"
+version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85a7878f17e23c775cb6cbf40c66651076b3bc483ffe5396a4b17874d2114a35"
+checksum = "5b2ae214a4ff7272c6d4f718626f9a4a85d239be37c8059e7952ec32b99189d5"
dependencies = [
"async-trait",
"bytes 1.4.0",
@@ -2333,6 +2406,7 @@ dependencies = [
"getset",
"normpath",
"parking_lot",
+ "serde",
"thiserror",
"tokio",
"tokio-stream",
@@ -2344,16 +2418,19 @@ dependencies = [
name = "wick-component"
version = "0.15.0"
dependencies = [
+ "async-recursion",
"flow-component",
"paste",
"serde",
"serde_json",
"tokio-stream",
+ "tracing",
"wasmrs",
"wasmrs-codec",
"wasmrs-guest",
"wasmrs-runtime",
"wasmrs-rx",
+ "wick-operation",
"wick-packet",
]
@@ -2442,6 +2519,16 @@ dependencies = [
"wick-xdg",
]
+[[package]]
+name = "wick-operation"
+version = "0.1.0"
+dependencies = [
+ "proc-macro-crate",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.18",
+]
+
[[package]]
name = "wick-packet"
version = "0.15.0"
@@ -2464,6 +2551,7 @@ dependencies = [
"wasmrs-codec",
"wasmrs-frames",
"wasmrs-guest",
+ "wasmrs-runtime",
"wasmrs-rx",
"wick-interface-types",
]
@@ -2574,6 +2662,15 @@ version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
+[[package]]
+name = "winnow"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "25b5872fa2e10bd067ae946f927e726d7d603eaeb6e02fa6a350e0722d2b8c11"
+dependencies = [
+ "memchr",
+]
+
[[package]]
name = "winreg"
version = "0.10.1"
diff --git a/examples/http/wasm-http-call/wasm-component/Cargo.toml b/examples/http/wasm-http-call/wasm-component/Cargo.toml
index 9c24baddc..0871fb41c 100644
--- a/examples/http/wasm-http-call/wasm-component/Cargo.toml
+++ b/examples/http/wasm-http-call/wasm-component/Cargo.toml
@@ -23,3 +23,6 @@ anyhow = { version = "1" }
[build-dependencies]
wick-component-codegen = { path = "../../../../crates/wick/wick-component-codegen" }
+
+# Including this section keeps this crate out of a workspace without needing to alter the workspace.
+[workspace]
diff --git a/examples/http/wasm-http-call/wasm-component/src/lib.rs b/examples/http/wasm-http-call/wasm-component/src/lib.rs
index 1c1b5e6b4..ae78122ff 100644
--- a/examples/http/wasm-http-call/wasm-component/src/lib.rs
+++ b/examples/http/wasm-http-call/wasm-component/src/lib.rs
@@ -4,7 +4,7 @@ mod wick {
use wick::*;
#[async_trait::async_trait(?Send)]
-impl RequestOperation for Component {
+impl request::Operation for Component {
type Error = anyhow::Error;
type Outputs = request::Outputs;
type Config = request::Config;
diff --git a/templates/rust/.cargo/config b/templates/rust/.cargo/config
index e52f56884..e69de29bb 100644
--- a/templates/rust/.cargo/config
+++ b/templates/rust/.cargo/config
@@ -1,2 +0,0 @@
-[build]
-target = "wasm32-unknown-unknown" # build for the target triple in case you run `cargo build` instead of `just build` and for rust-analyzer
\ No newline at end of file
diff --git a/templates/rust/Cargo.toml b/templates/rust/Cargo.toml
index ee010ed24..2c82ba725 100644
--- a/templates/rust/Cargo.toml
+++ b/templates/rust/Cargo.toml
@@ -23,3 +23,6 @@ anyhow = { version = "1" }
[build-dependencies]
wick-component-codegen = { git = "https://github.com/candlecorp/wick.git" }
+
+# Including this section keeps this crate out of a workspace without needing to alter the workspace.
+[workspace]
diff --git a/templates/rust/component.wick b/templates/rust/component.wick
index 2ed544c4c..ab9ea6c9c 100644
--- a/templates/rust/component.wick
+++ b/templates/rust/component.wick
@@ -6,7 +6,7 @@ metadata:
version: '0.0.1'
component:
kind: wick/component/wasmrs@v1
- ref: build/{{project-name | snake_case}}.signed.wasm
+ ref: build/component.signed.wasm
operations:
- name: greet
inputs:
diff --git a/templates/rust/justfile b/templates/rust/justfile
index 681506bd4..2fc90b467 100644
--- a/templates/rust/justfile
+++ b/templates/rust/justfile
@@ -1,15 +1,50 @@
-project_name := "{{project-name | snake_case}}"
+{% raw %}
+
+# The wick command to use for this project (usually just "wick" but can be a local path during development)
+wick := "wick"
+
+# Get the crate name from the Cargo.toml file (this uses wick instead of {{wick}} due to justfile limitations)
+crate_name := `wick query -f Cargo.toml '.package.name'`
+# Convert crate name to snake case for rust naming conventions.
+project_name := snakecase(crate_name)
+
+# The target to build for release.
+build_target := "wasm32-unknown-unknown"
+# The target to build for debug (wasm32-wasi can give easy access to println & STDIO for debugging)
+debug_target := "wasm32-wasi"
+
+# Build and sign a WebAssembly component implementation
build: setup
- cargo build --release --target=wasm32-unknown-unknown
- cp ./target/wasm32-unknown-unknown/release/{% raw %}{{project_name}}{% endraw %}.wasm ./build/
- wick wasm sign ./build/{% raw %}{{project_name}}{% endraw %}.wasm component.wick
+ cargo build --release --target="{{build_target}}"
+ cp "./target/{{build_target}}/release/{{project_name}}.wasm" ./build/component.wasm
+ {{wick}} wasm sign ./build/component.wasm component.wick
+
+# Build a debug version of a WebAssembly component
debug: setup
- cargo +nightly build --target=wasm32-wasi
- cp ./target/wasm32-wasi/debug/{% raw %}{{project_name}}{% endraw %}.wasm ./build/
- wick wasm sign ./build/{% raw %}{{project_name}}{% endraw %}.wasm component.wick
+ cargo +nightly build --target="{{debug_target}}"
+ cp "./target/{{debug_target}}/debug/{{project_name}}.wasm" ./build/component.wasm
+ {{wick}} wasm sign ./build/component.wasm component.wick
+
+# Echo variables used by this justfile
+debug-justfile:
+ @echo "Wick command: {{wick}}"
+ @echo "---"
+ @echo "Crate name: {{crate_name}}"
+ @echo "Crate name (rustified): {{project_name}}"
+ @echo "---"
+ @echo "Build target: {{build_target}}"
+ @echo "Debug target: {{debug_target}}"
+
+# Setup any environment needed for the build
setup:
mkdir -p build
+
+# Run tests
test: build
- wick test component.wick
+ {{wick}} test component.wick
+
+# Clean the project directory
clean:
cargo clean
+
+{% endraw %}
\ No newline at end of file
diff --git a/templates/rust/src/lib.rs b/templates/rust/src/lib.rs
index 9c2de516e..bc0c16d97 100644
--- a/templates/rust/src/lib.rs
+++ b/templates/rust/src/lib.rs
@@ -4,7 +4,7 @@ mod wick {
use wick::*;
#[async_trait::async_trait(?Send)]
-impl AddOperation for Component {
+impl add::Operation for Component {
type Error = anyhow::Error;
type Outputs = add::Outputs;
type Config = add::Config;
@@ -24,7 +24,7 @@ impl AddOperation for Component {
}
#[async_trait::async_trait(?Send)]
-impl GreetOperation for Component {
+impl greet::Operation for Component {
type Error = anyhow::Error;
type Outputs = greet::Outputs;
type Config = greet::Config;
diff --git a/tests/cli-tests/Cargo.toml b/tests/cli-tests/Cargo.toml
index 2bdddcbec..556bb8910 100644
--- a/tests/cli-tests/Cargo.toml
+++ b/tests/cli-tests/Cargo.toml
@@ -14,4 +14,4 @@ publish = false
trycmd = { workspace = true }
rstest = { workspace = true }
anyhow = { workspace = true }
-escargot = { workspace = true, features = ["print"] }
+escargot = { workspace = true }
diff --git a/tests/codegen-tests/src/import_types/mod.rs b/tests/codegen-tests/src/import_types/mod.rs
index 59aee0926..30662b1b2 100644
--- a/tests/codegen-tests/src/import_types/mod.rs
+++ b/tests/codegen-tests/src/import_types/mod.rs
@@ -14,6 +14,7 @@ extern "C" fn __wasmrs_init(guest_buffer_size: u32, host_buffer_size: u32, max_h
}
#[cfg(target_family = "wasm")]
mod imported_components_wasm {
+ #[allow(unused)]
use super::*;
#[allow(unused)]
pub struct Dep1Component {
@@ -61,6 +62,7 @@ pub use imported_components_wasm::*;
#[allow(unused)]
#[cfg(target_family = "wasm")]
mod provided_wasm {
+ #[allow(unused)]
use super::*;
pub(crate) struct Provided {
pub dep1: Dep1Component,
@@ -2081,6 +2083,7 @@ pub mod types {
}
///Types associated with the `echo` operation
pub mod echo {
+ #[allow(unused)]
use super::*;
#[derive(Debug, Clone, Default, ::serde::Serialize, ::serde::Deserialize, PartialEq)]
pub struct Config {}
@@ -2089,6 +2092,11 @@ pub mod echo {
pub(crate) output: wick_packet::Output,
pub(crate) time: wick_packet::Output,
}
+ impl wick_component::Broadcast for Outputs {
+ fn outputs_mut(&mut self) -> wick_packet::OutputIterator<'_> {
+ wick_packet::OutputIterator::new(vec![&mut self.output, &mut self.time])
+ }
+ }
impl Outputs {
pub fn new(channel: wasmrs_rx::FluxChannel) -> Self {
Self {
@@ -2096,53 +2104,39 @@ pub mod echo {
time: wick_packet::Output::new("time", channel),
}
}
+ }
+ #[async_trait::async_trait(?Send)]
+ #[cfg(target_family = "wasm")]
+ pub trait Operation {
+ type Error: std::fmt::Display;
+ type Outputs;
+ type Config: std::fmt::Debug;
#[allow(unused)]
- pub fn broadcast_open(&mut self) {
- self.output.open_bracket();
- self.time.open_bracket();
- }
- #[allow(unused)]
- pub fn broadcast_close(&mut self) {
- self.output.close_bracket();
- self.time.close_bracket();
- }
+ async fn echo(
+ input: WickStream,
+ time: WickStream,
+ outputs: Self::Outputs,
+ ctx: wick_component::flow_component::Context,
+ ) -> std::result::Result<(), Self::Error>;
+ }
+ #[async_trait::async_trait]
+ #[cfg(not(target_family = "wasm"))]
+ pub trait Operation {
+ type Error: std::fmt::Display + Send;
+ type Outputs: Send;
+ type Config: std::fmt::Debug + Send;
#[allow(unused)]
- pub fn broadcast_err(&mut self, err: impl AsRef) {
- self.output.error(&err);
- self.time.error(&err);
- }
+ async fn echo(
+ input: WickStream,
+ time: WickStream,
+ outputs: Self::Outputs,
+ ctx: wick_component::flow_component::Context,
+ ) -> std::result::Result<(), Self::Error>;
}
}
-#[async_trait::async_trait(?Send)]
-#[cfg(target_family = "wasm")]
-pub trait EchoOperation {
- type Error: std::fmt::Display;
- type Outputs;
- type Config: std::fmt::Debug;
- #[allow(unused)]
- async fn echo(
- input: WickStream,
- time: WickStream,
- outputs: Self::Outputs,
- ctx: wick_component::flow_component::Context,
- ) -> std::result::Result<(), Self::Error>;
-}
-#[async_trait::async_trait]
-#[cfg(not(target_family = "wasm"))]
-pub trait EchoOperation {
- type Error: std::fmt::Display + Send;
- type Outputs: Send;
- type Config: std::fmt::Debug + Send;
- #[allow(unused)]
- async fn echo(
- input: WickStream,
- time: WickStream,
- outputs: Self::Outputs,
- ctx: wick_component::flow_component::Context,
- ) -> std::result::Result<(), Self::Error>;
-}
///Types associated with the `testop` operation
pub mod testop {
+ #[allow(unused)]
use super::*;
#[derive(Debug, Clone, ::serde::Serialize, ::serde::Deserialize, PartialEq)]
pub struct Config {
@@ -2163,52 +2157,50 @@ pub mod testop {
#[allow(unused)]
pub(crate) output: wick_packet::Output,
}
+ impl wick_component::Broadcast for Outputs {
+ fn outputs_mut(&mut self) -> wick_packet::OutputIterator<'_> {
+ wick_packet::OutputIterator::new(vec![&mut self.output])
+ }
+ }
+ impl wick_component::SingleOutput for Outputs {
+ fn single_output(&mut self) -> &mut dyn wick_packet::Port {
+ &mut self.output
+ }
+ }
impl Outputs {
pub fn new(channel: wasmrs_rx::FluxChannel) -> Self {
Self {
output: wick_packet::Output::new("output", channel),
}
}
+ }
+ #[async_trait::async_trait(?Send)]
+ #[cfg(target_family = "wasm")]
+ pub trait Operation {
+ type Error: std::fmt::Display;
+ type Outputs;
+ type Config: std::fmt::Debug;
#[allow(unused)]
- pub fn broadcast_open(&mut self) {
- self.output.open_bracket();
- }
- #[allow(unused)]
- pub fn broadcast_close(&mut self) {
- self.output.close_bracket();
- }
+ async fn testop(
+ message: WickStream,
+ outputs: Self::Outputs,
+ ctx: wick_component::flow_component::Context,
+ ) -> std::result::Result<(), Self::Error>;
+ }
+ #[async_trait::async_trait]
+ #[cfg(not(target_family = "wasm"))]
+ pub trait Operation {
+ type Error: std::fmt::Display + Send;
+ type Outputs: Send;
+ type Config: std::fmt::Debug + Send;
#[allow(unused)]
- pub fn broadcast_err(&mut self, err: impl AsRef) {
- self.output.error(&err);
- }
+ async fn testop(
+ message: WickStream,
+ outputs: Self::Outputs,
+ ctx: wick_component::flow_component::Context,
+ ) -> std::result::Result<(), Self::Error>;
}
}
-#[async_trait::async_trait(?Send)]
-#[cfg(target_family = "wasm")]
-pub trait TestopOperation {
- type Error: std::fmt::Display;
- type Outputs;
- type Config: std::fmt::Debug;
- #[allow(unused)]
- async fn testop(
- message: WickStream,
- outputs: Self::Outputs,
- ctx: wick_component::flow_component::Context,
- ) -> std::result::Result<(), Self::Error>;
-}
-#[async_trait::async_trait]
-#[cfg(not(target_family = "wasm"))]
-pub trait TestopOperation {
- type Error: std::fmt::Display + Send;
- type Outputs: Send;
- type Config: std::fmt::Debug + Send;
- #[allow(unused)]
- async fn testop(
- message: WickStream,
- outputs: Self::Outputs,
- ctx: wick_component::flow_component::Context,
- ) -> std::result::Result<(), Self::Error>;
-}
#[derive(Default, Clone)]
///The struct that the component implementation hinges around
pub struct Component;
@@ -2240,6 +2232,7 @@ impl Component {
return;
}
};
+ use echo::Operation;
if let Err(e) = Component::echo(Box::pin(input), Box::pin(time), outputs, config).await {
let _ = channel.send_result(wick_packet::Packet::component_error(e.to_string()).into());
}
@@ -2272,6 +2265,7 @@ impl Component {
return;
}
};
+ use testop::Operation;
if let Err(e) = Component::testop(Box::pin(message), outputs, config).await {
let _ = channel.send_result(wick_packet::Packet::component_error(e.to_string()).into());
}
diff --git a/tests/codegen-tests/src/lib.rs b/tests/codegen-tests/src/lib.rs
index 75f623000..4c6ece53d 100644
--- a/tests/codegen-tests/src/lib.rs
+++ b/tests/codegen-tests/src/lib.rs
@@ -4,7 +4,7 @@ mod test1 {
use crate::import_types::*;
# [cfg_attr (target_family = "wasm" , async_trait :: async_trait (? Send))]
#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
- impl TestopOperation for Component {
+ impl testop::Operation for Component {
type Error = anyhow::Error;
type Outputs = testop::Outputs;
type Config = testop::Config;
@@ -21,7 +21,7 @@ mod test1 {
# [cfg_attr (target_family = "wasm" , async_trait :: async_trait (? Send))]
#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
- impl EchoOperation for Component {
+ impl echo::Operation for Component {
type Error = anyhow::Error;
type Outputs = echo::Outputs;
type Config = echo::Config;
@@ -48,6 +48,7 @@ mod test1 {
use wick_packet::{ContextTransport, FluxChannel, InherentData};
use super::*;
+ use crate::import_types::testop::Operation;
use crate::import_types::types::http::HttpResponse;
#[tokio::test]