diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..ea8c4bf7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 00000000..02133d19 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,4557 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "bytes", + "crypto-common", + "generic-array", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[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.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" +dependencies = [ + "backtrace", +] + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "askama" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b79091df18a97caea757e28cd2d5fda49c6cd4bd01ddffd7ff01ace0c0ad2c28" +dependencies = [ + "askama_derive", + "askama_escape", +] + +[[package]] +name = "askama_derive" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19fe8d6cb13c4714962c072ea496f3392015f0989b1a2847bb4b2d9effd71d83" +dependencies = [ + "askama_parser", + "basic-toml", + "mime", + "mime_guess", + "proc-macro2", + "quote", + "serde", + "syn 2.0.104", +] + +[[package]] +name = "askama_escape" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341" + +[[package]] +name = "askama_parser" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acb1161c6b64d1c3d83108213c2a2533a342ac225aabd0bda218278c2ddb00c0" +dependencies = [ + "nom", +] + +[[package]] +name = "async-compat" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bab94bde396a3f7b4962e396fdad640e241ed797d4d8d77fc8c237d14c58fc0" +dependencies = [ + "futures-core", + "futures-io", + "once_cell", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "async-trait" +version = "0.1.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "async_io_stream" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d7b9decdf35d8908a7e3ef02f64c5e9b1695e230154c0e8de3969142d9b94c" +dependencies = [ + "futures", + "pharos", + "rustc_version", +] + +[[package]] +name = "atomic-polyfill" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" +dependencies = [ + "critical-section", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "attohttpc" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16e2cdb6d5ed835199484bb92bb8b3edd526effe995c61732580439c1a67e2e9" +dependencies = [ + "base64", + "http", + "log", + "url", +] + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "backon" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "592277618714fbcecda9a02ba7a8781f319d26532a88553bbacc77ba5d2b3a8d" +dependencies = [ + "fastrand", + "gloo-timers", + "tokio", +] + +[[package]] +name = "backtrace" +version = "0.3.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets 0.52.6", +] + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base32" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "022dfe9eb35f19ebbcb51e0b40a5ab759f46ad60cadf7297e0bd085afb50e076" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "base64ct" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" + +[[package]] +name = "basic-toml" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba62675e8242a4c4e806d12f11d136e626e6c8361d6b829310732241652a178a" +dependencies = [ + "serde", +] + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" + +[[package]] +name = "blake3" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", +] + +[[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 = "bounded-integer" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "102dbef1187b1893e6dfe05a774e79fd52265f49f214f6879c8ff49f52c8188b" + +[[package]] +name = "btparse" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "387e80962b798815a2b5c4bcfdb6bf626fa922ffe9f74e373103b858738e9f31" + +[[package]] +name = "bumpalo" +version = "3.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" + +[[package]] +name = "camino" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0da45bc31171d8d6960122e222a67740df867c1dd53b4d51caa297084c185cab" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror 1.0.69", +] + +[[package]] +name = "cc" +version = "1.2.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3a42d84bb6b69d3a8b3eaacf0d88f179e1929695e1ad012b6cf64d9caaa5fd2" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "chacha20" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "chrono" +version = "0.4.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "num-traits", + "serde", + "windows-link", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", + "zeroize", +] + +[[package]] +name = "cobs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" +dependencies = [ + "thiserror 2.0.12", +] + +[[package]] +name = "color-backtrace" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2123a5984bd52ca861c66f66a9ab9883b27115c607f801f86c1bc2a84eb69f0f" +dependencies = [ + "backtrace", + "btparse", + "termcolor", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[package]] +name = "cordyceps" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "688d7fbb8092b8de775ef2536f36c8c31f2bc4006ece2e8d8ad2d17d00ce0a2a" +dependencies = [ + "loom", + "tracing", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9710d3b3739c2e349eb44fe848ad0b7c8cb1e42bd87ee49371df2f7acaf3e675" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + +[[package]] +name = "crossbeam-channel" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "typenum", +] + +[[package]] +name = "crypto_box" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16182b4f39a82ec8a6851155cc4c0cda3065bb1db33651726a29e1951de0f009" +dependencies = [ + "aead", + "chacha20", + "crypto_secretbox", + "curve25519-dalek", + "salsa20", + "serdect", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto_secretbox" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d6cf87adf719ddf43a805e92c6870a531aedda35ff640442cbaf8674e141e1" +dependencies = [ + "aead", + "chacha20", + "cipher", + "generic-array", + "poly1305", + "salsa20", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest", + "fiat-crypto", + "rand_core 0.6.4", + "rustc_version", + "serde", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "data-encoding" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" + +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "der_derive", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "der_derive" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8034092389675178f570469e6c3b0465d3d30b4505c294a6550db47f3c17ad18" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "deranged" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "derive_more" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +dependencies = [ + "derive_more-impl 1.0.0", +] + +[[package]] +name = "derive_more" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" +dependencies = [ + "derive_more-impl 2.0.1", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", + "unicode-xid", +] + +[[package]] +name = "derive_more-impl" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", + "unicode-xid", +] + +[[package]] +name = "diatomic-waker" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab03c107fafeb3ee9f5925686dbb7a73bc76e3932abb0d2b365cb64b169cf04c" + +[[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 = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "dlopen2" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09b4f5f101177ff01b8ec4ecc81eead416a8aa42819a2869311b3420fa114ffa" +dependencies = [ + "libc", + "once_cell", + "winapi", +] + +[[package]] +name = "document-features" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" +dependencies = [ + "litrs", +] + +[[package]] +name = "dyn-clone" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "serde", + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" +dependencies = [ + "curve25519-dalek", + "ed25519", + "rand_core 0.6.4", + "serde", + "sha2", + "subtle", + "zeroize", +] + +[[package]] +name = "embedded-io" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + +[[package]] +name = "enum-as-inner" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "enumflags2" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef" +dependencies = [ + "enumflags2_derive", +] + +[[package]] +name = "enumflags2_derive" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "fs-err" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41" +dependencies = [ + "autocfg", +] + +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-buffered" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8e0e1f38ec07ba4abbde21eed377082f17ccb988be9d988a5adbf4bafc118fd" +dependencies = [ + "cordyceps", + "diatomic-waker", + "futures-core", + "pin-project-lite", + "spin 0.10.0", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-lite" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generator" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d18470a76cb7f8ff746cf1f7470914f900252ec36bbc40b569d74b1258446827" +dependencies = [ + "cc", + "cfg-if", + "libc", + "log", + "rustversion", + "windows", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", + "wasm-bindgen", +] + +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "glob" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" + +[[package]] +name = "gloo-timers" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "goblin" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b363a30c165f666402fe6a3024d3bec7ebc898f96a4a23bd1c99f8dbf3f4f47" +dependencies = [ + "log", + "plain", + "scroll", +] + +[[package]] +name = "h2" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17da50a276f1e01e0ba6c029e47b7100754904ee8a278f886546e98575380785" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap", + "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.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "heapless" +version = "0.7.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" +dependencies = [ + "atomic-polyfill", + "hash32", + "rustc_version", + "serde", + "spin 0.9.8", + "stable_deref_trait", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hickory-proto" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8a6fe56c0038198998a6f217ca4e7ef3a5e51f46163bd6dd60b5c71ca6c6502" +dependencies = [ + "async-trait", + "cfg-if", + "data-encoding", + "enum-as-inner", + "futures-channel", + "futures-io", + "futures-util", + "idna", + "ipnet", + "once_cell", + "rand 0.9.2", + "ring", + "thiserror 2.0.12", + "tinyvec", + "tokio", + "tracing", + "url", +] + +[[package]] +name = "hickory-resolver" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc62a9a99b0bfb44d2ab95a7208ac952d31060efc16241c87eaf36406fecf87a" +dependencies = [ + "cfg-if", + "futures-util", + "hickory-proto", + "ipconfig", + "moka", + "once_cell", + "parking_lot", + "rand 0.9.2", + "resolv-conf", + "smallvec", + "thiserror 2.0.12", + "tokio", + "tracing", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "hmac-sha1" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b05da5b9e5d4720bfb691eebb2b9d42da3570745da71eac8a1f5bb7e59aab88" +dependencies = [ + "hmac", + "sha1", +] + +[[package]] +name = "hmac-sha256" +version = "1.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad6880c8d4a9ebf39c6e8b77007ce223f646a4d21ce29d99f70cb16420545425" + +[[package]] +name = "hostname-validator" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f558a64ac9af88b5ba400d99b579451af0d39c6d360980045b91aac966d705e2" + +[[package]] +name = "http" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", + "webpki-roots 1.0.2", +] + +[[package]] +name = "hyper-util" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e" +dependencies = [ + "base64", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2 0.6.0", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "icu_collections" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" + +[[package]] +name = "icu_properties" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "potential_utf", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" + +[[package]] +name = "icu_provider" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +dependencies = [ + "displaydoc", + "icu_locale_core", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "idna" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "igd-next" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "516893339c97f6011282d5825ac94fc1c7aad5cad26bdc2d0cee068c0bf97f97" +dependencies = [ + "async-trait", + "attohttpc", + "bytes", + "futures", + "http", + "http-body-util", + "hyper", + "hyper-util", + "log", + "rand 0.9.2", + "tokio", + "url", + "xmltree", +] + +[[package]] +name = "indexmap" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "generic-array", +] + +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "io-uring" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d93587f37623a1a17d94ef2bc9ada592f5465fe7732084ab7beefabe5c77c0c4" +dependencies = [ + "bitflags", + "cfg-if", + "libc", +] + +[[package]] +name = "ipconfig" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" +dependencies = [ + "socket2 0.5.10", + "widestring", + "windows-sys 0.48.0", + "winreg", +] + +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "iri-string" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "iroh" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6a98c47bb5f720edeb77be502a8acd238a3c0755f0b1ad865a716224d794a59" +dependencies = [ + "aead", + "backon", + "bytes", + "cfg_aliases", + "crypto_box", + "data-encoding", + "der", + "derive_more 2.0.1", + "ed25519-dalek", + "futures-buffered", + "futures-util", + "getrandom 0.3.3", + "hickory-resolver", + "http", + "igd-next", + "instant", + "iroh-base", + "iroh-metrics", + "iroh-quinn", + "iroh-quinn-proto", + "iroh-quinn-udp", + "iroh-relay", + "n0-future", + "n0-snafu", + "n0-watcher", + "nested_enum_utils", + "netdev", + "netwatch", + "pin-project", + "pkarr", + "portmapper", + "rand 0.8.5", + "reqwest", + "ring", + "rustls", + "rustls-pki-types", + "rustls-webpki", + "serde", + "smallvec", + "snafu", + "spki", + "strum", + "stun-rs", + "surge-ping", + "time", + "tokio", + "tokio-stream", + "tokio-util", + "tracing", + "url", + "wasm-bindgen-futures", + "webpki-roots 0.26.11", + "z32", +] + +[[package]] +name = "iroh-base" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78bde4e612191173e8ade55e3aa719044514edfff952292ffbf581be35cbb59c" +dependencies = [ + "curve25519-dalek", + "data-encoding", + "derive_more 2.0.1", + "ed25519-dalek", + "n0-snafu", + "nested_enum_utils", + "rand_core 0.6.4", + "serde", + "snafu", + "url", +] + +[[package]] +name = "iroh-metrics" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8922c169f1b84d39d325c02ef1bbe1419d4de6e35f0403462b3c7e60cc19634" +dependencies = [ + "iroh-metrics-derive", + "itoa", + "postcard", + "serde", + "snafu", + "tracing", +] + +[[package]] +name = "iroh-metrics-derive" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d12f5c45c4ed2436302a4e03cad9a0ad34b2962ad0c5791e1019c0ee30eeb09" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "iroh-quinn" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde160ebee7aabede6ae887460cd303c8b809054224815addf1469d54a6fcf7" +dependencies = [ + "bytes", + "cfg_aliases", + "iroh-quinn-proto", + "iroh-quinn-udp", + "pin-project-lite", + "rustc-hash", + "rustls", + "socket2 0.5.10", + "thiserror 2.0.12", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "iroh-quinn-proto" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "929d5d8fa77d5c304d3ee7cae9aede31f13908bd049f9de8c7c0094ad6f7c535" +dependencies = [ + "bytes", + "getrandom 0.2.16", + "rand 0.8.5", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.12", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "iroh-quinn-udp" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c53afaa1049f7c83ea1331f5ebb9e6ebc5fdd69c468b7a22dd598b02c9bcc973" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2 0.5.10", + "tracing", + "windows-sys 0.59.0", +] + +[[package]] +name = "iroh-relay" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f19e43de2cfc04748054e1cbf7854ae1e192ddc45a4adeae7be7076a8f1fd43" +dependencies = [ + "blake3", + "bytes", + "cfg_aliases", + "data-encoding", + "derive_more 2.0.1", + "getrandom 0.3.3", + "hickory-resolver", + "http", + "http-body-util", + "hyper", + "hyper-util", + "iroh-base", + "iroh-metrics", + "iroh-quinn", + "iroh-quinn-proto", + "lru", + "n0-future", + "n0-snafu", + "nested_enum_utils", + "num_enum", + "pin-project", + "pkarr", + "postcard", + "rand 0.8.5", + "reqwest", + "rustls", + "rustls-pki-types", + "rustls-webpki", + "serde", + "serde_bytes", + "sha1", + "snafu", + "strum", + "tokio", + "tokio-rustls", + "tokio-util", + "tokio-websockets", + "tracing", + "url", + "webpki-roots 0.26.11", + "ws_stream_wasm", + "z32", +] + +[[package]] +name = "iroh-streamplace" +version = "0.1.0" +dependencies = [ + "iroh", + "uniffi", +] + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.174" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" + +[[package]] +name = "litemap" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" + +[[package]] +name = "litrs" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed" + +[[package]] +name = "lock_api" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "loom" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "lru" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "227748d55f2f0ab4735d87fd623798cb6b664512fe979705f829c9f81c934465" +dependencies = [ + "hashbrown", +] + +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "md5" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" + +[[package]] +name = "memchr" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + +[[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.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +dependencies = [ + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", + "windows-sys 0.59.0", +] + +[[package]] +name = "moka" +version = "0.12.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9321642ca94a4282428e6ea4af8cc2ca4eac48ac7a6a4ea8f33f76d0ce70926" +dependencies = [ + "crossbeam-channel", + "crossbeam-epoch", + "crossbeam-utils", + "loom", + "parking_lot", + "portable-atomic", + "rustc_version", + "smallvec", + "tagptr", + "thiserror 1.0.69", + "uuid", +] + +[[package]] +name = "n0-future" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bb0e5d99e681ab3c938842b96fcb41bf8a7bb4bfdb11ccbd653a7e83e06c794" +dependencies = [ + "cfg_aliases", + "derive_more 1.0.0", + "futures-buffered", + "futures-lite", + "futures-util", + "js-sys", + "pin-project", + "send_wrapper", + "tokio", + "tokio-util", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-time", +] + +[[package]] +name = "n0-snafu" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4fed465ff57041f29db78a9adc8864296ef93c6c16029f9e192dc303404ebd0" +dependencies = [ + "anyhow", + "btparse", + "color-backtrace", + "snafu", + "tracing-error", +] + +[[package]] +name = "n0-watcher" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31462392a10d5ada4b945e840cbec2d5f3fee752b96c4b33eb41414d8f45c2a" +dependencies = [ + "derive_more 1.0.0", + "n0-future", + "snafu", +] + +[[package]] +name = "nested_enum_utils" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43fa9161ed44d30e9702fe42bd78693bceac0fed02f647da749f36109023d3a3" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "netdev" +version = "0.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "862209dce034f82a44c95ce2b5183730d616f2a68746b9c1959aa2572e77c0a1" +dependencies = [ + "dlopen2", + "ipnet", + "libc", + "netlink-packet-core", + "netlink-packet-route 0.22.0", + "netlink-sys", + "once_cell", + "system-configuration", + "windows-sys 0.59.0", +] + +[[package]] +name = "netlink-packet-core" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72724faf704479d67b388da142b186f916188505e7e0b26719019c525882eda4" +dependencies = [ + "anyhow", + "byteorder", + "netlink-packet-utils", +] + +[[package]] +name = "netlink-packet-route" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0e7987b28514adf555dc1f9a5c30dfc3e50750bbaffb1aec41ca7b23dcd8e4" +dependencies = [ + "anyhow", + "bitflags", + "byteorder", + "libc", + "log", + "netlink-packet-core", + "netlink-packet-utils", +] + +[[package]] +name = "netlink-packet-route" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56d83370a96813d7c977f8b63054f1162df6e5784f1c598d689236564fb5a6f2" +dependencies = [ + "anyhow", + "bitflags", + "byteorder", + "libc", + "log", + "netlink-packet-core", + "netlink-packet-utils", +] + +[[package]] +name = "netlink-packet-utils" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ede8a08c71ad5a95cdd0e4e52facd37190977039a4704eb82a283f713747d34" +dependencies = [ + "anyhow", + "byteorder", + "paste", + "thiserror 1.0.69", +] + +[[package]] +name = "netlink-proto" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72452e012c2f8d612410d89eea01e2d9b56205274abb35d53f60200b2ec41d60" +dependencies = [ + "bytes", + "futures", + "log", + "netlink-packet-core", + "netlink-sys", + "thiserror 2.0.12", +] + +[[package]] +name = "netlink-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16c903aa70590cb93691bf97a767c8d1d6122d2cc9070433deb3bbf36ce8bd23" +dependencies = [ + "bytes", + "futures", + "libc", + "log", + "tokio", +] + +[[package]] +name = "netwatch" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8901dbb408894af3df3fc51420ba0c6faf3a7d896077b797c39b7001e2f787bd" +dependencies = [ + "atomic-waker", + "bytes", + "cfg_aliases", + "derive_more 2.0.1", + "iroh-quinn-udp", + "js-sys", + "libc", + "n0-future", + "n0-watcher", + "nested_enum_utils", + "netdev", + "netlink-packet-core", + "netlink-packet-route 0.24.0", + "netlink-proto", + "netlink-sys", + "pin-project-lite", + "serde", + "snafu", + "socket2 0.6.0", + "time", + "tokio", + "tokio-util", + "tracing", + "web-sys", + "windows", + "windows-result", + "wmi", +] + +[[package]] +name = "no-std-net" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65" + +[[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 = "ntimestamp" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c50f94c405726d3e0095e89e72f75ce7f6587b94a8bd8dc8054b73f65c0fd68c" +dependencies = [ + "base32", + "document-features", + "getrandom 0.2.16", + "httpdate", + "js-sys", + "once_cell", + "serde", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_enum" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a973b4e44ce6cad84ce69d797acf9a044532e4184c4f267913d1b546a0727b7a" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +dependencies = [ + "critical-section", + "portable-atomic", +] + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + +[[package]] +name = "parking_lot" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.6", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pest" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1db05f56d34358a8b1066f67cbb203ee3e7ed2ba674a6263a1d5ec6db2204323" +dependencies = [ + "memchr", + "thiserror 2.0.12", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb056d9e8ea77922845ec74a1c4e8fb17e7c218cc4fc11a15c5d25e189aa40bc" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e404e638f781eb3202dc82db6760c8ae8a1eeef7fb3fa8264b2ef280504966" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "pest_meta" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd1101f170f5903fde0914f899bb503d9ff5271d7ba76bbb70bea63690cc0d5" +dependencies = [ + "pest", + "sha2", +] + +[[package]] +name = "pharos" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9567389417feee6ce15dd6527a8a1ecac205ef62c2932bcf3d9f6fc5b78b414" +dependencies = [ + "futures", + "rustc_version", +] + +[[package]] +name = "pin-project" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkarr" +version = "3.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eb1f2f4311bae1da11f930c804c724c9914cf55ae51a9ee0440fc98826984f7" +dependencies = [ + "async-compat", + "base32", + "bytes", + "cfg_aliases", + "document-features", + "dyn-clone", + "ed25519-dalek", + "futures-buffered", + "futures-lite", + "getrandom 0.2.16", + "log", + "lru", + "ntimestamp", + "reqwest", + "self_cell", + "serde", + "sha1_smol", + "simple-dns", + "thiserror 2.0.12", + "tokio", + "tracing", + "url", + "wasm-bindgen-futures", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "plain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" + +[[package]] +name = "pnet_base" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe4cf6fb3ab38b68d01ab2aea03ed3d1132b4868fa4e06285f29f16da01c5f4c" +dependencies = [ + "no-std-net", +] + +[[package]] +name = "pnet_macros" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "688b17499eee04a0408aca0aa5cba5fc86401d7216de8a63fdf7a4c227871804" +dependencies = [ + "proc-macro2", + "quote", + "regex", + "syn 2.0.104", +] + +[[package]] +name = "pnet_macros_support" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eea925b72f4bd37f8eab0f221bbe4c78b63498350c983ffa9dd4bcde7e030f56" +dependencies = [ + "pnet_base", +] + +[[package]] +name = "pnet_packet" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9a005825396b7fe7a38a8e288dbc342d5034dac80c15212436424fef8ea90ba" +dependencies = [ + "glob", + "pnet_base", + "pnet_macros", + "pnet_macros_support", +] + +[[package]] +name = "poly1305" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +dependencies = [ + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "portable-atomic" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" + +[[package]] +name = "portmapper" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62f1975debe62a70557e42b9ff9466e4890cf9d3d156d296408a711f1c5f642b" +dependencies = [ + "base64", + "bytes", + "derive_more 2.0.1", + "futures-lite", + "futures-util", + "hyper-util", + "igd-next", + "iroh-metrics", + "libc", + "nested_enum_utils", + "netwatch", + "num_enum", + "rand 0.9.2", + "serde", + "smallvec", + "snafu", + "socket2 0.6.0", + "time", + "tokio", + "tokio-util", + "tower-layer", + "tracing", + "url", +] + +[[package]] +name = "postcard" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24" +dependencies = [ + "cobs", + "embedded-io 0.4.0", + "embedded-io 0.6.1", + "heapless", + "postcard-derive", + "serde", +] + +[[package]] +name = "postcard-derive" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0232bd009a197ceec9cc881ba46f727fcd8060a2d8d6a9dde7a69030a6fe2bb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "potential_utf" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +dependencies = [ + "zerovec", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "precis-core" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c2e7b31f132e0c6f8682cfb7bf4a5340dbe925b7986618d0826a56dfe0c8e56" +dependencies = [ + "precis-tools", + "ucd-parse", + "unicode-normalization", +] + +[[package]] +name = "precis-profiles" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc4f67f78f50388f03494794766ba824a704db16fb5d400fe8d545fa7bc0d3f1" +dependencies = [ + "lazy_static", + "precis-core", + "precis-tools", + "unicode-normalization", +] + +[[package]] +name = "precis-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cc1eb2d5887ac7bfd2c0b745764db89edb84b856e4214e204ef48ef96d10c4a" +dependencies = [ + "lazy_static", + "regex", + "ucd-parse", +] + +[[package]] +name = "proc-macro-crate" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quinn" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "626214629cda6781b6dc1d316ba307189c85ba657213ce642d9c77670f8202c8" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2 0.5.10", + "thiserror 2.0.12", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49df843a9161c85bb8aae55f101bc0bac8bcafd637a620d9122fd7e0b2f7422e" +dependencies = [ + "bytes", + "getrandom 0.3.3", + "lru-slab", + "rand 0.9.2", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.12", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcebb1209ee276352ef14ff8732e24cc2b02bbac986cd74a4c81bcb2f9881970" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2 0.5.10", + "tracing", + "windows-sys 0.59.0", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "quoted-string-parser" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc75379cdb451d001f1cb667a9f74e8b355e9df84cc5193513cbe62b96fc5e9" +dependencies = [ + "pest", + "pest_derive", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", +] + +[[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 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.16", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.3", +] + +[[package]] +name = "redox_syscall" +version = "0.5.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-lite" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "reqwest" +version = "0.12.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbc931937e6ca3a06e3b6c0aa7841849b160a90351d6ab467a8b9b9959767531" +dependencies = [ + "base64", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-rustls", + "tokio-util", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "webpki-roots 1.0.2", +] + +[[package]] +name = "resolv-conf" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95325155c684b1c89f7765e30bc1c42e4a6da51ca513615660cb8a62ef9a88e3" + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.16", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" + +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustls" +version = "0.23.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc" +dependencies = [ + "log", + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +dependencies = [ + "web-time", + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "salsa20" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" +dependencies = [ + "cipher", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "scroll" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ab8598aa408498679922eff7fa985c25d58a90771bd6be794434c5277eab1a6" +dependencies = [ + "scroll_derive", +] + +[[package]] +name = "scroll_derive" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1783eabc414609e28a5ba76aee5ddd52199f7107a0b24c2e9746a1ecc34a683d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "self_cell" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f7d95a54511e0c7be3f51e8867aa8cf35148d7b9445d44de2f943e2b206e749" + +[[package]] +name = "semver" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" +dependencies = [ + "serde", +] + +[[package]] +name = "send_wrapper" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_bytes" +version = "0.11.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8437fd221bde2d4ca316d61b90e337e9e702b3820b87d63caa9ba6c02bd06d96" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "serde_json" +version = "1.0.142" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[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 = "serdect" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" +dependencies = [ + "base16ct", + "serde", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha1_smol" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + +[[package]] +name = "simple-dns" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee851d0e5e7af3721faea1843e8015e820a234f81fda3dea9247e15bac9a86a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "slab" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "smawk" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" + +[[package]] +name = "snafu" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320b01e011bf8d5d7a4a4a4be966d9160968935849c83b918827f6a435e7f627" +dependencies = [ + "backtrace", + "snafu-derive", +] + +[[package]] +name = "snafu-derive" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1961e2ef424c1424204d3a5d6975f934f56b6d50ff5732382d84ebf460e147f7" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "socket2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "socket2" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spin" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[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 = "strum" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "stun-rs" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb921f10397d5669e1af6455e9e2d367bf1f9cebcd6b1dd1dc50e19f6a9ac2ac" +dependencies = [ + "base64", + "bounded-integer", + "byteorder", + "crc", + "enumflags2", + "fallible-iterator", + "hmac-sha1", + "hmac-sha256", + "hostname-validator", + "lazy_static", + "md5", + "paste", + "precis-core", + "precis-profiles", + "quoted-string-parser", + "rand 0.9.2", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "surge-ping" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fda78103d8016bb25c331ddc54af634e801806463682cc3e549d335df644d95" +dependencies = [ + "hex", + "parking_lot", + "pnet_packet", + "rand 0.9.2", + "socket2 0.5.10", + "thiserror 1.0.69", + "tokio", + "tracing", +] + +[[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.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tagptr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057" +dependencies = [ + "smawk", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +dependencies = [ + "thiserror-impl 2.0.12", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "time" +version = "0.3.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" +dependencies = [ + "deranged", + "js-sys", + "num-conv", + "powerfmt", + "serde", + "time-core", +] + +[[package]] +name = "time-core" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" + +[[package]] +name = "tinystr" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tinyvec" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71" +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.47.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" +dependencies = [ + "backtrace", + "bytes", + "io-uring", + "libc", + "mio", + "pin-project-lite", + "signal-hook-registry", + "slab", + "socket2 0.6.0", + "tokio-macros", + "windows-sys 0.59.0", +] + +[[package]] +name = "tokio-macros" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", + "tokio-util", +] + +[[package]] +name = "tokio-util" +version = "0.7.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "futures-util", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-websockets" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f29ba084eb43becc9864ba514b4a64f5f65b82f9a6ffbafa5436c1c80605f03" +dependencies = [ + "base64", + "bytes", + "futures-core", + "futures-sink", + "getrandom 0.3.3", + "http", + "httparse", + "rand 0.9.2", + "ring", + "rustls-pki-types", + "simdutf8", + "tokio", + "tokio-rustls", + "tokio-util", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" + +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tower" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +dependencies = [ + "bitflags", + "bytes", + "futures-util", + "http", + "http-body", + "iri-string", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "tracing-core" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-error" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b1581020d7a273442f5b45074a6a57d5757ad0a47dac0e9f0bd57b81936f3db" +dependencies = [ + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + +[[package]] +name = "ucd-parse" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06ff81122fcbf4df4c1660b15f7e3336058e7aec14437c9f85c6b31a0f279b9" +dependencies = [ + "regex-lite", +] + +[[package]] +name = "ucd-trie" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" + +[[package]] +name = "unicase" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "unicode-normalization" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "uniffi" +version = "0.28.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cb08c58c7ed7033150132febe696bef553f891b1ede57424b40d87a89e3c170" +dependencies = [ + "anyhow", + "cargo_metadata", + "uniffi_bindgen", + "uniffi_core", + "uniffi_macros", +] + +[[package]] +name = "uniffi_bindgen" +version = "0.28.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cade167af943e189a55020eda2c314681e223f1e42aca7c4e52614c2b627698f" +dependencies = [ + "anyhow", + "askama", + "camino", + "cargo_metadata", + "fs-err", + "glob", + "goblin", + "heck", + "once_cell", + "paste", + "serde", + "textwrap", + "toml", + "uniffi_meta", + "uniffi_udl", +] + +[[package]] +name = "uniffi_checksum_derive" +version = "0.28.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "802d2051a700e3ec894c79f80d2705b69d85844dafbbe5d1a92776f8f48b563a" +dependencies = [ + "quote", + "syn 2.0.104", +] + +[[package]] +name = "uniffi_core" +version = "0.28.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc7687007d2546c454d8ae609b105daceb88175477dac280707ad6d95bcd6f1f" +dependencies = [ + "anyhow", + "async-compat", + "bytes", + "log", + "once_cell", + "paste", + "static_assertions", +] + +[[package]] +name = "uniffi_macros" +version = "0.28.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12c65a5b12ec544ef136693af8759fb9d11aefce740fb76916721e876639033b" +dependencies = [ + "bincode", + "camino", + "fs-err", + "once_cell", + "proc-macro2", + "quote", + "serde", + "syn 2.0.104", + "toml", + "uniffi_meta", +] + +[[package]] +name = "uniffi_meta" +version = "0.28.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a74ed96c26882dac1ca9b93ca23c827e284bacbd7ec23c6f0b0372f747d59e4" +dependencies = [ + "anyhow", + "bytes", + "siphasher", + "uniffi_checksum_derive", +] + +[[package]] +name = "uniffi_testing" +version = "0.28.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6f984f0781f892cc864a62c3a5c60361b1ccbd68e538e6c9fbced5d82268ac" +dependencies = [ + "anyhow", + "camino", + "cargo_metadata", + "fs-err", + "once_cell", +] + +[[package]] +name = "uniffi_udl" +version = "0.28.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037820a4cfc4422db1eaa82f291a3863c92c7d1789dc513489c36223f9b4cdfc" +dependencies = [ + "anyhow", + "textwrap", + "uniffi_meta", + "uniffi_testing", + "weedle2", +] + +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "uuid" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d" +dependencies = [ + "getrandom 0.3.3", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[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.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn 2.0.104", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "wasm-streams" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "web-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "0.26.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" +dependencies = [ + "webpki-roots 1.0.2", +] + +[[package]] +name = "webpki-roots" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "weedle2" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "998d2c24ec099a87daf9467808859f9d82b61f1d9c9701251aea037f514eae0e" +dependencies = [ + "nom", +] + +[[package]] +name = "widestring" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd7cf3379ca1aac9eea11fba24fd7e315d621f8dfe35c8d7d2be8b793726e07d" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[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.61.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" +dependencies = [ + "windows-collections", + "windows-core", + "windows-future", + "windows-link", + "windows-numerics", +] + +[[package]] +name = "windows-collections" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" +dependencies = [ + "windows-core", +] + +[[package]] +name = "windows-core" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-future" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" +dependencies = [ + "windows-core", + "windows-link", + "windows-threading", +] + +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "windows-interface" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-numerics" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" +dependencies = [ + "windows-core", + "windows-link", +] + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-threading" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags", +] + +[[package]] +name = "wmi" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3de777dce4cbcdc661d5d18e78ce4b46a37adc2bb7c0078a556c7f07bcce2f" +dependencies = [ + "chrono", + "futures", + "log", + "serde", + "thiserror 2.0.12", + "windows", + "windows-core", +] + +[[package]] +name = "writeable" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" + +[[package]] +name = "ws_stream_wasm" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c173014acad22e83f16403ee360115b38846fe754e735c5d9d3803fe70c6abc" +dependencies = [ + "async_io_stream", + "futures", + "js-sys", + "log", + "pharos", + "rustc_version", + "send_wrapper", + "thiserror 2.0.12", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "xml-rs" +version = "0.8.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fd8403733700263c6eb89f192880191f1b83e332f7a20371ddcf421c4a337c7" + +[[package]] +name = "xmltree" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7d8a75eaf6557bb84a65ace8609883db44a29951042ada9b393151532e41fcb" +dependencies = [ + "xml-rs", +] + +[[package]] +name = "yoke" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", + "synstructure", +] + +[[package]] +name = "z32" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2164e798d9e3d84ee2c91139ace54638059a3b23e361f5c11781c2c6459bde0f" + +[[package]] +name = "zerocopy" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + +[[package]] +name = "zerotrie" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdbb9122ea75b11bf96e7492afb723e8a7fbe12c67417aa95e7e3d18144d37cd" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 00000000..cb782292 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "iroh-streamplace" +version = "0.1.0" +edition = "2024" + +[lib] +name = "iroh_streamplace" +crate-type = ["staticlib", "cdylib"] + +[dependencies] +iroh = "0.91.1" + +uniffi = { version = "=0.28.3", features = ["tokio"] } diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..593e0792 --- /dev/null +++ b/Makefile @@ -0,0 +1,16 @@ +.PHONY: all +all: rust go + +.PHONY: rust +rust: + cargo install uniffi-bindgen-go --git https://github.com/NordSecurity/uniffi-bindgen-go --tag v0.3.0+v0.28.3 + cargo build --release + +.PHONY: go +go: + mkdir -p dist + uniffi-bindgen-go --out-dir pkg/iroh_streamplace/generated --library ./target/release/libiroh_streamplace.dylib + +.PHONY: test +test: + go test ./pkg/... diff --git a/README.md b/README.md new file mode 100644 index 00000000..8371bd5a --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# iroh-streamplace + + +## Development + +```sh +# Building +> make +# Testing +> make test +``` diff --git a/go.mod b/go.mod new file mode 100644 index 00000000..0cffb986 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/n0-computer/iroh-streamplace + +go 1.22.2 diff --git a/pkg/iroh_streamplace/generated/iroh_streamplace/iroh_streamplace.go b/pkg/iroh_streamplace/generated/iroh_streamplace/iroh_streamplace.go new file mode 100644 index 00000000..8b0bbf13 --- /dev/null +++ b/pkg/iroh_streamplace/generated/iroh_streamplace/iroh_streamplace.go @@ -0,0 +1,617 @@ +package iroh_streamplace + +// #include +import "C" + +import ( + "bytes" + "encoding/binary" + "fmt" + "io" + "math" + "runtime" + "runtime/cgo" + "sync/atomic" + "unsafe" +) + +// This is needed, because as of go 1.24 +// type RustBuffer C.RustBuffer cannot have methods, +// RustBuffer is treated as non-local type +type GoRustBuffer struct { + inner C.RustBuffer +} + +type RustBufferI interface { + AsReader() *bytes.Reader + Free() + ToGoBytes() []byte + Data() unsafe.Pointer + Len() uint64 + Capacity() uint64 +} + +func RustBufferFromExternal(b RustBufferI) GoRustBuffer { + return GoRustBuffer{ + inner: C.RustBuffer{ + capacity: C.uint64_t(b.Capacity()), + len: C.uint64_t(b.Len()), + data: (*C.uchar)(b.Data()), + }, + } +} + +func (cb GoRustBuffer) Capacity() uint64 { + return uint64(cb.inner.capacity) +} + +func (cb GoRustBuffer) Len() uint64 { + return uint64(cb.inner.len) +} + +func (cb GoRustBuffer) Data() unsafe.Pointer { + return unsafe.Pointer(cb.inner.data) +} + +func (cb GoRustBuffer) AsReader() *bytes.Reader { + b := unsafe.Slice((*byte)(cb.inner.data), C.uint64_t(cb.inner.len)) + return bytes.NewReader(b) +} + +func (cb GoRustBuffer) Free() { + rustCall(func(status *C.RustCallStatus) bool { + C.ffi_iroh_streamplace_rustbuffer_free(cb.inner, status) + return false + }) +} + +func (cb GoRustBuffer) ToGoBytes() []byte { + return C.GoBytes(unsafe.Pointer(cb.inner.data), C.int(cb.inner.len)) +} + +func stringToRustBuffer(str string) C.RustBuffer { + return bytesToRustBuffer([]byte(str)) +} + +func bytesToRustBuffer(b []byte) C.RustBuffer { + if len(b) == 0 { + return C.RustBuffer{} + } + // We can pass the pointer along here, as it is pinned + // for the duration of this call + foreign := C.ForeignBytes{ + len: C.int(len(b)), + data: (*C.uchar)(unsafe.Pointer(&b[0])), + } + + return rustCall(func(status *C.RustCallStatus) C.RustBuffer { + return C.ffi_iroh_streamplace_rustbuffer_from_bytes(foreign, status) + }) +} + +type BufLifter[GoType any] interface { + Lift(value RustBufferI) GoType +} + +type BufLowerer[GoType any] interface { + Lower(value GoType) C.RustBuffer +} + +type BufReader[GoType any] interface { + Read(reader io.Reader) GoType +} + +type BufWriter[GoType any] interface { + Write(writer io.Writer, value GoType) +} + +func LowerIntoRustBuffer[GoType any](bufWriter BufWriter[GoType], value GoType) C.RustBuffer { + // This might be not the most efficient way but it does not require knowing allocation size + // beforehand + var buffer bytes.Buffer + bufWriter.Write(&buffer, value) + + bytes, err := io.ReadAll(&buffer) + if err != nil { + panic(fmt.Errorf("reading written data: %w", err)) + } + return bytesToRustBuffer(bytes) +} + +func LiftFromRustBuffer[GoType any](bufReader BufReader[GoType], rbuf RustBufferI) GoType { + defer rbuf.Free() + reader := rbuf.AsReader() + item := bufReader.Read(reader) + if reader.Len() > 0 { + // TODO: Remove this + leftover, _ := io.ReadAll(reader) + panic(fmt.Errorf("Junk remaining in buffer after lifting: %s", string(leftover))) + } + return item +} + +func rustCallWithError[E any, U any](converter BufReader[*E], callback func(*C.RustCallStatus) U) (U, *E) { + var status C.RustCallStatus + returnValue := callback(&status) + err := checkCallStatus(converter, status) + return returnValue, err +} + +func checkCallStatus[E any](converter BufReader[*E], status C.RustCallStatus) *E { + switch status.code { + case 0: + return nil + case 1: + return LiftFromRustBuffer(converter, GoRustBuffer{inner: status.errorBuf}) + case 2: + // when the rust code sees a panic, it tries to construct a rustBuffer + // with the message. but if that code panics, then it just sends back + // an empty buffer. + if status.errorBuf.len > 0 { + panic(fmt.Errorf("%s", FfiConverterStringINSTANCE.Lift(GoRustBuffer{inner: status.errorBuf}))) + } else { + panic(fmt.Errorf("Rust panicked while handling Rust panic")) + } + default: + panic(fmt.Errorf("unknown status code: %d", status.code)) + } +} + +func checkCallStatusUnknown(status C.RustCallStatus) error { + switch status.code { + case 0: + return nil + case 1: + panic(fmt.Errorf("function not returning an error returned an error")) + case 2: + // when the rust code sees a panic, it tries to construct a C.RustBuffer + // with the message. but if that code panics, then it just sends back + // an empty buffer. + if status.errorBuf.len > 0 { + panic(fmt.Errorf("%s", FfiConverterStringINSTANCE.Lift(GoRustBuffer{ + inner: status.errorBuf, + }))) + } else { + panic(fmt.Errorf("Rust panicked while handling Rust panic")) + } + default: + return fmt.Errorf("unknown status code: %d", status.code) + } +} + +func rustCall[U any](callback func(*C.RustCallStatus) U) U { + returnValue, err := rustCallWithError[error](nil, callback) + if err != nil { + panic(err) + } + return returnValue +} + +type NativeError interface { + AsError() error +} + +func writeInt8(writer io.Writer, value int8) { + if err := binary.Write(writer, binary.BigEndian, value); err != nil { + panic(err) + } +} + +func writeUint8(writer io.Writer, value uint8) { + if err := binary.Write(writer, binary.BigEndian, value); err != nil { + panic(err) + } +} + +func writeInt16(writer io.Writer, value int16) { + if err := binary.Write(writer, binary.BigEndian, value); err != nil { + panic(err) + } +} + +func writeUint16(writer io.Writer, value uint16) { + if err := binary.Write(writer, binary.BigEndian, value); err != nil { + panic(err) + } +} + +func writeInt32(writer io.Writer, value int32) { + if err := binary.Write(writer, binary.BigEndian, value); err != nil { + panic(err) + } +} + +func writeUint32(writer io.Writer, value uint32) { + if err := binary.Write(writer, binary.BigEndian, value); err != nil { + panic(err) + } +} + +func writeInt64(writer io.Writer, value int64) { + if err := binary.Write(writer, binary.BigEndian, value); err != nil { + panic(err) + } +} + +func writeUint64(writer io.Writer, value uint64) { + if err := binary.Write(writer, binary.BigEndian, value); err != nil { + panic(err) + } +} + +func writeFloat32(writer io.Writer, value float32) { + if err := binary.Write(writer, binary.BigEndian, value); err != nil { + panic(err) + } +} + +func writeFloat64(writer io.Writer, value float64) { + if err := binary.Write(writer, binary.BigEndian, value); err != nil { + panic(err) + } +} + +func readInt8(reader io.Reader) int8 { + var result int8 + if err := binary.Read(reader, binary.BigEndian, &result); err != nil { + panic(err) + } + return result +} + +func readUint8(reader io.Reader) uint8 { + var result uint8 + if err := binary.Read(reader, binary.BigEndian, &result); err != nil { + panic(err) + } + return result +} + +func readInt16(reader io.Reader) int16 { + var result int16 + if err := binary.Read(reader, binary.BigEndian, &result); err != nil { + panic(err) + } + return result +} + +func readUint16(reader io.Reader) uint16 { + var result uint16 + if err := binary.Read(reader, binary.BigEndian, &result); err != nil { + panic(err) + } + return result +} + +func readInt32(reader io.Reader) int32 { + var result int32 + if err := binary.Read(reader, binary.BigEndian, &result); err != nil { + panic(err) + } + return result +} + +func readUint32(reader io.Reader) uint32 { + var result uint32 + if err := binary.Read(reader, binary.BigEndian, &result); err != nil { + panic(err) + } + return result +} + +func readInt64(reader io.Reader) int64 { + var result int64 + if err := binary.Read(reader, binary.BigEndian, &result); err != nil { + panic(err) + } + return result +} + +func readUint64(reader io.Reader) uint64 { + var result uint64 + if err := binary.Read(reader, binary.BigEndian, &result); err != nil { + panic(err) + } + return result +} + +func readFloat32(reader io.Reader) float32 { + var result float32 + if err := binary.Read(reader, binary.BigEndian, &result); err != nil { + panic(err) + } + return result +} + +func readFloat64(reader io.Reader) float64 { + var result float64 + if err := binary.Read(reader, binary.BigEndian, &result); err != nil { + panic(err) + } + return result +} + +func init() { + + uniffiCheckChecksums() +} + +func uniffiCheckChecksums() { + // Get the bindings contract version from our ComponentInterface + bindingsContractVersion := 26 + // Get the scaffolding contract version by calling the into the dylib + scaffoldingContractVersion := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint32_t { + return C.ffi_iroh_streamplace_uniffi_contract_version() + }) + if bindingsContractVersion != int(scaffoldingContractVersion) { + // If this happens try cleaning and rebuilding your project + panic("iroh_streamplace: UniFFI contract version mismatch") + } + { + checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_iroh_streamplace_checksum_constructor_senderendpoint_new() + }) + if checksum != 37772 { + // If this happens try cleaning and rebuilding your project + panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_constructor_senderendpoint_new: UniFFI API checksum mismatch") + } + } +} + +type FfiConverterString struct{} + +var FfiConverterStringINSTANCE = FfiConverterString{} + +func (FfiConverterString) Lift(rb RustBufferI) string { + defer rb.Free() + reader := rb.AsReader() + b, err := io.ReadAll(reader) + if err != nil { + panic(fmt.Errorf("reading reader: %w", err)) + } + return string(b) +} + +func (FfiConverterString) Read(reader io.Reader) string { + length := readInt32(reader) + buffer := make([]byte, length) + read_length, err := reader.Read(buffer) + if err != nil { + panic(err) + } + if read_length != int(length) { + panic(fmt.Errorf("bad read length when reading string, expected %d, read %d", length, read_length)) + } + return string(buffer) +} + +func (FfiConverterString) Lower(value string) C.RustBuffer { + return stringToRustBuffer(value) +} + +func (FfiConverterString) Write(writer io.Writer, value string) { + if len(value) > math.MaxInt32 { + panic("String is too large to fit into Int32") + } + + writeInt32(writer, int32(len(value))) + write_length, err := io.WriteString(writer, value) + if err != nil { + panic(err) + } + if write_length != len(value) { + panic(fmt.Errorf("bad write length when writing string, expected %d, written %d", len(value), write_length)) + } +} + +type FfiDestroyerString struct{} + +func (FfiDestroyerString) Destroy(_ string) {} + +// Below is an implementation of synchronization requirements outlined in the link. +// https://github.com/mozilla/uniffi-rs/blob/0dc031132d9493ca812c3af6e7dd60ad2ea95bf0/uniffi_bindgen/src/bindings/kotlin/templates/ObjectRuntime.kt#L31 + +type FfiObject struct { + pointer unsafe.Pointer + callCounter atomic.Int64 + cloneFunction func(unsafe.Pointer, *C.RustCallStatus) unsafe.Pointer + freeFunction func(unsafe.Pointer, *C.RustCallStatus) + destroyed atomic.Bool +} + +func newFfiObject( + pointer unsafe.Pointer, + cloneFunction func(unsafe.Pointer, *C.RustCallStatus) unsafe.Pointer, + freeFunction func(unsafe.Pointer, *C.RustCallStatus), +) FfiObject { + return FfiObject{ + pointer: pointer, + cloneFunction: cloneFunction, + freeFunction: freeFunction, + } +} + +func (ffiObject *FfiObject) incrementPointer(debugName string) unsafe.Pointer { + for { + counter := ffiObject.callCounter.Load() + if counter <= -1 { + panic(fmt.Errorf("%v object has already been destroyed", debugName)) + } + if counter == math.MaxInt64 { + panic(fmt.Errorf("%v object call counter would overflow", debugName)) + } + if ffiObject.callCounter.CompareAndSwap(counter, counter+1) { + break + } + } + + return rustCall(func(status *C.RustCallStatus) unsafe.Pointer { + return ffiObject.cloneFunction(ffiObject.pointer, status) + }) +} + +func (ffiObject *FfiObject) decrementPointer() { + if ffiObject.callCounter.Add(-1) == -1 { + ffiObject.freeRustArcPtr() + } +} + +func (ffiObject *FfiObject) destroy() { + if ffiObject.destroyed.CompareAndSwap(false, true) { + if ffiObject.callCounter.Add(-1) == -1 { + ffiObject.freeRustArcPtr() + } + } +} + +func (ffiObject *FfiObject) freeRustArcPtr() { + rustCall(func(status *C.RustCallStatus) int32 { + ffiObject.freeFunction(ffiObject.pointer, status) + return 0 + }) +} + +type SenderEndpointInterface interface { +} +type SenderEndpoint struct { + ffiObject FfiObject +} + +// Create a new sender endpoint. +func NewSenderEndpoint() *SenderEndpoint { + res, _ := uniffiRustCallAsync[struct{}]( + nil, + // completeFn + func(handle C.uint64_t, status *C.RustCallStatus) unsafe.Pointer { + res := C.ffi_iroh_streamplace_rust_future_complete_pointer(handle, status) + return res + }, + // liftFn + func(ffi unsafe.Pointer) *SenderEndpoint { + return FfiConverterSenderEndpointINSTANCE.Lift(ffi) + }, + C.uniffi_iroh_streamplace_fn_constructor_senderendpoint_new(), + // pollFn + func(handle C.uint64_t, continuation C.UniffiRustFutureContinuationCallback, data C.uint64_t) { + C.ffi_iroh_streamplace_rust_future_poll_pointer(handle, continuation, data) + }, + // freeFn + func(handle C.uint64_t) { + C.ffi_iroh_streamplace_rust_future_free_pointer(handle) + }, + ) + + return res +} + +func (object *SenderEndpoint) Destroy() { + runtime.SetFinalizer(object, nil) + object.ffiObject.destroy() +} + +type FfiConverterSenderEndpoint struct{} + +var FfiConverterSenderEndpointINSTANCE = FfiConverterSenderEndpoint{} + +func (c FfiConverterSenderEndpoint) Lift(pointer unsafe.Pointer) *SenderEndpoint { + result := &SenderEndpoint{ + newFfiObject( + pointer, + func(pointer unsafe.Pointer, status *C.RustCallStatus) unsafe.Pointer { + return C.uniffi_iroh_streamplace_fn_clone_senderendpoint(pointer, status) + }, + func(pointer unsafe.Pointer, status *C.RustCallStatus) { + C.uniffi_iroh_streamplace_fn_free_senderendpoint(pointer, status) + }, + ), + } + runtime.SetFinalizer(result, (*SenderEndpoint).Destroy) + return result +} + +func (c FfiConverterSenderEndpoint) Read(reader io.Reader) *SenderEndpoint { + return c.Lift(unsafe.Pointer(uintptr(readUint64(reader)))) +} + +func (c FfiConverterSenderEndpoint) Lower(value *SenderEndpoint) unsafe.Pointer { + // TODO: this is bad - all synchronization from ObjectRuntime.go is discarded here, + // because the pointer will be decremented immediately after this function returns, + // and someone will be left holding onto a non-locked pointer. + pointer := value.ffiObject.incrementPointer("*SenderEndpoint") + defer value.ffiObject.decrementPointer() + return pointer + +} + +func (c FfiConverterSenderEndpoint) Write(writer io.Writer, value *SenderEndpoint) { + writeUint64(writer, uint64(uintptr(c.Lower(value)))) +} + +type FfiDestroyerSenderEndpoint struct{} + +func (_ FfiDestroyerSenderEndpoint) Destroy(value *SenderEndpoint) { + value.Destroy() +} + +const ( + uniffiRustFuturePollReady int8 = 0 + uniffiRustFuturePollMaybeReady int8 = 1 +) + +type rustFuturePollFunc func(C.uint64_t, C.UniffiRustFutureContinuationCallback, C.uint64_t) +type rustFutureCompleteFunc[T any] func(C.uint64_t, *C.RustCallStatus) T +type rustFutureFreeFunc func(C.uint64_t) + +//export iroh_streamplace_uniffiFutureContinuationCallback +func iroh_streamplace_uniffiFutureContinuationCallback(data C.uint64_t, pollResult C.int8_t) { + h := cgo.Handle(uintptr(data)) + waiter := h.Value().(chan int8) + waiter <- int8(pollResult) +} + +func uniffiRustCallAsync[E any, T any, F any]( + errConverter BufReader[*E], + completeFunc rustFutureCompleteFunc[F], + liftFunc func(F) T, + rustFuture C.uint64_t, + pollFunc rustFuturePollFunc, + freeFunc rustFutureFreeFunc, +) (T, *E) { + defer freeFunc(rustFuture) + + pollResult := int8(-1) + waiter := make(chan int8, 1) + + chanHandle := cgo.NewHandle(waiter) + defer chanHandle.Delete() + + for pollResult != uniffiRustFuturePollReady { + pollFunc( + rustFuture, + (C.UniffiRustFutureContinuationCallback)(C.iroh_streamplace_uniffiFutureContinuationCallback), + C.uint64_t(chanHandle), + ) + pollResult = <-waiter + } + + var goValue T + var ffiValue F + var err *E + + ffiValue, err = rustCallWithError(errConverter, func(status *C.RustCallStatus) F { + return completeFunc(rustFuture, status) + }) + if err != nil { + return goValue, err + } + return liftFunc(ffiValue), nil +} + +//export iroh_streamplace_uniffiFreeGorutine +func iroh_streamplace_uniffiFreeGorutine(data C.uint64_t) { + handle := cgo.Handle(uintptr(data)) + defer handle.Delete() + + guard := handle.Value().(chan struct{}) + guard <- struct{}{} +} diff --git a/pkg/iroh_streamplace/generated/iroh_streamplace/iroh_streamplace.h b/pkg/iroh_streamplace/generated/iroh_streamplace/iroh_streamplace.h new file mode 100644 index 00000000..480d0467 --- /dev/null +++ b/pkg/iroh_streamplace/generated/iroh_streamplace/iroh_streamplace.h @@ -0,0 +1,692 @@ + + +// This file was autogenerated by some hot garbage in the `uniffi` crate. +// Trust me, you don't want to mess with it! + + + +#include +#include + +// The following structs are used to implement the lowest level +// of the FFI, and thus useful to multiple uniffied crates. +// We ensure they are declared exactly once, with a header guard, UNIFFI_SHARED_H. +#ifdef UNIFFI_SHARED_H + // We also try to prevent mixing versions of shared uniffi header structs. + // If you add anything to the #else block, you must increment the version suffix in UNIFFI_SHARED_HEADER_V6 + #ifndef UNIFFI_SHARED_HEADER_V6 + #error Combining helper code from multiple versions of uniffi is not supported + #endif // ndef UNIFFI_SHARED_HEADER_V6 +#else +#define UNIFFI_SHARED_H +#define UNIFFI_SHARED_HEADER_V6 +// ⚠️ Attention: If you change this #else block (ending in `#endif // def UNIFFI_SHARED_H`) you *must* ⚠️ +// ⚠️ increment the version suffix in all instances of UNIFFI_SHARED_HEADER_V6 in this file. ⚠️ + +typedef struct RustBuffer { + uint64_t capacity; + uint64_t len; + uint8_t *data; +} RustBuffer; + +typedef struct ForeignBytes { + int32_t len; + const uint8_t *data; +} ForeignBytes; + +// Error definitions +typedef struct RustCallStatus { + int8_t code; + RustBuffer errorBuf; +} RustCallStatus; + +#endif // UNIFFI_SHARED_H + + +#ifndef UNIFFI_FFIDEF_RUST_FUTURE_CONTINUATION_CALLBACK +#define UNIFFI_FFIDEF_RUST_FUTURE_CONTINUATION_CALLBACK +typedef void (*UniffiRustFutureContinuationCallback)(uint64_t data, int8_t poll_result); + +// Making function static works arround: +// https://github.com/golang/go/issues/11263 +static void call_UniffiRustFutureContinuationCallback( + UniffiRustFutureContinuationCallback cb, uint64_t data, int8_t poll_result) +{ + return cb(data, poll_result); +} + + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_FREE +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_FREE +typedef void (*UniffiForeignFutureFree)(uint64_t handle); + +// Making function static works arround: +// https://github.com/golang/go/issues/11263 +static void call_UniffiForeignFutureFree( + UniffiForeignFutureFree cb, uint64_t handle) +{ + return cb(handle); +} + + +#endif +#ifndef UNIFFI_FFIDEF_CALLBACK_INTERFACE_FREE +#define UNIFFI_FFIDEF_CALLBACK_INTERFACE_FREE +typedef void (*UniffiCallbackInterfaceFree)(uint64_t handle); + +// Making function static works arround: +// https://github.com/golang/go/issues/11263 +static void call_UniffiCallbackInterfaceFree( + UniffiCallbackInterfaceFree cb, uint64_t handle) +{ + return cb(handle); +} + + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE +#define UNIFFI_FFIDEF_FOREIGN_FUTURE +typedef struct UniffiForeignFuture { + uint64_t handle; + UniffiForeignFutureFree free; +} UniffiForeignFuture; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_U8 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_U8 +typedef struct UniffiForeignFutureStructU8 { + uint8_t returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureStructU8; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U8 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U8 +typedef void (*UniffiForeignFutureCompleteU8)(uint64_t callback_data, UniffiForeignFutureStructU8 result); + +// Making function static works arround: +// https://github.com/golang/go/issues/11263 +static void call_UniffiForeignFutureCompleteU8( + UniffiForeignFutureCompleteU8 cb, uint64_t callback_data, UniffiForeignFutureStructU8 result) +{ + return cb(callback_data, result); +} + + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_I8 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_I8 +typedef struct UniffiForeignFutureStructI8 { + int8_t returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureStructI8; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I8 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I8 +typedef void (*UniffiForeignFutureCompleteI8)(uint64_t callback_data, UniffiForeignFutureStructI8 result); + +// Making function static works arround: +// https://github.com/golang/go/issues/11263 +static void call_UniffiForeignFutureCompleteI8( + UniffiForeignFutureCompleteI8 cb, uint64_t callback_data, UniffiForeignFutureStructI8 result) +{ + return cb(callback_data, result); +} + + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_U16 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_U16 +typedef struct UniffiForeignFutureStructU16 { + uint16_t returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureStructU16; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U16 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U16 +typedef void (*UniffiForeignFutureCompleteU16)(uint64_t callback_data, UniffiForeignFutureStructU16 result); + +// Making function static works arround: +// https://github.com/golang/go/issues/11263 +static void call_UniffiForeignFutureCompleteU16( + UniffiForeignFutureCompleteU16 cb, uint64_t callback_data, UniffiForeignFutureStructU16 result) +{ + return cb(callback_data, result); +} + + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_I16 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_I16 +typedef struct UniffiForeignFutureStructI16 { + int16_t returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureStructI16; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I16 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I16 +typedef void (*UniffiForeignFutureCompleteI16)(uint64_t callback_data, UniffiForeignFutureStructI16 result); + +// Making function static works arround: +// https://github.com/golang/go/issues/11263 +static void call_UniffiForeignFutureCompleteI16( + UniffiForeignFutureCompleteI16 cb, uint64_t callback_data, UniffiForeignFutureStructI16 result) +{ + return cb(callback_data, result); +} + + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_U32 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_U32 +typedef struct UniffiForeignFutureStructU32 { + uint32_t returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureStructU32; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U32 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U32 +typedef void (*UniffiForeignFutureCompleteU32)(uint64_t callback_data, UniffiForeignFutureStructU32 result); + +// Making function static works arround: +// https://github.com/golang/go/issues/11263 +static void call_UniffiForeignFutureCompleteU32( + UniffiForeignFutureCompleteU32 cb, uint64_t callback_data, UniffiForeignFutureStructU32 result) +{ + return cb(callback_data, result); +} + + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_I32 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_I32 +typedef struct UniffiForeignFutureStructI32 { + int32_t returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureStructI32; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I32 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I32 +typedef void (*UniffiForeignFutureCompleteI32)(uint64_t callback_data, UniffiForeignFutureStructI32 result); + +// Making function static works arround: +// https://github.com/golang/go/issues/11263 +static void call_UniffiForeignFutureCompleteI32( + UniffiForeignFutureCompleteI32 cb, uint64_t callback_data, UniffiForeignFutureStructI32 result) +{ + return cb(callback_data, result); +} + + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_U64 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_U64 +typedef struct UniffiForeignFutureStructU64 { + uint64_t returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureStructU64; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U64 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U64 +typedef void (*UniffiForeignFutureCompleteU64)(uint64_t callback_data, UniffiForeignFutureStructU64 result); + +// Making function static works arround: +// https://github.com/golang/go/issues/11263 +static void call_UniffiForeignFutureCompleteU64( + UniffiForeignFutureCompleteU64 cb, uint64_t callback_data, UniffiForeignFutureStructU64 result) +{ + return cb(callback_data, result); +} + + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_I64 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_I64 +typedef struct UniffiForeignFutureStructI64 { + int64_t returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureStructI64; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I64 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I64 +typedef void (*UniffiForeignFutureCompleteI64)(uint64_t callback_data, UniffiForeignFutureStructI64 result); + +// Making function static works arround: +// https://github.com/golang/go/issues/11263 +static void call_UniffiForeignFutureCompleteI64( + UniffiForeignFutureCompleteI64 cb, uint64_t callback_data, UniffiForeignFutureStructI64 result) +{ + return cb(callback_data, result); +} + + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_F32 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_F32 +typedef struct UniffiForeignFutureStructF32 { + float returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureStructF32; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_F32 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_F32 +typedef void (*UniffiForeignFutureCompleteF32)(uint64_t callback_data, UniffiForeignFutureStructF32 result); + +// Making function static works arround: +// https://github.com/golang/go/issues/11263 +static void call_UniffiForeignFutureCompleteF32( + UniffiForeignFutureCompleteF32 cb, uint64_t callback_data, UniffiForeignFutureStructF32 result) +{ + return cb(callback_data, result); +} + + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_F64 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_F64 +typedef struct UniffiForeignFutureStructF64 { + double returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureStructF64; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_F64 +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_F64 +typedef void (*UniffiForeignFutureCompleteF64)(uint64_t callback_data, UniffiForeignFutureStructF64 result); + +// Making function static works arround: +// https://github.com/golang/go/issues/11263 +static void call_UniffiForeignFutureCompleteF64( + UniffiForeignFutureCompleteF64 cb, uint64_t callback_data, UniffiForeignFutureStructF64 result) +{ + return cb(callback_data, result); +} + + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_POINTER +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_POINTER +typedef struct UniffiForeignFutureStructPointer { + void* returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureStructPointer; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_POINTER +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_POINTER +typedef void (*UniffiForeignFutureCompletePointer)(uint64_t callback_data, UniffiForeignFutureStructPointer result); + +// Making function static works arround: +// https://github.com/golang/go/issues/11263 +static void call_UniffiForeignFutureCompletePointer( + UniffiForeignFutureCompletePointer cb, uint64_t callback_data, UniffiForeignFutureStructPointer result) +{ + return cb(callback_data, result); +} + + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_RUST_BUFFER +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_RUST_BUFFER +typedef struct UniffiForeignFutureStructRustBuffer { + RustBuffer returnValue; + RustCallStatus callStatus; +} UniffiForeignFutureStructRustBuffer; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_RUST_BUFFER +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_RUST_BUFFER +typedef void (*UniffiForeignFutureCompleteRustBuffer)(uint64_t callback_data, UniffiForeignFutureStructRustBuffer result); + +// Making function static works arround: +// https://github.com/golang/go/issues/11263 +static void call_UniffiForeignFutureCompleteRustBuffer( + UniffiForeignFutureCompleteRustBuffer cb, uint64_t callback_data, UniffiForeignFutureStructRustBuffer result) +{ + return cb(callback_data, result); +} + + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_VOID +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_VOID +typedef struct UniffiForeignFutureStructVoid { + RustCallStatus callStatus; +} UniffiForeignFutureStructVoid; + +#endif +#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_VOID +#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_VOID +typedef void (*UniffiForeignFutureCompleteVoid)(uint64_t callback_data, UniffiForeignFutureStructVoid result); + +// Making function static works arround: +// https://github.com/golang/go/issues/11263 +static void call_UniffiForeignFutureCompleteVoid( + UniffiForeignFutureCompleteVoid cb, uint64_t callback_data, UniffiForeignFutureStructVoid result) +{ + return cb(callback_data, result); +} + + +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CLONE_SENDERENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CLONE_SENDERENDPOINT +void* uniffi_iroh_streamplace_fn_clone_senderendpoint(void* ptr, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_FREE_SENDERENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_FREE_SENDERENDPOINT +void uniffi_iroh_streamplace_fn_free_senderendpoint(void* ptr, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CONSTRUCTOR_SENDERENDPOINT_NEW +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CONSTRUCTOR_SENDERENDPOINT_NEW +uint64_t uniffi_iroh_streamplace_fn_constructor_senderendpoint_new(void + +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUSTBUFFER_ALLOC +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUSTBUFFER_ALLOC +RustBuffer ffi_iroh_streamplace_rustbuffer_alloc(uint64_t size, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUSTBUFFER_FROM_BYTES +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUSTBUFFER_FROM_BYTES +RustBuffer ffi_iroh_streamplace_rustbuffer_from_bytes(ForeignBytes bytes, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUSTBUFFER_FREE +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUSTBUFFER_FREE +void ffi_iroh_streamplace_rustbuffer_free(RustBuffer buf, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUSTBUFFER_RESERVE +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUSTBUFFER_RESERVE +RustBuffer ffi_iroh_streamplace_rustbuffer_reserve(RustBuffer buf, uint64_t additional, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_POLL_U8 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_POLL_U8 +void ffi_iroh_streamplace_rust_future_poll_u8(uint64_t handle, UniffiRustFutureContinuationCallback callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_CANCEL_U8 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_CANCEL_U8 +void ffi_iroh_streamplace_rust_future_cancel_u8(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_FREE_U8 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_FREE_U8 +void ffi_iroh_streamplace_rust_future_free_u8(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_COMPLETE_U8 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_COMPLETE_U8 +uint8_t ffi_iroh_streamplace_rust_future_complete_u8(uint64_t handle, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_POLL_I8 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_POLL_I8 +void ffi_iroh_streamplace_rust_future_poll_i8(uint64_t handle, UniffiRustFutureContinuationCallback callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_CANCEL_I8 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_CANCEL_I8 +void ffi_iroh_streamplace_rust_future_cancel_i8(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_FREE_I8 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_FREE_I8 +void ffi_iroh_streamplace_rust_future_free_i8(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_COMPLETE_I8 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_COMPLETE_I8 +int8_t ffi_iroh_streamplace_rust_future_complete_i8(uint64_t handle, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_POLL_U16 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_POLL_U16 +void ffi_iroh_streamplace_rust_future_poll_u16(uint64_t handle, UniffiRustFutureContinuationCallback callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_CANCEL_U16 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_CANCEL_U16 +void ffi_iroh_streamplace_rust_future_cancel_u16(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_FREE_U16 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_FREE_U16 +void ffi_iroh_streamplace_rust_future_free_u16(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_COMPLETE_U16 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_COMPLETE_U16 +uint16_t ffi_iroh_streamplace_rust_future_complete_u16(uint64_t handle, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_POLL_I16 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_POLL_I16 +void ffi_iroh_streamplace_rust_future_poll_i16(uint64_t handle, UniffiRustFutureContinuationCallback callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_CANCEL_I16 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_CANCEL_I16 +void ffi_iroh_streamplace_rust_future_cancel_i16(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_FREE_I16 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_FREE_I16 +void ffi_iroh_streamplace_rust_future_free_i16(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_COMPLETE_I16 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_COMPLETE_I16 +int16_t ffi_iroh_streamplace_rust_future_complete_i16(uint64_t handle, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_POLL_U32 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_POLL_U32 +void ffi_iroh_streamplace_rust_future_poll_u32(uint64_t handle, UniffiRustFutureContinuationCallback callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_CANCEL_U32 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_CANCEL_U32 +void ffi_iroh_streamplace_rust_future_cancel_u32(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_FREE_U32 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_FREE_U32 +void ffi_iroh_streamplace_rust_future_free_u32(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_COMPLETE_U32 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_COMPLETE_U32 +uint32_t ffi_iroh_streamplace_rust_future_complete_u32(uint64_t handle, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_POLL_I32 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_POLL_I32 +void ffi_iroh_streamplace_rust_future_poll_i32(uint64_t handle, UniffiRustFutureContinuationCallback callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_CANCEL_I32 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_CANCEL_I32 +void ffi_iroh_streamplace_rust_future_cancel_i32(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_FREE_I32 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_FREE_I32 +void ffi_iroh_streamplace_rust_future_free_i32(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_COMPLETE_I32 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_COMPLETE_I32 +int32_t ffi_iroh_streamplace_rust_future_complete_i32(uint64_t handle, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_POLL_U64 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_POLL_U64 +void ffi_iroh_streamplace_rust_future_poll_u64(uint64_t handle, UniffiRustFutureContinuationCallback callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_CANCEL_U64 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_CANCEL_U64 +void ffi_iroh_streamplace_rust_future_cancel_u64(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_FREE_U64 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_FREE_U64 +void ffi_iroh_streamplace_rust_future_free_u64(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_COMPLETE_U64 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_COMPLETE_U64 +uint64_t ffi_iroh_streamplace_rust_future_complete_u64(uint64_t handle, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_POLL_I64 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_POLL_I64 +void ffi_iroh_streamplace_rust_future_poll_i64(uint64_t handle, UniffiRustFutureContinuationCallback callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_CANCEL_I64 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_CANCEL_I64 +void ffi_iroh_streamplace_rust_future_cancel_i64(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_FREE_I64 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_FREE_I64 +void ffi_iroh_streamplace_rust_future_free_i64(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_COMPLETE_I64 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_COMPLETE_I64 +int64_t ffi_iroh_streamplace_rust_future_complete_i64(uint64_t handle, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_POLL_F32 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_POLL_F32 +void ffi_iroh_streamplace_rust_future_poll_f32(uint64_t handle, UniffiRustFutureContinuationCallback callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_CANCEL_F32 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_CANCEL_F32 +void ffi_iroh_streamplace_rust_future_cancel_f32(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_FREE_F32 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_FREE_F32 +void ffi_iroh_streamplace_rust_future_free_f32(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_COMPLETE_F32 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_COMPLETE_F32 +float ffi_iroh_streamplace_rust_future_complete_f32(uint64_t handle, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_POLL_F64 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_POLL_F64 +void ffi_iroh_streamplace_rust_future_poll_f64(uint64_t handle, UniffiRustFutureContinuationCallback callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_CANCEL_F64 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_CANCEL_F64 +void ffi_iroh_streamplace_rust_future_cancel_f64(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_FREE_F64 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_FREE_F64 +void ffi_iroh_streamplace_rust_future_free_f64(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_COMPLETE_F64 +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_COMPLETE_F64 +double ffi_iroh_streamplace_rust_future_complete_f64(uint64_t handle, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_POLL_POINTER +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_POLL_POINTER +void ffi_iroh_streamplace_rust_future_poll_pointer(uint64_t handle, UniffiRustFutureContinuationCallback callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_CANCEL_POINTER +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_CANCEL_POINTER +void ffi_iroh_streamplace_rust_future_cancel_pointer(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_FREE_POINTER +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_FREE_POINTER +void ffi_iroh_streamplace_rust_future_free_pointer(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_COMPLETE_POINTER +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_COMPLETE_POINTER +void* ffi_iroh_streamplace_rust_future_complete_pointer(uint64_t handle, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_POLL_RUST_BUFFER +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_POLL_RUST_BUFFER +void ffi_iroh_streamplace_rust_future_poll_rust_buffer(uint64_t handle, UniffiRustFutureContinuationCallback callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_CANCEL_RUST_BUFFER +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_CANCEL_RUST_BUFFER +void ffi_iroh_streamplace_rust_future_cancel_rust_buffer(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_FREE_RUST_BUFFER +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_FREE_RUST_BUFFER +void ffi_iroh_streamplace_rust_future_free_rust_buffer(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_COMPLETE_RUST_BUFFER +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_COMPLETE_RUST_BUFFER +RustBuffer ffi_iroh_streamplace_rust_future_complete_rust_buffer(uint64_t handle, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_POLL_VOID +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_POLL_VOID +void ffi_iroh_streamplace_rust_future_poll_void(uint64_t handle, UniffiRustFutureContinuationCallback callback, uint64_t callback_data +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_CANCEL_VOID +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_CANCEL_VOID +void ffi_iroh_streamplace_rust_future_cancel_void(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_FREE_VOID +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_FREE_VOID +void ffi_iroh_streamplace_rust_future_free_void(uint64_t handle +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_COMPLETE_VOID +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_COMPLETE_VOID +void ffi_iroh_streamplace_rust_future_complete_void(uint64_t handle, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_CONSTRUCTOR_SENDERENDPOINT_NEW +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_CONSTRUCTOR_SENDERENDPOINT_NEW +uint16_t uniffi_iroh_streamplace_checksum_constructor_senderendpoint_new(void + +); +#endif +#ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_UNIFFI_CONTRACT_VERSION +#define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_UNIFFI_CONTRACT_VERSION +uint32_t ffi_iroh_streamplace_uniffi_contract_version(void + +); +#endif + + +void iroh_streamplace_uniffiFutureContinuationCallback(uint64_t, int8_t); +void iroh_streamplace_uniffiFreeGorutine(uint64_t); diff --git a/pkg/iroh_streamplace/iroh_streamplace.go b/pkg/iroh_streamplace/iroh_streamplace.go new file mode 100644 index 00000000..0dc2a43e --- /dev/null +++ b/pkg/iroh_streamplace/iroh_streamplace.go @@ -0,0 +1,14 @@ +package iroh_streamplace + +import ( + iroh "github.com/n0-computer/iroh-streamplace/pkg/iroh_streamplace/generated/iroh_streamplace" +) + +// #cgo LDFLAGS: -L../../target/release -liroh_streamplace -lm +// #cgo darwin LDFLAGS: -framework Security +import "C" + +func NewSenderEndpoint() *iroh.SenderEndpoint { + ep := iroh.NewSenderEndpoint() + return ep +} diff --git a/pkg/iroh_streamplace/iroh_streamplace_test.go b/pkg/iroh_streamplace/iroh_streamplace_test.go new file mode 100644 index 00000000..6ecc16f8 --- /dev/null +++ b/pkg/iroh_streamplace/iroh_streamplace_test.go @@ -0,0 +1,9 @@ +package iroh_streamplace + +import ( + "testing" +) + +func TestSender(*testing.T) { + _ = NewSenderEndpoint() +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 00000000..471ce1bd --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,17 @@ +uniffi::setup_scaffolding!(); + +#[derive(uniffi::Object)] +pub struct SenderEndpoint { + endpoint: iroh::Endpoint, +} + +#[uniffi::export] +impl SenderEndpoint { + /// Create a new sender endpoint. + #[uniffi::constructor(async_runtime = "tokio")] + pub async fn new() -> SenderEndpoint { + // TODO: error handling + let endpoint = iroh::Endpoint::builder().bind().await.unwrap(); + SenderEndpoint { endpoint } + } +} -- 2.51.2 From ede88b2ae69ae151787cd9abad423ef07353b090 Mon Sep 17 00:00:00 2001 From: dignifiedquire Date: Tue, 5 Aug 2025 11:50:45 +0200 Subject: [PATCH 02/15] feat: flesh out sender endpoint --- Cargo.lock | 2 + Cargo.toml | 2 + Makefile | 1 + src/key.rs | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 18 ++------- src/sender.rs | 57 +++++++++++++++++++++++++++ src/utils.rs | 76 +++++++++++++++++++++++++++++++++++ 7 files changed, 249 insertions(+), 14 deletions(-) create mode 100644 src/key.rs create mode 100644 src/sender.rs create mode 100644 src/utils.rs diff --git a/Cargo.lock b/Cargo.lock index 02133d19..dc8f1c19 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1732,7 +1732,9 @@ name = "iroh-streamplace" version = "0.1.0" dependencies = [ "iroh", + "tokio", "uniffi", + "url", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index cb782292..d667ae05 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,5 +9,7 @@ crate-type = ["staticlib", "cdylib"] [dependencies] iroh = "0.91.1" +tokio = "1.47.1" uniffi = { version = "=0.28.3", features = ["tokio"] } +url = "2.5.4" diff --git a/Makefile b/Makefile index 593e0792..85c6a562 100644 --- a/Makefile +++ b/Makefile @@ -13,4 +13,5 @@ go: .PHONY: test test: + cargo test go test ./pkg/... diff --git a/src/key.rs b/src/key.rs new file mode 100644 index 00000000..b318a326 --- /dev/null +++ b/src/key.rs @@ -0,0 +1,107 @@ +use std::str::FromStr; + +/// A public key. +/// +/// The key itself is just a 32 byte array, but a key has associated crypto +/// information that is cached for performance reasons. +#[derive(Debug, Clone, Eq, uniffi::Object)] +#[uniffi::export(Display)] +pub struct PublicKey { + pub(crate) key: [u8; 32], +} + +impl From for PublicKey { + fn from(key: iroh::PublicKey) -> Self { + PublicKey { + key: *key.as_bytes(), + } + } +} +impl From<&PublicKey> for iroh::PublicKey { + fn from(key: &PublicKey) -> Self { + iroh::PublicKey::from_bytes(&key.key).unwrap() + } +} + +#[uniffi::export] +impl PublicKey { + /// Returns true if the PublicKeys are equal + pub fn equal(&self, other: &PublicKey) -> bool { + *self == *other + } + + /// Express the PublicKey as a byte array + pub fn to_bytes(&self) -> Vec { + self.key.to_vec() + } + + /// Make a PublicKey from base32 string + #[uniffi::constructor] + pub fn from_string(s: String) -> Self { + // TODO: error + let key = iroh::PublicKey::from_str(&s).unwrap(); + key.into() + } + + /// Make a PublicKey from byte array + #[uniffi::constructor] + pub fn from_bytes(bytes: Vec) -> Self { + if bytes.len() != 32 { + panic!("the PublicKey must be 32 bytes in length"); + } + let bytes: [u8; 32] = bytes.try_into().expect("checked above"); + let key = iroh::PublicKey::from_bytes(&bytes).unwrap(); + key.into() + } + + /// Convert to a base32 string limited to the first 10 bytes for a friendly string + /// representation of the key. + pub fn fmt_short(&self) -> String { + iroh::PublicKey::from(self).fmt_short() + } +} + +impl PartialEq for PublicKey { + fn eq(&self, other: &PublicKey) -> bool { + self.key == other.key + } +} + +impl std::fmt::Display for PublicKey { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + iroh::PublicKey::from(self).fmt(f) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_public_key() { + let key_str = + String::from("523c7996bad77424e96786cf7a7205115337a5b4565cd25506a0f297b191a5ea"); + let fmt_str = String::from("523c7996ba"); + let bytes = b"\x52\x3c\x79\x96\xba\xd7\x74\x24\xe9\x67\x86\xcf\x7a\x72\x05\x11\x53\x37\xa5\xb4\x56\x5c\xd2\x55\x06\xa0\xf2\x97\xb1\x91\xa5\xea"; + // + // create key from string + let key = PublicKey::from_string(key_str.clone()); + // + // test methods are as expected + assert_eq!(key_str, key.to_string()); + assert_eq!(bytes.to_vec(), key.to_bytes()); + assert_eq!(fmt_str, key.fmt_short()); + // + // create key from bytes + let key_0 = PublicKey::from_bytes(bytes.to_vec()); + // + // test methods are as expected + assert_eq!(key_str, key_0.to_string()); + assert_eq!(bytes.to_vec(), key_0.to_bytes()); + assert_eq!(fmt_str, key_0.fmt_short()); + // + // test that the eq function works + assert!(key.equal(&key_0)); + assert!(key_0.equal(&key)); + } +} diff --git a/src/lib.rs b/src/lib.rs index 471ce1bd..b0896a71 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,17 +1,7 @@ uniffi::setup_scaffolding!(); -#[derive(uniffi::Object)] -pub struct SenderEndpoint { - endpoint: iroh::Endpoint, -} +pub mod key; +pub mod sender; +pub mod utils; -#[uniffi::export] -impl SenderEndpoint { - /// Create a new sender endpoint. - #[uniffi::constructor(async_runtime = "tokio")] - pub async fn new() -> SenderEndpoint { - // TODO: error handling - let endpoint = iroh::Endpoint::builder().bind().await.unwrap(); - SenderEndpoint { endpoint } - } -} +const ALPN: &[u8] = b"/iroh/streamplace/1"; diff --git a/src/sender.rs b/src/sender.rs new file mode 100644 index 00000000..4d800b2d --- /dev/null +++ b/src/sender.rs @@ -0,0 +1,57 @@ +use std::collections::HashMap; + +use iroh::endpoint::Connection; +use iroh::{NodeId, Watcher}; +use tokio::sync::Mutex; + +use crate::ALPN; +use crate::key::PublicKey; +use crate::utils::NodeAddr; + +#[derive(uniffi::Object)] +pub struct SenderEndpoint { + endpoint: iroh::Endpoint, + connections: Mutex>, +} + +#[uniffi::export] +impl SenderEndpoint { + /// Create a new sender endpoint. + #[uniffi::constructor(async_runtime = "tokio")] + pub async fn new() -> SenderEndpoint { + // TODO: error handling + let endpoint = iroh::Endpoint::builder().bind().await.unwrap(); + SenderEndpoint { + endpoint, + connections: Default::default(), + } + } + + #[uniffi::method(async_runtime = "tokio")] + pub async fn add_peer(&self, addr: &NodeAddr) { + let addr: iroh::NodeAddr = addr.clone().try_into().unwrap(); + + let mut conns = self.connections.lock().await; + let node_id = addr.node_id; + if conns.contains_key(&node_id) { + return; + } + let conn = self.endpoint.connect(addr, ALPN).await.unwrap(); + conns.insert(node_id, conn); + } + + #[uniffi::method(async_runtime = "tokio")] + pub async fn send(&self, node_id: &PublicKey, data: &[u8]) { + let node_id: NodeId = node_id.into(); + let Some(conn) = self.connections.lock().await.get(&node_id).cloned() else { + panic!("no connection"); + }; + + todo!("send data"); + } + + pub fn node_addr(&self) -> NodeAddr { + let addr = self.endpoint.node_addr().get().unwrap(); + addr.into() + } +} diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 00000000..9ccaab2a --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,76 @@ +use std::str::FromStr; +use std::sync::Arc; + +use crate::key::PublicKey; + +/// A peer and it's addressing information. +#[derive(Debug, Clone, PartialEq, Eq, uniffi::Object)] +pub struct NodeAddr { + node_id: Arc, + relay_url: Option, + addresses: Vec, +} + +#[uniffi::export] +impl NodeAddr { + /// Create a new [`NodeAddr`] with empty [`AddrInfo`]. + #[uniffi::constructor] + pub fn new(node_id: &PublicKey, derp_url: Option, addresses: Vec) -> Self { + Self { + node_id: Arc::new(node_id.clone()), + relay_url: derp_url, + addresses, + } + } + + /// Get the direct addresses of this peer. + pub fn direct_addresses(&self) -> Vec { + self.addresses.clone() + } + + /// Get the home relay URL for this peer + pub fn relay_url(&self) -> Option { + self.relay_url.clone() + } + + /// Returns true if both NodeAddr's have the same values + pub fn equal(&self, other: &NodeAddr) -> bool { + self == other + } +} + +impl TryFrom for iroh::NodeAddr { + type Error = (); + + fn try_from(value: NodeAddr) -> Result { + let mut node_addr = iroh::NodeAddr::new((&*value.node_id).into()); + let addresses = value + .direct_addresses() + .into_iter() + .map(|addr| std::net::SocketAddr::from_str(&addr)) + .collect::, _>>() + .map_err(|_| ())?; + + if let Some(derp_url) = value.relay_url() { + let url = url::Url::parse(&derp_url).map_err(|_| ())?; + + node_addr = node_addr.with_relay_url(url.into()); + } + node_addr = node_addr.with_direct_addresses(addresses); + Ok(node_addr) + } +} + +impl From for NodeAddr { + fn from(value: iroh::NodeAddr) -> Self { + NodeAddr { + node_id: Arc::new(value.node_id.into()), + relay_url: value.relay_url.map(|url| url.to_string()), + addresses: value + .direct_addresses + .into_iter() + .map(|d| d.to_string()) + .collect(), + } + } +} -- 2.51.2 From fe96e29a4a7cf11811ed985cb3c654717bf8e76e Mon Sep 17 00:00:00 2001 From: dignifiedquire Date: Tue, 5 Aug 2025 12:45:33 +0200 Subject: [PATCH 03/15] feat: implement basic send and recv --- Cargo.lock | 48 +++++++++++++++++-- Cargo.toml | 4 ++ src/lib.rs | 1 + src/receiver.rs | 120 ++++++++++++++++++++++++++++++++++++++++++++++++ src/sender.rs | 15 ++++-- src/utils.rs | 4 ++ 6 files changed, 183 insertions(+), 9 deletions(-) create mode 100644 src/receiver.rs diff --git a/Cargo.lock b/Cargo.lock index dc8f1c19..fa749a98 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1448,6 +1448,21 @@ dependencies = [ "xmltree", ] +[[package]] +name = "imsg" +version = "0.1.0" +source = "git+https://github.com/n0-computer/imsg?branch=main#9165b1c6d6bc27ea324a01b1090fb7f269f05dc2" +dependencies = [ + "anyhow", + "bytes", + "iroh", + "n0-future 0.2.0", + "thiserror 2.0.12", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "indexmap" version = "2.10.0" @@ -1546,7 +1561,7 @@ dependencies = [ "iroh-quinn-proto", "iroh-quinn-udp", "iroh-relay", - "n0-future", + "n0-future 0.1.3", "n0-snafu", "n0-watcher", "nested_enum_utils", @@ -1699,7 +1714,7 @@ dependencies = [ "iroh-quinn", "iroh-quinn-proto", "lru", - "n0-future", + "n0-future 0.1.3", "n0-snafu", "nested_enum_utils", "num_enum", @@ -1731,7 +1746,11 @@ dependencies = [ name = "iroh-streamplace" version = "0.1.0" dependencies = [ + "async-trait", + "bytes", + "imsg", "iroh", + "n0-future 0.2.0", "tokio", "uniffi", "url", @@ -1924,6 +1943,27 @@ dependencies = [ "web-time", ] +[[package]] +name = "n0-future" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89d7dd42bd0114c9daa9c4f2255d692a73bba45767ec32cf62892af6fe5d31f6" +dependencies = [ + "cfg_aliases", + "derive_more 1.0.0", + "futures-buffered", + "futures-lite", + "futures-util", + "js-sys", + "pin-project", + "send_wrapper", + "tokio", + "tokio-util", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-time", +] + [[package]] name = "n0-snafu" version = "0.2.1" @@ -1944,7 +1984,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c31462392a10d5ada4b945e840cbec2d5f3fee752b96c4b33eb41414d8f45c2a" dependencies = [ "derive_more 1.0.0", - "n0-future", + "n0-future 0.1.3", "snafu", ] @@ -2070,7 +2110,7 @@ dependencies = [ "iroh-quinn-udp", "js-sys", "libc", - "n0-future", + "n0-future 0.1.3", "n0-watcher", "nested_enum_utils", "netdev", diff --git a/Cargo.toml b/Cargo.toml index d667ae05..2da0c2c9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,11 @@ crate-type = ["staticlib", "cdylib"] [dependencies] iroh = "0.91.1" +imsg = { git = "https://github.com/n0-computer/imsg", branch = "main" } tokio = "1.47.1" uniffi = { version = "=0.28.3", features = ["tokio"] } url = "2.5.4" +bytes = "1.10.1" +n0-future = "0.2.0" +async-trait = "0.1.88" diff --git a/src/lib.rs b/src/lib.rs index b0896a71..a124d0c1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,7 @@ uniffi::setup_scaffolding!(); pub mod key; +pub mod receiver; pub mod sender; pub mod utils; diff --git a/src/receiver.rs b/src/receiver.rs new file mode 100644 index 00000000..23038b21 --- /dev/null +++ b/src/receiver.rs @@ -0,0 +1,120 @@ +use std::sync::Arc; + +use iroh::Watcher; +use n0_future::task::{self, AbortOnDropHandle}; +use tokio::task::JoinSet; + +use crate::ALPN; +use crate::key::PublicKey; +use crate::utils::NodeAddr; + +#[derive(uniffi::Object)] +pub struct ReceiverEndpoint { + endpoint: iroh::Endpoint, + _handle: AbortOnDropHandle<()>, +} + +#[uniffi::export] +impl ReceiverEndpoint { + /// Create a new receiver endpoint. + #[uniffi::constructor(async_runtime = "tokio")] + pub async fn new(handler: Arc) -> ReceiverEndpoint { + // TODO: error handling + let endpoint = iroh::Endpoint::builder() + .alpns(vec![ALPN.to_vec()]) + .bind() + .await + .unwrap(); + + let ep = endpoint.clone(); + let handle = task::spawn(async move { + let mut tasks = JoinSet::default(); + + while let Some(incoming) = ep.accept().await { + let handler = handler.clone(); + tasks.spawn(async move { + let Ok(conn) = incoming.await else { + return; + }; + let peer: PublicKey = conn.remote_node_id().unwrap().into(); + let conn = imsg::Connection::new(conn).await.unwrap(); + + while let Ok(stream) = conn.accept_stream().await { + if let Ok(msg) = stream.recv_msg().await { + handler.clone().handle_data(&peer, msg.to_vec()).await; + } + } + }); + } + + // cleanup + tasks.abort_all(); + }); + + ReceiverEndpoint { + endpoint, + _handle: AbortOnDropHandle::new(handle), + } + } + + #[uniffi::method(async_runtime = "tokio")] + pub async fn node_addr(&self) -> NodeAddr { + let addr = self.endpoint.node_addr().initialized().await; + addr.into() + } +} + +#[uniffi::export] +#[async_trait::async_trait] +pub trait DataHandler: Send + Sync { + async fn handle_data(self: Arc, peer: &PublicKey, data: Vec); +} + +#[cfg(test)] +mod tests { + + use crate::sender::SenderEndpoint; + + use super::*; + + #[tokio::test] + async fn test_roundtrip() { + let sender = SenderEndpoint::new().await; + + let (s, mut r) = tokio::sync::mpsc::channel(5); + + #[derive(Debug, Clone)] + struct TestHandler { + messages: tokio::sync::mpsc::Sender<(PublicKey, Vec)>, + } + + #[async_trait::async_trait] + impl DataHandler for TestHandler { + async fn handle_data(self: Arc, peer: &PublicKey, data: Vec) { + self.messages.send((peer.clone(), data)).await.unwrap(); + } + } + + let handler = TestHandler { messages: s }; + let receiver = ReceiverEndpoint::new(Arc::new(handler.clone())).await; + + let receiver_addr = receiver.node_addr().await; + let receiver_id = receiver_addr.node_id(); + + // add peer + sender.add_peer(&receiver_addr).await; + + // send a few messages + for i in 0u8..5 { + sender.send(&receiver_id, &[i, 0, 0, 0]).await; + } + + // make sure the receiver got them + let sender_id = sender.node_addr().await.node_id(); + for i in 0u8..5 { + let (id, msg) = r.recv().await.unwrap(); + assert_eq!(id, sender_id); + assert_eq!(msg, vec![i, 0, 0, 0]); + } + } +} diff --git a/src/sender.rs b/src/sender.rs index 4d800b2d..88c6c222 100644 --- a/src/sender.rs +++ b/src/sender.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use iroh::endpoint::Connection; +use bytes::Bytes; use iroh::{NodeId, Watcher}; use tokio::sync::Mutex; @@ -11,7 +11,7 @@ use crate::utils::NodeAddr; #[derive(uniffi::Object)] pub struct SenderEndpoint { endpoint: iroh::Endpoint, - connections: Mutex>, + connections: Mutex>, } #[uniffi::export] @@ -37,6 +37,7 @@ impl SenderEndpoint { return; } let conn = self.endpoint.connect(addr, ALPN).await.unwrap(); + let conn = imsg::Connection::new(conn).await.unwrap(); conns.insert(node_id, conn); } @@ -47,11 +48,15 @@ impl SenderEndpoint { panic!("no connection"); }; - todo!("send data"); + // TODO: store streams + let stream = conn.open_stream().await.unwrap(); + let data = Bytes::copy_from_slice(data); + stream.send_msg(data).await.unwrap(); } - pub fn node_addr(&self) -> NodeAddr { - let addr = self.endpoint.node_addr().get().unwrap(); + #[uniffi::method(async_runtime = "tokio")] + pub async fn node_addr(&self) -> NodeAddr { + let addr = self.endpoint.node_addr().initialized().await; addr.into() } } diff --git a/src/utils.rs b/src/utils.rs index 9ccaab2a..f683235a 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -23,6 +23,10 @@ impl NodeAddr { } } + pub fn node_id(&self) -> PublicKey { + self.node_id.as_ref().clone() + } + /// Get the direct addresses of this peer. pub fn direct_addresses(&self) -> Vec { self.addresses.clone() -- 2.51.2 From adbf12cc90b301ee8c579c12219cf5e444408169 Mon Sep 17 00:00:00 2001 From: dignifiedquire Date: Tue, 5 Aug 2025 13:12:46 +0200 Subject: [PATCH 04/15] feat: basic go send and receive test is passing --- go.mod | 7 + go.sum | 9 + .../iroh_streamplace/iroh_streamplace.go | 931 ++++++++++++++++++ .../iroh_streamplace/iroh_streamplace.h | 250 +++++ pkg/iroh_streamplace/iroh_streamplace.go | 7 +- pkg/iroh_streamplace/iroh_streamplace_test.go | 38 +- src/receiver.rs | 18 +- 7 files changed, 1246 insertions(+), 14 deletions(-) create mode 100644 go.sum diff --git a/go.mod b/go.mod index 0cffb986..36c3a073 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,10 @@ module github.com/n0-computer/iroh-streamplace go 1.22.2 + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/stretchr/testify v1.10.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 00000000..fe99d711 --- /dev/null +++ b/go.sum @@ -0,0 +1,9 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pkg/iroh_streamplace/generated/iroh_streamplace/iroh_streamplace.go b/pkg/iroh_streamplace/generated/iroh_streamplace/iroh_streamplace.go index 8b0bbf13..d661ff46 100644 --- a/pkg/iroh_streamplace/generated/iroh_streamplace/iroh_streamplace.go +++ b/pkg/iroh_streamplace/generated/iroh_streamplace/iroh_streamplace.go @@ -11,6 +11,7 @@ import ( "math" "runtime" "runtime/cgo" + "sync" "sync/atomic" "unsafe" ) @@ -333,6 +334,7 @@ func readFloat64(reader io.Reader) float64 { func init() { + FfiConverterDataHandlerINSTANCE.register() uniffiCheckChecksums() } @@ -347,6 +349,150 @@ func uniffiCheckChecksums() { // If this happens try cleaning and rebuilding your project panic("iroh_streamplace: UniFFI contract version mismatch") } + { + checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_iroh_streamplace_checksum_method_datahandler_handle_data() + }) + if checksum != 61779 { + // If this happens try cleaning and rebuilding your project + panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_method_datahandler_handle_data: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_iroh_streamplace_checksum_method_nodeaddr_direct_addresses() + }) + if checksum != 17536 { + // If this happens try cleaning and rebuilding your project + panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_method_nodeaddr_direct_addresses: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_iroh_streamplace_checksum_method_nodeaddr_equal() + }) + if checksum != 15520 { + // If this happens try cleaning and rebuilding your project + panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_method_nodeaddr_equal: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_iroh_streamplace_checksum_method_nodeaddr_node_id() + }) + if checksum != 35476 { + // If this happens try cleaning and rebuilding your project + panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_method_nodeaddr_node_id: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_iroh_streamplace_checksum_method_nodeaddr_relay_url() + }) + if checksum != 18967 { + // If this happens try cleaning and rebuilding your project + panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_method_nodeaddr_relay_url: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_iroh_streamplace_checksum_method_publickey_equal() + }) + if checksum != 25030 { + // If this happens try cleaning and rebuilding your project + panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_method_publickey_equal: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_iroh_streamplace_checksum_method_publickey_fmt_short() + }) + if checksum != 57639 { + // If this happens try cleaning and rebuilding your project + panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_method_publickey_fmt_short: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_iroh_streamplace_checksum_method_publickey_to_bytes() + }) + if checksum != 8223 { + // If this happens try cleaning and rebuilding your project + panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_method_publickey_to_bytes: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_iroh_streamplace_checksum_method_receiverendpoint_node_addr() + }) + if checksum != 2125 { + // If this happens try cleaning and rebuilding your project + panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_method_receiverendpoint_node_addr: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_iroh_streamplace_checksum_method_senderendpoint_add_peer() + }) + if checksum != 63624 { + // If this happens try cleaning and rebuilding your project + panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_method_senderendpoint_add_peer: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_iroh_streamplace_checksum_method_senderendpoint_node_addr() + }) + if checksum != 56355 { + // If this happens try cleaning and rebuilding your project + panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_method_senderendpoint_node_addr: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_iroh_streamplace_checksum_method_senderendpoint_send() + }) + if checksum != 21989 { + // If this happens try cleaning and rebuilding your project + panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_method_senderendpoint_send: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_iroh_streamplace_checksum_constructor_nodeaddr_new() + }) + if checksum != 28044 { + // If this happens try cleaning and rebuilding your project + panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_constructor_nodeaddr_new: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_iroh_streamplace_checksum_constructor_publickey_from_bytes() + }) + if checksum != 51762 { + // If this happens try cleaning and rebuilding your project + panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_constructor_publickey_from_bytes: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_iroh_streamplace_checksum_constructor_publickey_from_string() + }) + if checksum != 2826 { + // If this happens try cleaning and rebuilding your project + panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_constructor_publickey_from_string: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_iroh_streamplace_checksum_constructor_receiverendpoint_new() + }) + if checksum != 30890 { + // If this happens try cleaning and rebuilding your project + panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_constructor_receiverendpoint_new: UniFFI API checksum mismatch") + } + } { checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { return C.uniffi_iroh_streamplace_checksum_constructor_senderendpoint_new() @@ -358,6 +504,37 @@ func uniffiCheckChecksums() { } } +type FfiConverterBool struct{} + +var FfiConverterBoolINSTANCE = FfiConverterBool{} + +func (FfiConverterBool) Lower(value bool) C.int8_t { + if value { + return C.int8_t(1) + } + return C.int8_t(0) +} + +func (FfiConverterBool) Write(writer io.Writer, value bool) { + if value { + writeInt8(writer, 1) + } else { + writeInt8(writer, 0) + } +} + +func (FfiConverterBool) Lift(value C.int8_t) bool { + return value != 0 +} + +func (FfiConverterBool) Read(reader io.Reader) bool { + return readInt8(reader) != 0 +} + +type FfiDestroyerBool struct{} + +func (FfiDestroyerBool) Destroy(_ bool) {} + type FfiConverterString struct{} var FfiConverterStringINSTANCE = FfiConverterString{} @@ -408,6 +585,50 @@ type FfiDestroyerString struct{} func (FfiDestroyerString) Destroy(_ string) {} +type FfiConverterBytes struct{} + +var FfiConverterBytesINSTANCE = FfiConverterBytes{} + +func (c FfiConverterBytes) Lower(value []byte) C.RustBuffer { + return LowerIntoRustBuffer[[]byte](c, value) +} + +func (c FfiConverterBytes) Write(writer io.Writer, value []byte) { + if len(value) > math.MaxInt32 { + panic("[]byte is too large to fit into Int32") + } + + writeInt32(writer, int32(len(value))) + write_length, err := writer.Write(value) + if err != nil { + panic(err) + } + if write_length != len(value) { + panic(fmt.Errorf("bad write length when writing []byte, expected %d, written %d", len(value), write_length)) + } +} + +func (c FfiConverterBytes) Lift(rb RustBufferI) []byte { + return LiftFromRustBuffer[[]byte](c, rb) +} + +func (c FfiConverterBytes) Read(reader io.Reader) []byte { + length := readInt32(reader) + buffer := make([]byte, length) + read_length, err := reader.Read(buffer) + if err != nil { + panic(err) + } + if read_length != int(length) { + panic(fmt.Errorf("bad read length when reading []byte, expected %d, read %d", length, read_length)) + } + return buffer +} + +type FfiDestroyerBytes struct{} + +func (FfiDestroyerBytes) Destroy(_ []byte) {} + // Below is an implementation of synchronization requirements outlined in the link. // https://github.com/mozilla/uniffi-rs/blob/0dc031132d9493ca812c3af6e7dd60ad2ea95bf0/uniffi_bindgen/src/bindings/kotlin/templates/ObjectRuntime.kt#L31 @@ -471,7 +692,557 @@ func (ffiObject *FfiObject) freeRustArcPtr() { }) } +type DataHandler interface { + HandleData(peer *PublicKey, data []byte) +} +type DataHandlerImpl struct { + ffiObject FfiObject +} + +func (_self *DataHandlerImpl) HandleData(peer *PublicKey, data []byte) { + _pointer := _self.ffiObject.incrementPointer("DataHandler") + defer _self.ffiObject.decrementPointer() + uniffiRustCallAsync[struct{}]( + nil, + // completeFn + func(handle C.uint64_t, status *C.RustCallStatus) struct{} { + C.ffi_iroh_streamplace_rust_future_complete_void(handle, status) + return struct{}{} + }, + // liftFn + func(_ struct{}) struct{} { return struct{}{} }, + C.uniffi_iroh_streamplace_fn_method_datahandler_handle_data( + _pointer, FfiConverterPublicKeyINSTANCE.Lower(peer), FfiConverterBytesINSTANCE.Lower(data)), + // pollFn + func(handle C.uint64_t, continuation C.UniffiRustFutureContinuationCallback, data C.uint64_t) { + C.ffi_iroh_streamplace_rust_future_poll_void(handle, continuation, data) + }, + // freeFn + func(handle C.uint64_t) { + C.ffi_iroh_streamplace_rust_future_free_void(handle) + }, + ) + +} +func (object *DataHandlerImpl) Destroy() { + runtime.SetFinalizer(object, nil) + object.ffiObject.destroy() +} + +type FfiConverterDataHandler struct { + handleMap *concurrentHandleMap[DataHandler] +} + +var FfiConverterDataHandlerINSTANCE = FfiConverterDataHandler{ + handleMap: newConcurrentHandleMap[DataHandler](), +} + +func (c FfiConverterDataHandler) Lift(pointer unsafe.Pointer) DataHandler { + result := &DataHandlerImpl{ + newFfiObject( + pointer, + func(pointer unsafe.Pointer, status *C.RustCallStatus) unsafe.Pointer { + return C.uniffi_iroh_streamplace_fn_clone_datahandler(pointer, status) + }, + func(pointer unsafe.Pointer, status *C.RustCallStatus) { + C.uniffi_iroh_streamplace_fn_free_datahandler(pointer, status) + }, + ), + } + runtime.SetFinalizer(result, (*DataHandlerImpl).Destroy) + return result +} + +func (c FfiConverterDataHandler) Read(reader io.Reader) DataHandler { + return c.Lift(unsafe.Pointer(uintptr(readUint64(reader)))) +} + +func (c FfiConverterDataHandler) Lower(value DataHandler) unsafe.Pointer { + // TODO: this is bad - all synchronization from ObjectRuntime.go is discarded here, + // because the pointer will be decremented immediately after this function returns, + // and someone will be left holding onto a non-locked pointer. + pointer := unsafe.Pointer(uintptr(c.handleMap.insert(value))) + return pointer + +} + +func (c FfiConverterDataHandler) Write(writer io.Writer, value DataHandler) { + writeUint64(writer, uint64(uintptr(c.Lower(value)))) +} + +type FfiDestroyerDataHandler struct{} + +func (_ FfiDestroyerDataHandler) Destroy(value DataHandler) { + if val, ok := value.(*DataHandlerImpl); ok { + val.Destroy() + } else { + panic("Expected *DataHandlerImpl") + } +} + +type uniffiCallbackResult C.int8_t + +const ( + uniffiIdxCallbackFree uniffiCallbackResult = 0 + uniffiCallbackResultSuccess uniffiCallbackResult = 0 + uniffiCallbackResultError uniffiCallbackResult = 1 + uniffiCallbackUnexpectedResultError uniffiCallbackResult = 2 + uniffiCallbackCancelled uniffiCallbackResult = 3 +) + +type concurrentHandleMap[T any] struct { + handles map[uint64]T + currentHandle uint64 + lock sync.RWMutex +} + +func newConcurrentHandleMap[T any]() *concurrentHandleMap[T] { + return &concurrentHandleMap[T]{ + handles: map[uint64]T{}, + } +} + +func (cm *concurrentHandleMap[T]) insert(obj T) uint64 { + cm.lock.Lock() + defer cm.lock.Unlock() + + cm.currentHandle = cm.currentHandle + 1 + cm.handles[cm.currentHandle] = obj + return cm.currentHandle +} + +func (cm *concurrentHandleMap[T]) remove(handle uint64) { + cm.lock.Lock() + defer cm.lock.Unlock() + + delete(cm.handles, handle) +} + +func (cm *concurrentHandleMap[T]) tryGet(handle uint64) (T, bool) { + cm.lock.RLock() + defer cm.lock.RUnlock() + + val, ok := cm.handles[handle] + return val, ok +} + +//export iroh_streamplace_cgo_dispatchCallbackInterfaceDataHandlerMethod0 +func iroh_streamplace_cgo_dispatchCallbackInterfaceDataHandlerMethod0(uniffiHandle C.uint64_t, peer unsafe.Pointer, data C.RustBuffer, uniffiFutureCallback C.UniffiForeignFutureCompleteVoid, uniffiCallbackData C.uint64_t, uniffiOutReturn *C.UniffiForeignFuture) { + handle := uint64(uniffiHandle) + uniffiObj, ok := FfiConverterDataHandlerINSTANCE.handleMap.tryGet(handle) + if !ok { + panic(fmt.Errorf("no callback in handle map: %d", handle)) + } + + result := make(chan C.UniffiForeignFutureStructVoid, 1) + cancel := make(chan struct{}, 1) + guardHandle := cgo.NewHandle(cancel) + *uniffiOutReturn = C.UniffiForeignFuture{ + handle: C.uint64_t(guardHandle), + free: C.UniffiForeignFutureFree(C.iroh_streamplace_uniffiFreeGorutine), + } + + // Wait for compleation or cancel + go func() { + select { + case <-cancel: + case res := <-result: + C.call_UniffiForeignFutureCompleteVoid(uniffiFutureCallback, uniffiCallbackData, res) + } + }() + + // Eval callback asynchroniously + go func() { + asyncResult := &C.UniffiForeignFutureStructVoid{} + defer func() { + result <- *asyncResult + }() + + uniffiObj.HandleData( + FfiConverterPublicKeyINSTANCE.Lift(peer), + FfiConverterBytesINSTANCE.Lift(GoRustBuffer{ + inner: data, + }), + ) + + }() +} + +var UniffiVTableCallbackInterfaceDataHandlerINSTANCE = C.UniffiVTableCallbackInterfaceDataHandler{ + handleData: (C.UniffiCallbackInterfaceDataHandlerMethod0)(C.iroh_streamplace_cgo_dispatchCallbackInterfaceDataHandlerMethod0), + + uniffiFree: (C.UniffiCallbackInterfaceFree)(C.iroh_streamplace_cgo_dispatchCallbackInterfaceDataHandlerFree), +} + +//export iroh_streamplace_cgo_dispatchCallbackInterfaceDataHandlerFree +func iroh_streamplace_cgo_dispatchCallbackInterfaceDataHandlerFree(handle C.uint64_t) { + FfiConverterDataHandlerINSTANCE.handleMap.remove(uint64(handle)) +} + +func (c FfiConverterDataHandler) register() { + C.uniffi_iroh_streamplace_fn_init_callback_vtable_datahandler(&UniffiVTableCallbackInterfaceDataHandlerINSTANCE) +} + +// A peer and it's addressing information. +type NodeAddrInterface interface { + // Get the direct addresses of this peer. + DirectAddresses() []string + // Returns true if both NodeAddr's have the same values + Equal(other *NodeAddr) bool + NodeId() *PublicKey + // Get the home relay URL for this peer + RelayUrl() *string +} + +// A peer and it's addressing information. +type NodeAddr struct { + ffiObject FfiObject +} + +// Create a new [`NodeAddr`] with empty [`AddrInfo`]. +func NewNodeAddr(nodeId *PublicKey, derpUrl *string, addresses []string) *NodeAddr { + return FfiConverterNodeAddrINSTANCE.Lift(rustCall(func(_uniffiStatus *C.RustCallStatus) unsafe.Pointer { + return C.uniffi_iroh_streamplace_fn_constructor_nodeaddr_new(FfiConverterPublicKeyINSTANCE.Lower(nodeId), FfiConverterOptionalStringINSTANCE.Lower(derpUrl), FfiConverterSequenceStringINSTANCE.Lower(addresses), _uniffiStatus) + })) +} + +// Get the direct addresses of this peer. +func (_self *NodeAddr) DirectAddresses() []string { + _pointer := _self.ffiObject.incrementPointer("*NodeAddr") + defer _self.ffiObject.decrementPointer() + return FfiConverterSequenceStringINSTANCE.Lift(rustCall(func(_uniffiStatus *C.RustCallStatus) RustBufferI { + return GoRustBuffer{ + inner: C.uniffi_iroh_streamplace_fn_method_nodeaddr_direct_addresses( + _pointer, _uniffiStatus), + } + })) +} + +// Returns true if both NodeAddr's have the same values +func (_self *NodeAddr) Equal(other *NodeAddr) bool { + _pointer := _self.ffiObject.incrementPointer("*NodeAddr") + defer _self.ffiObject.decrementPointer() + return FfiConverterBoolINSTANCE.Lift(rustCall(func(_uniffiStatus *C.RustCallStatus) C.int8_t { + return C.uniffi_iroh_streamplace_fn_method_nodeaddr_equal( + _pointer, FfiConverterNodeAddrINSTANCE.Lower(other), _uniffiStatus) + })) +} + +func (_self *NodeAddr) NodeId() *PublicKey { + _pointer := _self.ffiObject.incrementPointer("*NodeAddr") + defer _self.ffiObject.decrementPointer() + return FfiConverterPublicKeyINSTANCE.Lift(rustCall(func(_uniffiStatus *C.RustCallStatus) unsafe.Pointer { + return C.uniffi_iroh_streamplace_fn_method_nodeaddr_node_id( + _pointer, _uniffiStatus) + })) +} + +// Get the home relay URL for this peer +func (_self *NodeAddr) RelayUrl() *string { + _pointer := _self.ffiObject.incrementPointer("*NodeAddr") + defer _self.ffiObject.decrementPointer() + return FfiConverterOptionalStringINSTANCE.Lift(rustCall(func(_uniffiStatus *C.RustCallStatus) RustBufferI { + return GoRustBuffer{ + inner: C.uniffi_iroh_streamplace_fn_method_nodeaddr_relay_url( + _pointer, _uniffiStatus), + } + })) +} +func (object *NodeAddr) Destroy() { + runtime.SetFinalizer(object, nil) + object.ffiObject.destroy() +} + +type FfiConverterNodeAddr struct{} + +var FfiConverterNodeAddrINSTANCE = FfiConverterNodeAddr{} + +func (c FfiConverterNodeAddr) Lift(pointer unsafe.Pointer) *NodeAddr { + result := &NodeAddr{ + newFfiObject( + pointer, + func(pointer unsafe.Pointer, status *C.RustCallStatus) unsafe.Pointer { + return C.uniffi_iroh_streamplace_fn_clone_nodeaddr(pointer, status) + }, + func(pointer unsafe.Pointer, status *C.RustCallStatus) { + C.uniffi_iroh_streamplace_fn_free_nodeaddr(pointer, status) + }, + ), + } + runtime.SetFinalizer(result, (*NodeAddr).Destroy) + return result +} + +func (c FfiConverterNodeAddr) Read(reader io.Reader) *NodeAddr { + return c.Lift(unsafe.Pointer(uintptr(readUint64(reader)))) +} + +func (c FfiConverterNodeAddr) Lower(value *NodeAddr) unsafe.Pointer { + // TODO: this is bad - all synchronization from ObjectRuntime.go is discarded here, + // because the pointer will be decremented immediately after this function returns, + // and someone will be left holding onto a non-locked pointer. + pointer := value.ffiObject.incrementPointer("*NodeAddr") + defer value.ffiObject.decrementPointer() + return pointer + +} + +func (c FfiConverterNodeAddr) Write(writer io.Writer, value *NodeAddr) { + writeUint64(writer, uint64(uintptr(c.Lower(value)))) +} + +type FfiDestroyerNodeAddr struct{} + +func (_ FfiDestroyerNodeAddr) Destroy(value *NodeAddr) { + value.Destroy() +} + +// A public key. +// +// The key itself is just a 32 byte array, but a key has associated crypto +// information that is cached for performance reasons. +type PublicKeyInterface interface { + // Returns true if the PublicKeys are equal + Equal(other *PublicKey) bool + // Convert to a base32 string limited to the first 10 bytes for a friendly string + // representation of the key. + FmtShort() string + // Express the PublicKey as a byte array + ToBytes() []byte +} + +// A public key. +// +// The key itself is just a 32 byte array, but a key has associated crypto +// information that is cached for performance reasons. +type PublicKey struct { + ffiObject FfiObject +} + +// Make a PublicKey from byte array +func PublicKeyFromBytes(bytes []byte) *PublicKey { + return FfiConverterPublicKeyINSTANCE.Lift(rustCall(func(_uniffiStatus *C.RustCallStatus) unsafe.Pointer { + return C.uniffi_iroh_streamplace_fn_constructor_publickey_from_bytes(FfiConverterBytesINSTANCE.Lower(bytes), _uniffiStatus) + })) +} + +// Make a PublicKey from base32 string +func PublicKeyFromString(s string) *PublicKey { + return FfiConverterPublicKeyINSTANCE.Lift(rustCall(func(_uniffiStatus *C.RustCallStatus) unsafe.Pointer { + return C.uniffi_iroh_streamplace_fn_constructor_publickey_from_string(FfiConverterStringINSTANCE.Lower(s), _uniffiStatus) + })) +} + +// Returns true if the PublicKeys are equal +func (_self *PublicKey) Equal(other *PublicKey) bool { + _pointer := _self.ffiObject.incrementPointer("*PublicKey") + defer _self.ffiObject.decrementPointer() + return FfiConverterBoolINSTANCE.Lift(rustCall(func(_uniffiStatus *C.RustCallStatus) C.int8_t { + return C.uniffi_iroh_streamplace_fn_method_publickey_equal( + _pointer, FfiConverterPublicKeyINSTANCE.Lower(other), _uniffiStatus) + })) +} + +// Convert to a base32 string limited to the first 10 bytes for a friendly string +// representation of the key. +func (_self *PublicKey) FmtShort() string { + _pointer := _self.ffiObject.incrementPointer("*PublicKey") + defer _self.ffiObject.decrementPointer() + return FfiConverterStringINSTANCE.Lift(rustCall(func(_uniffiStatus *C.RustCallStatus) RustBufferI { + return GoRustBuffer{ + inner: C.uniffi_iroh_streamplace_fn_method_publickey_fmt_short( + _pointer, _uniffiStatus), + } + })) +} + +// Express the PublicKey as a byte array +func (_self *PublicKey) ToBytes() []byte { + _pointer := _self.ffiObject.incrementPointer("*PublicKey") + defer _self.ffiObject.decrementPointer() + return FfiConverterBytesINSTANCE.Lift(rustCall(func(_uniffiStatus *C.RustCallStatus) RustBufferI { + return GoRustBuffer{ + inner: C.uniffi_iroh_streamplace_fn_method_publickey_to_bytes( + _pointer, _uniffiStatus), + } + })) +} + +func (_self *PublicKey) String() string { + _pointer := _self.ffiObject.incrementPointer("*PublicKey") + defer _self.ffiObject.decrementPointer() + return FfiConverterStringINSTANCE.Lift(rustCall(func(_uniffiStatus *C.RustCallStatus) RustBufferI { + return GoRustBuffer{ + inner: C.uniffi_iroh_streamplace_fn_method_publickey_uniffi_trait_display( + _pointer, _uniffiStatus), + } + })) +} + +func (object *PublicKey) Destroy() { + runtime.SetFinalizer(object, nil) + object.ffiObject.destroy() +} + +type FfiConverterPublicKey struct{} + +var FfiConverterPublicKeyINSTANCE = FfiConverterPublicKey{} + +func (c FfiConverterPublicKey) Lift(pointer unsafe.Pointer) *PublicKey { + result := &PublicKey{ + newFfiObject( + pointer, + func(pointer unsafe.Pointer, status *C.RustCallStatus) unsafe.Pointer { + return C.uniffi_iroh_streamplace_fn_clone_publickey(pointer, status) + }, + func(pointer unsafe.Pointer, status *C.RustCallStatus) { + C.uniffi_iroh_streamplace_fn_free_publickey(pointer, status) + }, + ), + } + runtime.SetFinalizer(result, (*PublicKey).Destroy) + return result +} + +func (c FfiConverterPublicKey) Read(reader io.Reader) *PublicKey { + return c.Lift(unsafe.Pointer(uintptr(readUint64(reader)))) +} + +func (c FfiConverterPublicKey) Lower(value *PublicKey) unsafe.Pointer { + // TODO: this is bad - all synchronization from ObjectRuntime.go is discarded here, + // because the pointer will be decremented immediately after this function returns, + // and someone will be left holding onto a non-locked pointer. + pointer := value.ffiObject.incrementPointer("*PublicKey") + defer value.ffiObject.decrementPointer() + return pointer + +} + +func (c FfiConverterPublicKey) Write(writer io.Writer, value *PublicKey) { + writeUint64(writer, uint64(uintptr(c.Lower(value)))) +} + +type FfiDestroyerPublicKey struct{} + +func (_ FfiDestroyerPublicKey) Destroy(value *PublicKey) { + value.Destroy() +} + +type ReceiverEndpointInterface interface { + NodeAddr() *NodeAddr +} +type ReceiverEndpoint struct { + ffiObject FfiObject +} + +// Create a new receiver endpoint. +func NewReceiverEndpoint(handler DataHandler) *ReceiverEndpoint { + res, _ := uniffiRustCallAsync[struct{}]( + nil, + // completeFn + func(handle C.uint64_t, status *C.RustCallStatus) unsafe.Pointer { + res := C.ffi_iroh_streamplace_rust_future_complete_pointer(handle, status) + return res + }, + // liftFn + func(ffi unsafe.Pointer) *ReceiverEndpoint { + return FfiConverterReceiverEndpointINSTANCE.Lift(ffi) + }, + C.uniffi_iroh_streamplace_fn_constructor_receiverendpoint_new(FfiConverterDataHandlerINSTANCE.Lower(handler)), + // pollFn + func(handle C.uint64_t, continuation C.UniffiRustFutureContinuationCallback, data C.uint64_t) { + C.ffi_iroh_streamplace_rust_future_poll_pointer(handle, continuation, data) + }, + // freeFn + func(handle C.uint64_t) { + C.ffi_iroh_streamplace_rust_future_free_pointer(handle) + }, + ) + + return res +} + +func (_self *ReceiverEndpoint) NodeAddr() *NodeAddr { + _pointer := _self.ffiObject.incrementPointer("*ReceiverEndpoint") + defer _self.ffiObject.decrementPointer() + res, _ := uniffiRustCallAsync[struct{}]( + nil, + // completeFn + func(handle C.uint64_t, status *C.RustCallStatus) unsafe.Pointer { + res := C.ffi_iroh_streamplace_rust_future_complete_pointer(handle, status) + return res + }, + // liftFn + func(ffi unsafe.Pointer) *NodeAddr { + return FfiConverterNodeAddrINSTANCE.Lift(ffi) + }, + C.uniffi_iroh_streamplace_fn_method_receiverendpoint_node_addr( + _pointer), + // pollFn + func(handle C.uint64_t, continuation C.UniffiRustFutureContinuationCallback, data C.uint64_t) { + C.ffi_iroh_streamplace_rust_future_poll_pointer(handle, continuation, data) + }, + // freeFn + func(handle C.uint64_t) { + C.ffi_iroh_streamplace_rust_future_free_pointer(handle) + }, + ) + + return res +} +func (object *ReceiverEndpoint) Destroy() { + runtime.SetFinalizer(object, nil) + object.ffiObject.destroy() +} + +type FfiConverterReceiverEndpoint struct{} + +var FfiConverterReceiverEndpointINSTANCE = FfiConverterReceiverEndpoint{} + +func (c FfiConverterReceiverEndpoint) Lift(pointer unsafe.Pointer) *ReceiverEndpoint { + result := &ReceiverEndpoint{ + newFfiObject( + pointer, + func(pointer unsafe.Pointer, status *C.RustCallStatus) unsafe.Pointer { + return C.uniffi_iroh_streamplace_fn_clone_receiverendpoint(pointer, status) + }, + func(pointer unsafe.Pointer, status *C.RustCallStatus) { + C.uniffi_iroh_streamplace_fn_free_receiverendpoint(pointer, status) + }, + ), + } + runtime.SetFinalizer(result, (*ReceiverEndpoint).Destroy) + return result +} + +func (c FfiConverterReceiverEndpoint) Read(reader io.Reader) *ReceiverEndpoint { + return c.Lift(unsafe.Pointer(uintptr(readUint64(reader)))) +} + +func (c FfiConverterReceiverEndpoint) Lower(value *ReceiverEndpoint) unsafe.Pointer { + // TODO: this is bad - all synchronization from ObjectRuntime.go is discarded here, + // because the pointer will be decremented immediately after this function returns, + // and someone will be left holding onto a non-locked pointer. + pointer := value.ffiObject.incrementPointer("*ReceiverEndpoint") + defer value.ffiObject.decrementPointer() + return pointer + +} + +func (c FfiConverterReceiverEndpoint) Write(writer io.Writer, value *ReceiverEndpoint) { + writeUint64(writer, uint64(uintptr(c.Lower(value)))) +} + +type FfiDestroyerReceiverEndpoint struct{} + +func (_ FfiDestroyerReceiverEndpoint) Destroy(value *ReceiverEndpoint) { + value.Destroy() +} + type SenderEndpointInterface interface { + AddPeer(addr *NodeAddr) + NodeAddr() *NodeAddr + Send(nodeId *PublicKey, data []byte) } type SenderEndpoint struct { ffiObject FfiObject @@ -504,6 +1275,86 @@ func NewSenderEndpoint() *SenderEndpoint { return res } +func (_self *SenderEndpoint) AddPeer(addr *NodeAddr) { + _pointer := _self.ffiObject.incrementPointer("*SenderEndpoint") + defer _self.ffiObject.decrementPointer() + uniffiRustCallAsync[struct{}]( + nil, + // completeFn + func(handle C.uint64_t, status *C.RustCallStatus) struct{} { + C.ffi_iroh_streamplace_rust_future_complete_void(handle, status) + return struct{}{} + }, + // liftFn + func(_ struct{}) struct{} { return struct{}{} }, + C.uniffi_iroh_streamplace_fn_method_senderendpoint_add_peer( + _pointer, FfiConverterNodeAddrINSTANCE.Lower(addr)), + // pollFn + func(handle C.uint64_t, continuation C.UniffiRustFutureContinuationCallback, data C.uint64_t) { + C.ffi_iroh_streamplace_rust_future_poll_void(handle, continuation, data) + }, + // freeFn + func(handle C.uint64_t) { + C.ffi_iroh_streamplace_rust_future_free_void(handle) + }, + ) + +} + +func (_self *SenderEndpoint) NodeAddr() *NodeAddr { + _pointer := _self.ffiObject.incrementPointer("*SenderEndpoint") + defer _self.ffiObject.decrementPointer() + res, _ := uniffiRustCallAsync[struct{}]( + nil, + // completeFn + func(handle C.uint64_t, status *C.RustCallStatus) unsafe.Pointer { + res := C.ffi_iroh_streamplace_rust_future_complete_pointer(handle, status) + return res + }, + // liftFn + func(ffi unsafe.Pointer) *NodeAddr { + return FfiConverterNodeAddrINSTANCE.Lift(ffi) + }, + C.uniffi_iroh_streamplace_fn_method_senderendpoint_node_addr( + _pointer), + // pollFn + func(handle C.uint64_t, continuation C.UniffiRustFutureContinuationCallback, data C.uint64_t) { + C.ffi_iroh_streamplace_rust_future_poll_pointer(handle, continuation, data) + }, + // freeFn + func(handle C.uint64_t) { + C.ffi_iroh_streamplace_rust_future_free_pointer(handle) + }, + ) + + return res +} + +func (_self *SenderEndpoint) Send(nodeId *PublicKey, data []byte) { + _pointer := _self.ffiObject.incrementPointer("*SenderEndpoint") + defer _self.ffiObject.decrementPointer() + uniffiRustCallAsync[struct{}]( + nil, + // completeFn + func(handle C.uint64_t, status *C.RustCallStatus) struct{} { + C.ffi_iroh_streamplace_rust_future_complete_void(handle, status) + return struct{}{} + }, + // liftFn + func(_ struct{}) struct{} { return struct{}{} }, + C.uniffi_iroh_streamplace_fn_method_senderendpoint_send( + _pointer, FfiConverterPublicKeyINSTANCE.Lower(nodeId), FfiConverterBytesINSTANCE.Lower(data)), + // pollFn + func(handle C.uint64_t, continuation C.UniffiRustFutureContinuationCallback, data C.uint64_t) { + C.ffi_iroh_streamplace_rust_future_poll_void(handle, continuation, data) + }, + // freeFn + func(handle C.uint64_t) { + C.ffi_iroh_streamplace_rust_future_free_void(handle) + }, + ) + +} func (object *SenderEndpoint) Destroy() { runtime.SetFinalizer(object, nil) object.ffiObject.destroy() @@ -553,6 +1404,86 @@ func (_ FfiDestroyerSenderEndpoint) Destroy(value *SenderEndpoint) { value.Destroy() } +type FfiConverterOptionalString struct{} + +var FfiConverterOptionalStringINSTANCE = FfiConverterOptionalString{} + +func (c FfiConverterOptionalString) Lift(rb RustBufferI) *string { + return LiftFromRustBuffer[*string](c, rb) +} + +func (_ FfiConverterOptionalString) Read(reader io.Reader) *string { + if readInt8(reader) == 0 { + return nil + } + temp := FfiConverterStringINSTANCE.Read(reader) + return &temp +} + +func (c FfiConverterOptionalString) Lower(value *string) C.RustBuffer { + return LowerIntoRustBuffer[*string](c, value) +} + +func (_ FfiConverterOptionalString) Write(writer io.Writer, value *string) { + if value == nil { + writeInt8(writer, 0) + } else { + writeInt8(writer, 1) + FfiConverterStringINSTANCE.Write(writer, *value) + } +} + +type FfiDestroyerOptionalString struct{} + +func (_ FfiDestroyerOptionalString) Destroy(value *string) { + if value != nil { + FfiDestroyerString{}.Destroy(*value) + } +} + +type FfiConverterSequenceString struct{} + +var FfiConverterSequenceStringINSTANCE = FfiConverterSequenceString{} + +func (c FfiConverterSequenceString) Lift(rb RustBufferI) []string { + return LiftFromRustBuffer[[]string](c, rb) +} + +func (c FfiConverterSequenceString) Read(reader io.Reader) []string { + length := readInt32(reader) + if length == 0 { + return nil + } + result := make([]string, 0, length) + for i := int32(0); i < length; i++ { + result = append(result, FfiConverterStringINSTANCE.Read(reader)) + } + return result +} + +func (c FfiConverterSequenceString) Lower(value []string) C.RustBuffer { + return LowerIntoRustBuffer[[]string](c, value) +} + +func (c FfiConverterSequenceString) Write(writer io.Writer, value []string) { + if len(value) > math.MaxInt32 { + panic("[]string is too large to fit into Int32") + } + + writeInt32(writer, int32(len(value))) + for _, item := range value { + FfiConverterStringINSTANCE.Write(writer, item) + } +} + +type FfiDestroyerSequenceString struct{} + +func (FfiDestroyerSequenceString) Destroy(sequence []string) { + for _, value := range sequence { + FfiDestroyerString{}.Destroy(value) + } +} + const ( uniffiRustFuturePollReady int8 = 0 uniffiRustFuturePollMaybeReady int8 = 1 diff --git a/pkg/iroh_streamplace/generated/iroh_streamplace/iroh_streamplace.h b/pkg/iroh_streamplace/generated/iroh_streamplace/iroh_streamplace.h index 480d0467..809d9cae 100644 --- a/pkg/iroh_streamplace/generated/iroh_streamplace/iroh_streamplace.h +++ b/pkg/iroh_streamplace/generated/iroh_streamplace/iroh_streamplace.h @@ -377,6 +377,143 @@ static void call_UniffiForeignFutureCompleteVoid( } +#endif +#ifndef UNIFFI_FFIDEF_CALLBACK_INTERFACE_DATA_HANDLER_METHOD0 +#define UNIFFI_FFIDEF_CALLBACK_INTERFACE_DATA_HANDLER_METHOD0 +typedef void (*UniffiCallbackInterfaceDataHandlerMethod0)(uint64_t uniffi_handle, void* peer, RustBuffer data, UniffiForeignFutureCompleteVoid uniffi_future_callback, uint64_t uniffi_callback_data, UniffiForeignFuture* uniffi_out_return); + +// Making function static works arround: +// https://github.com/golang/go/issues/11263 +static void call_UniffiCallbackInterfaceDataHandlerMethod0( + UniffiCallbackInterfaceDataHandlerMethod0 cb, uint64_t uniffi_handle, void* peer, RustBuffer data, UniffiForeignFutureCompleteVoid uniffi_future_callback, uint64_t uniffi_callback_data, UniffiForeignFuture* uniffi_out_return) +{ + return cb(uniffi_handle, peer, data, uniffi_future_callback, uniffi_callback_data, uniffi_out_return); +} + + +#endif +#ifndef UNIFFI_FFIDEF_V_TABLE_CALLBACK_INTERFACE_DATA_HANDLER +#define UNIFFI_FFIDEF_V_TABLE_CALLBACK_INTERFACE_DATA_HANDLER +typedef struct UniffiVTableCallbackInterfaceDataHandler { + UniffiCallbackInterfaceDataHandlerMethod0 handleData; + UniffiCallbackInterfaceFree uniffiFree; +} UniffiVTableCallbackInterfaceDataHandler; + +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CLONE_DATAHANDLER +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CLONE_DATAHANDLER +void* uniffi_iroh_streamplace_fn_clone_datahandler(void* ptr, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_FREE_DATAHANDLER +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_FREE_DATAHANDLER +void uniffi_iroh_streamplace_fn_free_datahandler(void* ptr, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_INIT_CALLBACK_VTABLE_DATAHANDLER +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_INIT_CALLBACK_VTABLE_DATAHANDLER +void uniffi_iroh_streamplace_fn_init_callback_vtable_datahandler(UniffiVTableCallbackInterfaceDataHandler* vtable +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_DATAHANDLER_HANDLE_DATA +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_DATAHANDLER_HANDLE_DATA +uint64_t uniffi_iroh_streamplace_fn_method_datahandler_handle_data(void* ptr, void* peer, RustBuffer data +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CLONE_NODEADDR +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CLONE_NODEADDR +void* uniffi_iroh_streamplace_fn_clone_nodeaddr(void* ptr, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_FREE_NODEADDR +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_FREE_NODEADDR +void uniffi_iroh_streamplace_fn_free_nodeaddr(void* ptr, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CONSTRUCTOR_NODEADDR_NEW +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CONSTRUCTOR_NODEADDR_NEW +void* uniffi_iroh_streamplace_fn_constructor_nodeaddr_new(void* node_id, RustBuffer derp_url, RustBuffer addresses, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_NODEADDR_DIRECT_ADDRESSES +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_NODEADDR_DIRECT_ADDRESSES +RustBuffer uniffi_iroh_streamplace_fn_method_nodeaddr_direct_addresses(void* ptr, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_NODEADDR_EQUAL +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_NODEADDR_EQUAL +int8_t uniffi_iroh_streamplace_fn_method_nodeaddr_equal(void* ptr, void* other, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_NODEADDR_NODE_ID +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_NODEADDR_NODE_ID +void* uniffi_iroh_streamplace_fn_method_nodeaddr_node_id(void* ptr, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_NODEADDR_RELAY_URL +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_NODEADDR_RELAY_URL +RustBuffer uniffi_iroh_streamplace_fn_method_nodeaddr_relay_url(void* ptr, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CLONE_PUBLICKEY +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CLONE_PUBLICKEY +void* uniffi_iroh_streamplace_fn_clone_publickey(void* ptr, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_FREE_PUBLICKEY +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_FREE_PUBLICKEY +void uniffi_iroh_streamplace_fn_free_publickey(void* ptr, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CONSTRUCTOR_PUBLICKEY_FROM_BYTES +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CONSTRUCTOR_PUBLICKEY_FROM_BYTES +void* uniffi_iroh_streamplace_fn_constructor_publickey_from_bytes(RustBuffer bytes, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CONSTRUCTOR_PUBLICKEY_FROM_STRING +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CONSTRUCTOR_PUBLICKEY_FROM_STRING +void* uniffi_iroh_streamplace_fn_constructor_publickey_from_string(RustBuffer s, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_PUBLICKEY_EQUAL +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_PUBLICKEY_EQUAL +int8_t uniffi_iroh_streamplace_fn_method_publickey_equal(void* ptr, void* other, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_PUBLICKEY_FMT_SHORT +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_PUBLICKEY_FMT_SHORT +RustBuffer uniffi_iroh_streamplace_fn_method_publickey_fmt_short(void* ptr, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_PUBLICKEY_TO_BYTES +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_PUBLICKEY_TO_BYTES +RustBuffer uniffi_iroh_streamplace_fn_method_publickey_to_bytes(void* ptr, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_PUBLICKEY_UNIFFI_TRAIT_DISPLAY +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_PUBLICKEY_UNIFFI_TRAIT_DISPLAY +RustBuffer uniffi_iroh_streamplace_fn_method_publickey_uniffi_trait_display(void* ptr, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CLONE_RECEIVERENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CLONE_RECEIVERENDPOINT +void* uniffi_iroh_streamplace_fn_clone_receiverendpoint(void* ptr, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_FREE_RECEIVERENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_FREE_RECEIVERENDPOINT +void uniffi_iroh_streamplace_fn_free_receiverendpoint(void* ptr, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CONSTRUCTOR_RECEIVERENDPOINT_NEW +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CONSTRUCTOR_RECEIVERENDPOINT_NEW +uint64_t uniffi_iroh_streamplace_fn_constructor_receiverendpoint_new(void* handler +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_RECEIVERENDPOINT_NODE_ADDR +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_RECEIVERENDPOINT_NODE_ADDR +uint64_t uniffi_iroh_streamplace_fn_method_receiverendpoint_node_addr(void* ptr +); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CLONE_SENDERENDPOINT #define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CLONE_SENDERENDPOINT @@ -392,6 +529,21 @@ void uniffi_iroh_streamplace_fn_free_senderendpoint(void* ptr, RustCallStatus *o #define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CONSTRUCTOR_SENDERENDPOINT_NEW uint64_t uniffi_iroh_streamplace_fn_constructor_senderendpoint_new(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_SENDERENDPOINT_ADD_PEER +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_SENDERENDPOINT_ADD_PEER +uint64_t uniffi_iroh_streamplace_fn_method_senderendpoint_add_peer(void* ptr, void* addr +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_SENDERENDPOINT_NODE_ADDR +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_SENDERENDPOINT_NODE_ADDR +uint64_t uniffi_iroh_streamplace_fn_method_senderendpoint_node_addr(void* ptr +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_SENDERENDPOINT_SEND +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_SENDERENDPOINT_SEND +uint64_t uniffi_iroh_streamplace_fn_method_senderendpoint_send(void* ptr, void* node_id, RustBuffer data ); #endif #ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUSTBUFFER_ALLOC @@ -672,6 +824,102 @@ void ffi_iroh_streamplace_rust_future_free_void(uint64_t handle #ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_COMPLETE_VOID #define UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUST_FUTURE_COMPLETE_VOID void ffi_iroh_streamplace_rust_future_complete_void(uint64_t handle, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_DATAHANDLER_HANDLE_DATA +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_DATAHANDLER_HANDLE_DATA +uint16_t uniffi_iroh_streamplace_checksum_method_datahandler_handle_data(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_NODEADDR_DIRECT_ADDRESSES +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_NODEADDR_DIRECT_ADDRESSES +uint16_t uniffi_iroh_streamplace_checksum_method_nodeaddr_direct_addresses(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_NODEADDR_EQUAL +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_NODEADDR_EQUAL +uint16_t uniffi_iroh_streamplace_checksum_method_nodeaddr_equal(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_NODEADDR_NODE_ID +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_NODEADDR_NODE_ID +uint16_t uniffi_iroh_streamplace_checksum_method_nodeaddr_node_id(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_NODEADDR_RELAY_URL +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_NODEADDR_RELAY_URL +uint16_t uniffi_iroh_streamplace_checksum_method_nodeaddr_relay_url(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_PUBLICKEY_EQUAL +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_PUBLICKEY_EQUAL +uint16_t uniffi_iroh_streamplace_checksum_method_publickey_equal(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_PUBLICKEY_FMT_SHORT +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_PUBLICKEY_FMT_SHORT +uint16_t uniffi_iroh_streamplace_checksum_method_publickey_fmt_short(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_PUBLICKEY_TO_BYTES +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_PUBLICKEY_TO_BYTES +uint16_t uniffi_iroh_streamplace_checksum_method_publickey_to_bytes(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_RECEIVERENDPOINT_NODE_ADDR +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_RECEIVERENDPOINT_NODE_ADDR +uint16_t uniffi_iroh_streamplace_checksum_method_receiverendpoint_node_addr(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_SENDERENDPOINT_ADD_PEER +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_SENDERENDPOINT_ADD_PEER +uint16_t uniffi_iroh_streamplace_checksum_method_senderendpoint_add_peer(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_SENDERENDPOINT_NODE_ADDR +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_SENDERENDPOINT_NODE_ADDR +uint16_t uniffi_iroh_streamplace_checksum_method_senderendpoint_node_addr(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_SENDERENDPOINT_SEND +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_SENDERENDPOINT_SEND +uint16_t uniffi_iroh_streamplace_checksum_method_senderendpoint_send(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_CONSTRUCTOR_NODEADDR_NEW +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_CONSTRUCTOR_NODEADDR_NEW +uint16_t uniffi_iroh_streamplace_checksum_constructor_nodeaddr_new(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_CONSTRUCTOR_PUBLICKEY_FROM_BYTES +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_CONSTRUCTOR_PUBLICKEY_FROM_BYTES +uint16_t uniffi_iroh_streamplace_checksum_constructor_publickey_from_bytes(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_CONSTRUCTOR_PUBLICKEY_FROM_STRING +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_CONSTRUCTOR_PUBLICKEY_FROM_STRING +uint16_t uniffi_iroh_streamplace_checksum_constructor_publickey_from_string(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_CONSTRUCTOR_RECEIVERENDPOINT_NEW +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_CONSTRUCTOR_RECEIVERENDPOINT_NEW +uint16_t uniffi_iroh_streamplace_checksum_constructor_receiverendpoint_new(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_CONSTRUCTOR_SENDERENDPOINT_NEW @@ -687,6 +935,8 @@ uint32_t ffi_iroh_streamplace_uniffi_contract_version(void ); #endif + void iroh_streamplace_cgo_dispatchCallbackInterfaceDataHandlerMethod0(uint64_t uniffi_handle, void* peer, RustBuffer data, UniffiForeignFutureCompleteVoid uniffi_future_callback, uint64_t uniffi_callback_data, UniffiForeignFuture* uniffi_out_return); + void iroh_streamplace_cgo_dispatchCallbackInterfaceDataHandlerFree(uint64_t handle); void iroh_streamplace_uniffiFutureContinuationCallback(uint64_t, int8_t); void iroh_streamplace_uniffiFreeGorutine(uint64_t); diff --git a/pkg/iroh_streamplace/iroh_streamplace.go b/pkg/iroh_streamplace/iroh_streamplace.go index 0dc2a43e..037cae4b 100644 --- a/pkg/iroh_streamplace/iroh_streamplace.go +++ b/pkg/iroh_streamplace/iroh_streamplace.go @@ -1,14 +1,9 @@ package iroh_streamplace import ( - iroh "github.com/n0-computer/iroh-streamplace/pkg/iroh_streamplace/generated/iroh_streamplace" + _ "github.com/n0-computer/iroh-streamplace/pkg/iroh_streamplace/generated/iroh_streamplace" ) // #cgo LDFLAGS: -L../../target/release -liroh_streamplace -lm // #cgo darwin LDFLAGS: -framework Security import "C" - -func NewSenderEndpoint() *iroh.SenderEndpoint { - ep := iroh.NewSenderEndpoint() - return ep -} diff --git a/pkg/iroh_streamplace/iroh_streamplace_test.go b/pkg/iroh_streamplace/iroh_streamplace_test.go index 6ecc16f8..15ed68ad 100644 --- a/pkg/iroh_streamplace/iroh_streamplace_test.go +++ b/pkg/iroh_streamplace/iroh_streamplace_test.go @@ -2,8 +2,42 @@ package iroh_streamplace import ( "testing" + + "github.com/stretchr/testify/assert" + + iroh "github.com/n0-computer/iroh-streamplace/pkg/iroh_streamplace/generated/iroh_streamplace" ) -func TestSender(*testing.T) { - _ = NewSenderEndpoint() +type TestHandler struct { + messages chan []byte +} + +func (handler TestHandler) HandleData(node *iroh.PublicKey, data []byte) { + handler.messages <- data +} + +func TestSender(t *testing.T) { + sender := iroh.NewSenderEndpoint() + + messages := make(chan []byte, 5) + handler := TestHandler { messages: messages } + + receiver := iroh.NewReceiverEndpoint(&handler) + + receiverAddr := receiver.NodeAddr() + receiverId := receiverAddr.NodeId() + + // add peer + sender.AddPeer(receiverAddr) + + // send a few messages + for i := range(5) { + sender.Send(receiverId, []byte{ byte(i), 0, 0, 0 }) + } + + // make sure the receiver got them + for i := range(5) { + msg := <- messages + assert.Equal(t, msg, []byte{byte(i), 0, 0, 0 }) + } } diff --git a/src/receiver.rs b/src/receiver.rs index 23038b21..f76d5f1f 100644 --- a/src/receiver.rs +++ b/src/receiver.rs @@ -36,12 +36,15 @@ impl ReceiverEndpoint { let Ok(conn) = incoming.await else { return; }; - let peer: PublicKey = conn.remote_node_id().unwrap().into(); + let peer = Arc::new(PublicKey::from(conn.remote_node_id().unwrap())); let conn = imsg::Connection::new(conn).await.unwrap(); while let Ok(stream) = conn.accept_stream().await { if let Ok(msg) = stream.recv_msg().await { - handler.clone().handle_data(&peer, msg.to_vec()).await; + handler + .clone() + .handle_data(peer.clone(), msg.to_vec()) + .await; } } }); @@ -64,10 +67,10 @@ impl ReceiverEndpoint { } } -#[uniffi::export] +#[uniffi::export(with_foreign)] #[async_trait::async_trait] pub trait DataHandler: Send + Sync { - async fn handle_data(self: Arc, peer: &PublicKey, data: Vec); + async fn handle_data(&self, peer: Arc, data: Vec); } #[cfg(test)] @@ -90,8 +93,11 @@ mod tests { #[async_trait::async_trait] impl DataHandler for TestHandler { - async fn handle_data(self: Arc, peer: &PublicKey, data: Vec) { - self.messages.send((peer.clone(), data)).await.unwrap(); + async fn handle_data(&self, peer: Arc, data: Vec) { + self.messages + .send((peer.as_ref().clone(), data)) + .await + .unwrap(); } } -- 2.51.2 From 449fe3719c2666d880a28183abaee4a56a3bc218 Mon Sep 17 00:00:00 2001 From: dignifiedquire Date: Tue, 5 Aug 2025 13:13:27 +0200 Subject: [PATCH 05/15] test(go): update test name --- pkg/iroh_streamplace/iroh_streamplace_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/iroh_streamplace/iroh_streamplace_test.go b/pkg/iroh_streamplace/iroh_streamplace_test.go index 15ed68ad..99a893ce 100644 --- a/pkg/iroh_streamplace/iroh_streamplace_test.go +++ b/pkg/iroh_streamplace/iroh_streamplace_test.go @@ -16,7 +16,7 @@ func (handler TestHandler) HandleData(node *iroh.PublicKey, data []byte) { handler.messages <- data } -func TestSender(t *testing.T) { +func TestBasicRoundtrip(t *testing.T) { sender := iroh.NewSenderEndpoint() messages := make(chan []byte, 5) -- 2.51.2 From 155d07454b906b0c5d31c1c1864eeac26c2b2f2a Mon Sep 17 00:00:00 2001 From: dignifiedquire Date: Thu, 7 Aug 2025 18:12:49 +0200 Subject: [PATCH 06/15] build: initial meson setup --- meson.build | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 meson.build diff --git a/meson.build b/meson.build new file mode 100644 index 00000000..0d635ae9 --- /dev/null +++ b/meson.build @@ -0,0 +1,27 @@ +project( + 'iroh-streamplace', + default_options: ['default_library=static'], +) + +prog_cargo = find_program('cargo') + +cargo_cmd = '@0@ build --release --target-dir "@1@"'.format(prog_cargo.full_path(), meson.current_build_dir()) +archive_dir = meson.current_build_dir() + +triple = get_option('RUST_TRIPLE') +if triple != '' + cargo_cmd += ' --target @0@'.format(triple) + archive_dir += '/' + triple +endif + +c2pa_go_dep = custom_target( + 'libiroh_streamplace', + input: [], + output: ['libiroh_streamplace.a'], + command: [ + 'sh', + '-c', + 'cd "@2@" && @0@ && cp "@3@/release/libiroh_streamplace.a" "@1@/libiroh_streamplace.a"'.format(cargo_cmd, meson.current_build_dir(), meson.current_source_dir(), archive_dir), + ], + build_by_default: true, +) -- 2.51.2 From 47c730d5637f3a24e95daa81198ef75e05490dd4 Mon Sep 17 00:00:00 2001 From: dignifiedquire Date: Thu, 7 Aug 2025 18:16:36 +0200 Subject: [PATCH 07/15] build: add meson.options --- meson.options | 1 + 1 file changed, 1 insertion(+) create mode 100644 meson.options diff --git a/meson.options b/meson.options new file mode 100644 index 00000000..b3093e04 --- /dev/null +++ b/meson.options @@ -0,0 +1 @@ +option('RUST_TRIPLE', type : 'string', description : 'Rust triple for cross-compilation') \ No newline at end of file -- 2.51.2 From 21a359e339906ccb8b1e9fdada26284c673ec0a5 Mon Sep 17 00:00:00 2001 From: dignifiedquire Date: Thu, 7 Aug 2025 18:25:29 +0200 Subject: [PATCH 08/15] build: fix typo --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 0d635ae9..a4eeca06 100644 --- a/meson.build +++ b/meson.build @@ -14,7 +14,7 @@ if triple != '' archive_dir += '/' + triple endif -c2pa_go_dep = custom_target( +iroh_streamplace_dep = custom_target( 'libiroh_streamplace', input: [], output: ['libiroh_streamplace.a'], -- 2.51.2 From 93db7cfcfa36c1f75c990d1822c45495e0ff6d51 Mon Sep 17 00:00:00 2001 From: dignifiedquire Date: Thu, 7 Aug 2025 18:33:56 +0200 Subject: [PATCH 09/15] chore: make sure to include relevant framework --- pkg/iroh_streamplace/iroh_streamplace.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/iroh_streamplace/iroh_streamplace.go b/pkg/iroh_streamplace/iroh_streamplace.go index 037cae4b..5a7e525b 100644 --- a/pkg/iroh_streamplace/iroh_streamplace.go +++ b/pkg/iroh_streamplace/iroh_streamplace.go @@ -5,5 +5,5 @@ import ( ) // #cgo LDFLAGS: -L../../target/release -liroh_streamplace -lm -// #cgo darwin LDFLAGS: -framework Security +// #cgo darwin LDFLAGS: -framework Security -framework SystemConfiguration import "C" -- 2.51.2 From d95cfce2dd09a131e085bf2b1399da8faad4344c Mon Sep 17 00:00:00 2001 From: dignifiedquire Date: Thu, 7 Aug 2025 23:28:10 +0200 Subject: [PATCH 10/15] chore: go fmt --- pkg/iroh_streamplace/iroh_streamplace_test.go | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/pkg/iroh_streamplace/iroh_streamplace_test.go b/pkg/iroh_streamplace/iroh_streamplace_test.go index 99a893ce..79dc6c2b 100644 --- a/pkg/iroh_streamplace/iroh_streamplace_test.go +++ b/pkg/iroh_streamplace/iroh_streamplace_test.go @@ -16,28 +16,28 @@ func (handler TestHandler) HandleData(node *iroh.PublicKey, data []byte) { handler.messages <- data } -func TestBasicRoundtrip(t *testing.T) { - sender := iroh.NewSenderEndpoint() +func TestBasicRoundtrip(t *testing.T) { + sender := iroh.NewSenderEndpoint() messages := make(chan []byte, 5) - handler := TestHandler { messages: messages } + handler := TestHandler{messages: messages} - receiver := iroh.NewReceiverEndpoint(&handler) + receiver := iroh.NewReceiverEndpoint(&handler) - receiverAddr := receiver.NodeAddr() - receiverId := receiverAddr.NodeId() + receiverAddr := receiver.NodeAddr() + receiverId := receiverAddr.NodeId() - // add peer - sender.AddPeer(receiverAddr) + // add peer + sender.AddPeer(receiverAddr) - // send a few messages - for i := range(5) { - sender.Send(receiverId, []byte{ byte(i), 0, 0, 0 }) - } + // send a few messages + for i := range 5 { + sender.Send(receiverId, []byte{byte(i), 0, 0, 0}) + } - // make sure the receiver got them - for i := range(5) { - msg := <- messages - assert.Equal(t, msg, []byte{byte(i), 0, 0, 0 }) + // make sure the receiver got them + for i := range 5 { + msg := <-messages + assert.Equal(t, msg, []byte{byte(i), 0, 0, 0}) } } -- 2.51.2 From 0444603168ecb723520a59d90847f1ac4efe9365 Mon Sep 17 00:00:00 2001 From: dignifiedquire Date: Fri, 8 Aug 2025 09:50:23 +0200 Subject: [PATCH 11/15] feat: enable n0-discovery --- src/receiver.rs | 1 + src/sender.rs | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/receiver.rs b/src/receiver.rs index f76d5f1f..4e245ff9 100644 --- a/src/receiver.rs +++ b/src/receiver.rs @@ -21,6 +21,7 @@ impl ReceiverEndpoint { pub async fn new(handler: Arc) -> ReceiverEndpoint { // TODO: error handling let endpoint = iroh::Endpoint::builder() + .discovery_n0() .alpns(vec![ALPN.to_vec()]) .bind() .await diff --git a/src/sender.rs b/src/sender.rs index 88c6c222..c83f75ce 100644 --- a/src/sender.rs +++ b/src/sender.rs @@ -20,7 +20,11 @@ impl SenderEndpoint { #[uniffi::constructor(async_runtime = "tokio")] pub async fn new() -> SenderEndpoint { // TODO: error handling - let endpoint = iroh::Endpoint::builder().bind().await.unwrap(); + let endpoint = iroh::Endpoint::builder() + .discovery_n0() + .bind() + .await + .unwrap(); SenderEndpoint { endpoint, connections: Default::default(), -- 2.51.2 From 91b7dba2dee6b69a06a5edcea501511e7975617d Mon Sep 17 00:00:00 2001 From: dignifiedquire Date: Fri, 8 Aug 2025 10:07:39 +0200 Subject: [PATCH 12/15] fix: ensure addr handling is correct --- Cargo.lock | 37 +++++++++++++++++++++++++++++++++++++ Cargo.toml | 5 ++++- src/receiver.rs | 11 ++++++++++- src/sender.rs | 2 ++ 4 files changed, 53 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fa749a98..3085cb3a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,20 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "acto" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a026259da4f1a13b4af60cda453c392de64c58c12d239c560923e0382f42f2b9" +dependencies = [ + "parking_lot", + "pin-project-lite", + "rustc_version", + "smol_str", + "tokio", + "tracing", +] + [[package]] name = "addr2line" version = "0.24.2" @@ -1583,6 +1597,7 @@ dependencies = [ "strum", "stun-rs", "surge-ping", + "swarm-discovery", "time", "tokio", "tokio-stream", @@ -1752,6 +1767,7 @@ dependencies = [ "iroh", "n0-future 0.2.0", "tokio", + "tracing-subscriber", "uniffi", "url", ] @@ -3168,6 +3184,12 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" +[[package]] +name = "smol_str" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fad6c857cbab2627dcf01ec85a623ca4e7dcb5691cbaa3d7fb7653671f0d09c9" + [[package]] name = "snafu" version = "0.8.6" @@ -3314,6 +3336,21 @@ dependencies = [ "tracing", ] +[[package]] +name = "swarm-discovery" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eae338a4551897c6a50fa2c041c4b75f578962d9fca8adb828cf81f7158740f" +dependencies = [ + "acto", + "hickory-proto", + "rand 0.9.2", + "socket2 0.5.10", + "thiserror 2.0.12", + "tokio", + "tracing", +] + [[package]] name = "syn" version = "1.0.109" diff --git a/Cargo.toml b/Cargo.toml index 2da0c2c9..bce3be64 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ name = "iroh_streamplace" crate-type = ["staticlib", "cdylib"] [dependencies] -iroh = "0.91.1" +iroh = { version = "0.91.1", features = ["discovery-local-network"] } imsg = { git = "https://github.com/n0-computer/imsg", branch = "main" } tokio = "1.47.1" @@ -17,3 +17,6 @@ url = "2.5.4" bytes = "1.10.1" n0-future = "0.2.0" async-trait = "0.1.88" + +[dev-dependencies] +tracing-subscriber = { version = "0.3.19", features = ["env-filter"] } diff --git a/src/receiver.rs b/src/receiver.rs index 4e245ff9..a86398c8 100644 --- a/src/receiver.rs +++ b/src/receiver.rs @@ -22,6 +22,7 @@ impl ReceiverEndpoint { // TODO: error handling let endpoint = iroh::Endpoint::builder() .discovery_n0() + .discovery_local_network() .alpns(vec![ALPN.to_vec()]) .bind() .await @@ -63,6 +64,7 @@ impl ReceiverEndpoint { #[uniffi::method(async_runtime = "tokio")] pub async fn node_addr(&self) -> NodeAddr { + let _ = self.endpoint.home_relay().initialized().await; let addr = self.endpoint.node_addr().initialized().await; addr.into() } @@ -83,6 +85,10 @@ mod tests { #[tokio::test] async fn test_roundtrip() { + tracing_subscriber::fmt() + .with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) + .init(); + let sender = SenderEndpoint::new().await; let (s, mut r) = tokio::sync::mpsc::channel(5); @@ -106,10 +112,13 @@ mod tests { let receiver = ReceiverEndpoint::new(Arc::new(handler.clone())).await; let receiver_addr = receiver.node_addr().await; + println!("recv addr: {:?}", receiver_addr); let receiver_id = receiver_addr.node_id(); // add peer - sender.add_peer(&receiver_addr).await; + sender + .add_peer(&NodeAddr::new(&receiver_id, None, Vec::new())) + .await; // send a few messages for i in 0u8..5 { diff --git a/src/sender.rs b/src/sender.rs index c83f75ce..a4fdfcb2 100644 --- a/src/sender.rs +++ b/src/sender.rs @@ -22,6 +22,7 @@ impl SenderEndpoint { // TODO: error handling let endpoint = iroh::Endpoint::builder() .discovery_n0() + .discovery_local_network() .bind() .await .unwrap(); @@ -60,6 +61,7 @@ impl SenderEndpoint { #[uniffi::method(async_runtime = "tokio")] pub async fn node_addr(&self) -> NodeAddr { + let _ = self.endpoint.home_relay().initialized().await; let addr = self.endpoint.node_addr().initialized().await; addr.into() } -- 2.51.2 From c70ba180eab2e1e7845308871ee6b6e0b550ced6 Mon Sep 17 00:00:00 2001 From: dignifiedquire Date: Fri, 8 Aug 2025 10:28:07 +0200 Subject: [PATCH 13/15] fix: improve error handling in the receiver --- Cargo.lock | 1 + Cargo.toml | 1 + src/receiver.rs | 15 +++++++++++++-- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3085cb3a..6fef9b2e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1767,6 +1767,7 @@ dependencies = [ "iroh", "n0-future 0.2.0", "tokio", + "tracing", "tracing-subscriber", "uniffi", "url", diff --git a/Cargo.toml b/Cargo.toml index bce3be64..e1881733 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ url = "2.5.4" bytes = "1.10.1" n0-future = "0.2.0" async-trait = "0.1.88" +tracing = "0.1.41" [dev-dependencies] tracing-subscriber = { version = "0.3.19", features = ["env-filter"] } diff --git a/src/receiver.rs b/src/receiver.rs index a86398c8..dba8d796 100644 --- a/src/receiver.rs +++ b/src/receiver.rs @@ -3,6 +3,7 @@ use std::sync::Arc; use iroh::Watcher; use n0_future::task::{self, AbortOnDropHandle}; use tokio::task::JoinSet; +use tracing::{debug, warn}; use crate::ALPN; use crate::key::PublicKey; @@ -38,11 +39,21 @@ impl ReceiverEndpoint { let Ok(conn) = incoming.await else { return; }; - let peer = Arc::new(PublicKey::from(conn.remote_node_id().unwrap())); - let conn = imsg::Connection::new(conn).await.unwrap(); + let peer = Arc::new(PublicKey::from( + conn.remote_node_id().expect("invalid remote"), + )); + let conn = match imsg::Connection::new(conn).await { + Ok(conn) => conn, + Err(err) => { + warn!("imsg connection failed: {:?}", err); + return; + } + }; while let Ok(stream) = conn.accept_stream().await { + debug!("accepted stream"); if let Ok(msg) = stream.recv_msg().await { + debug!("received msg {} bytes", msg.len()); handler .clone() .handle_data(peer.clone(), msg.to_vec()) -- 2.51.2 From 215e45c24581bdf19ebcbf17cd27f868d67b089e Mon Sep 17 00:00:00 2001 From: dignifiedquire Date: Wed, 13 Aug 2025 10:45:09 +0200 Subject: [PATCH 14/15] feat: implement error handling --- Cargo.lock | 6 +- Cargo.toml | 2 + .../iroh_streamplace/iroh_streamplace.go | 371 ++++++++++++++++-- pkg/iroh_streamplace/iroh_streamplace_test.go | 12 +- src/error.rs | 26 ++ src/key.rs | 21 +- src/lib.rs | 1 + src/receiver.rs | 22 +- src/sender.rs | 44 ++- src/utils.rs | 10 +- 10 files changed, 439 insertions(+), 76 deletions(-) create mode 100644 src/error.rs diff --git a/Cargo.lock b/Cargo.lock index 6fef9b2e..9aeac85c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -74,9 +74,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.98" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" +checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" dependencies = [ "backtrace", ] @@ -1761,11 +1761,13 @@ dependencies = [ name = "iroh-streamplace" version = "0.1.0" dependencies = [ + "anyhow", "async-trait", "bytes", "imsg", "iroh", "n0-future 0.2.0", + "snafu", "tokio", "tracing", "tracing-subscriber", diff --git a/Cargo.toml b/Cargo.toml index e1881733..d5f51721 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,8 @@ bytes = "1.10.1" n0-future = "0.2.0" async-trait = "0.1.88" tracing = "0.1.41" +snafu = "0.8.6" +anyhow = "1.0.99" [dev-dependencies] tracing-subscriber = { version = "0.3.19", features = ["env-filter"] } diff --git a/pkg/iroh_streamplace/generated/iroh_streamplace/iroh_streamplace.go b/pkg/iroh_streamplace/generated/iroh_streamplace/iroh_streamplace.go index d661ff46..79366fce 100644 --- a/pkg/iroh_streamplace/generated/iroh_streamplace/iroh_streamplace.go +++ b/pkg/iroh_streamplace/generated/iroh_streamplace/iroh_streamplace.go @@ -434,7 +434,7 @@ func uniffiCheckChecksums() { checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { return C.uniffi_iroh_streamplace_checksum_method_senderendpoint_add_peer() }) - if checksum != 63624 { + if checksum != 5255 { // If this happens try cleaning and rebuilding your project panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_method_senderendpoint_add_peer: UniFFI API checksum mismatch") } @@ -452,7 +452,7 @@ func uniffiCheckChecksums() { checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { return C.uniffi_iroh_streamplace_checksum_method_senderendpoint_send() }) - if checksum != 21989 { + if checksum != 20180 { // If this happens try cleaning and rebuilding your project panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_method_senderendpoint_send: UniFFI API checksum mismatch") } @@ -470,7 +470,7 @@ func uniffiCheckChecksums() { checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { return C.uniffi_iroh_streamplace_checksum_constructor_publickey_from_bytes() }) - if checksum != 51762 { + if checksum != 54187 { // If this happens try cleaning and rebuilding your project panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_constructor_publickey_from_bytes: UniFFI API checksum mismatch") } @@ -479,7 +479,7 @@ func uniffiCheckChecksums() { checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { return C.uniffi_iroh_streamplace_checksum_constructor_publickey_from_string() }) - if checksum != 2826 { + if checksum != 62773 { // If this happens try cleaning and rebuilding your project panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_constructor_publickey_from_string: UniFFI API checksum mismatch") } @@ -488,7 +488,7 @@ func uniffiCheckChecksums() { checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { return C.uniffi_iroh_streamplace_checksum_constructor_receiverendpoint_new() }) - if checksum != 30890 { + if checksum != 45400 { // If this happens try cleaning and rebuilding your project panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_constructor_receiverendpoint_new: UniFFI API checksum mismatch") } @@ -497,7 +497,7 @@ func uniffiCheckChecksums() { checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { return C.uniffi_iroh_streamplace_checksum_constructor_senderendpoint_new() }) - if checksum != 37772 { + if checksum != 47627 { // If this happens try cleaning and rebuilding your project panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_constructor_senderendpoint_new: UniFFI API checksum mismatch") } @@ -1020,17 +1020,29 @@ type PublicKey struct { } // Make a PublicKey from byte array -func PublicKeyFromBytes(bytes []byte) *PublicKey { - return FfiConverterPublicKeyINSTANCE.Lift(rustCall(func(_uniffiStatus *C.RustCallStatus) unsafe.Pointer { +func PublicKeyFromBytes(bytes []byte) (*PublicKey, *Error) { + _uniffiRV, _uniffiErr := rustCallWithError[Error](FfiConverterError{}, func(_uniffiStatus *C.RustCallStatus) unsafe.Pointer { return C.uniffi_iroh_streamplace_fn_constructor_publickey_from_bytes(FfiConverterBytesINSTANCE.Lower(bytes), _uniffiStatus) - })) + }) + if _uniffiErr != nil { + var _uniffiDefaultValue *PublicKey + return _uniffiDefaultValue, _uniffiErr + } else { + return FfiConverterPublicKeyINSTANCE.Lift(_uniffiRV), _uniffiErr + } } // Make a PublicKey from base32 string -func PublicKeyFromString(s string) *PublicKey { - return FfiConverterPublicKeyINSTANCE.Lift(rustCall(func(_uniffiStatus *C.RustCallStatus) unsafe.Pointer { +func PublicKeyFromString(s string) (*PublicKey, *Error) { + _uniffiRV, _uniffiErr := rustCallWithError[Error](FfiConverterError{}, func(_uniffiStatus *C.RustCallStatus) unsafe.Pointer { return C.uniffi_iroh_streamplace_fn_constructor_publickey_from_string(FfiConverterStringINSTANCE.Lower(s), _uniffiStatus) - })) + }) + if _uniffiErr != nil { + var _uniffiDefaultValue *PublicKey + return _uniffiDefaultValue, _uniffiErr + } else { + return FfiConverterPublicKeyINSTANCE.Lift(_uniffiRV), _uniffiErr + } } // Returns true if the PublicKeys are equal @@ -1136,9 +1148,9 @@ type ReceiverEndpoint struct { } // Create a new receiver endpoint. -func NewReceiverEndpoint(handler DataHandler) *ReceiverEndpoint { - res, _ := uniffiRustCallAsync[struct{}]( - nil, +func NewReceiverEndpoint(handler DataHandler) (*ReceiverEndpoint, *Error) { + res, err := uniffiRustCallAsync[Error]( + FfiConverterErrorINSTANCE, // completeFn func(handle C.uint64_t, status *C.RustCallStatus) unsafe.Pointer { res := C.ffi_iroh_streamplace_rust_future_complete_pointer(handle, status) @@ -1159,7 +1171,7 @@ func NewReceiverEndpoint(handler DataHandler) *ReceiverEndpoint { }, ) - return res + return res, err } func (_self *ReceiverEndpoint) NodeAddr() *NodeAddr { @@ -1240,18 +1252,18 @@ func (_ FfiDestroyerReceiverEndpoint) Destroy(value *ReceiverEndpoint) { } type SenderEndpointInterface interface { - AddPeer(addr *NodeAddr) + AddPeer(addr *NodeAddr) *Error NodeAddr() *NodeAddr - Send(nodeId *PublicKey, data []byte) + Send(nodeId *PublicKey, data []byte) *Error } type SenderEndpoint struct { ffiObject FfiObject } // Create a new sender endpoint. -func NewSenderEndpoint() *SenderEndpoint { - res, _ := uniffiRustCallAsync[struct{}]( - nil, +func NewSenderEndpoint() (*SenderEndpoint, *Error) { + res, err := uniffiRustCallAsync[Error]( + FfiConverterErrorINSTANCE, // completeFn func(handle C.uint64_t, status *C.RustCallStatus) unsafe.Pointer { res := C.ffi_iroh_streamplace_rust_future_complete_pointer(handle, status) @@ -1272,14 +1284,14 @@ func NewSenderEndpoint() *SenderEndpoint { }, ) - return res + return res, err } -func (_self *SenderEndpoint) AddPeer(addr *NodeAddr) { +func (_self *SenderEndpoint) AddPeer(addr *NodeAddr) *Error { _pointer := _self.ffiObject.incrementPointer("*SenderEndpoint") defer _self.ffiObject.decrementPointer() - uniffiRustCallAsync[struct{}]( - nil, + _, err := uniffiRustCallAsync[Error]( + FfiConverterErrorINSTANCE, // completeFn func(handle C.uint64_t, status *C.RustCallStatus) struct{} { C.ffi_iroh_streamplace_rust_future_complete_void(handle, status) @@ -1299,6 +1311,7 @@ func (_self *SenderEndpoint) AddPeer(addr *NodeAddr) { }, ) + return err } func (_self *SenderEndpoint) NodeAddr() *NodeAddr { @@ -1330,11 +1343,11 @@ func (_self *SenderEndpoint) NodeAddr() *NodeAddr { return res } -func (_self *SenderEndpoint) Send(nodeId *PublicKey, data []byte) { +func (_self *SenderEndpoint) Send(nodeId *PublicKey, data []byte) *Error { _pointer := _self.ffiObject.incrementPointer("*SenderEndpoint") defer _self.ffiObject.decrementPointer() - uniffiRustCallAsync[struct{}]( - nil, + _, err := uniffiRustCallAsync[Error]( + FfiConverterErrorINSTANCE, // completeFn func(handle C.uint64_t, status *C.RustCallStatus) struct{} { C.ffi_iroh_streamplace_rust_future_complete_void(handle, status) @@ -1354,6 +1367,7 @@ func (_self *SenderEndpoint) Send(nodeId *PublicKey, data []byte) { }, ) + return err } func (object *SenderEndpoint) Destroy() { runtime.SetFinalizer(object, nil) @@ -1404,6 +1418,307 @@ func (_ FfiDestroyerSenderEndpoint) Destroy(value *SenderEndpoint) { value.Destroy() } +// An Error. +type Error struct { + err error +} + +// Convience method to turn *Error into error +// Avoiding treating nil pointer as non nil error interface +func (err *Error) AsError() error { + if err == nil { + return nil + } else { + return err + } +} + +func (err Error) Error() string { + return fmt.Sprintf("Error: %s", err.err.Error()) +} + +func (err Error) Unwrap() error { + return err.err +} + +// Err* are used for checking error type with `errors.Is` +var ErrErrorIrohBind = fmt.Errorf("ErrorIrohBind") +var ErrErrorInvalidUrl = fmt.Errorf("ErrorInvalidUrl") +var ErrErrorIrohConnect = fmt.Errorf("ErrorIrohConnect") +var ErrErrorInvalidNetworkAddress = fmt.Errorf("ErrorInvalidNetworkAddress") +var ErrErrorOpenStream = fmt.Errorf("ErrorOpenStream") +var ErrErrorSendMessage = fmt.Errorf("ErrorSendMessage") +var ErrErrorNewConnection = fmt.Errorf("ErrorNewConnection") +var ErrErrorMissingConnection = fmt.Errorf("ErrorMissingConnection") +var ErrErrorInvalidPublicKey = fmt.Errorf("ErrorInvalidPublicKey") + +// Variant structs +type ErrorIrohBind struct { + message string +} + +func NewErrorIrohBind() *Error { + return &Error{err: &ErrorIrohBind{}} +} + +func (e ErrorIrohBind) destroy() { +} + +func (err ErrorIrohBind) Error() string { + return fmt.Sprintf("IrohBind: %s", err.message) +} + +func (self ErrorIrohBind) Is(target error) bool { + return target == ErrErrorIrohBind +} + +type ErrorInvalidUrl struct { + message string +} + +func NewErrorInvalidUrl() *Error { + return &Error{err: &ErrorInvalidUrl{}} +} + +func (e ErrorInvalidUrl) destroy() { +} + +func (err ErrorInvalidUrl) Error() string { + return fmt.Sprintf("InvalidUrl: %s", err.message) +} + +func (self ErrorInvalidUrl) Is(target error) bool { + return target == ErrErrorInvalidUrl +} + +type ErrorIrohConnect struct { + message string +} + +func NewErrorIrohConnect() *Error { + return &Error{err: &ErrorIrohConnect{}} +} + +func (e ErrorIrohConnect) destroy() { +} + +func (err ErrorIrohConnect) Error() string { + return fmt.Sprintf("IrohConnect: %s", err.message) +} + +func (self ErrorIrohConnect) Is(target error) bool { + return target == ErrErrorIrohConnect +} + +type ErrorInvalidNetworkAddress struct { + message string +} + +func NewErrorInvalidNetworkAddress() *Error { + return &Error{err: &ErrorInvalidNetworkAddress{}} +} + +func (e ErrorInvalidNetworkAddress) destroy() { +} + +func (err ErrorInvalidNetworkAddress) Error() string { + return fmt.Sprintf("InvalidNetworkAddress: %s", err.message) +} + +func (self ErrorInvalidNetworkAddress) Is(target error) bool { + return target == ErrErrorInvalidNetworkAddress +} + +type ErrorOpenStream struct { + message string +} + +func NewErrorOpenStream() *Error { + return &Error{err: &ErrorOpenStream{}} +} + +func (e ErrorOpenStream) destroy() { +} + +func (err ErrorOpenStream) Error() string { + return fmt.Sprintf("OpenStream: %s", err.message) +} + +func (self ErrorOpenStream) Is(target error) bool { + return target == ErrErrorOpenStream +} + +type ErrorSendMessage struct { + message string +} + +func NewErrorSendMessage() *Error { + return &Error{err: &ErrorSendMessage{}} +} + +func (e ErrorSendMessage) destroy() { +} + +func (err ErrorSendMessage) Error() string { + return fmt.Sprintf("SendMessage: %s", err.message) +} + +func (self ErrorSendMessage) Is(target error) bool { + return target == ErrErrorSendMessage +} + +type ErrorNewConnection struct { + message string +} + +func NewErrorNewConnection() *Error { + return &Error{err: &ErrorNewConnection{}} +} + +func (e ErrorNewConnection) destroy() { +} + +func (err ErrorNewConnection) Error() string { + return fmt.Sprintf("NewConnection: %s", err.message) +} + +func (self ErrorNewConnection) Is(target error) bool { + return target == ErrErrorNewConnection +} + +type ErrorMissingConnection struct { + message string +} + +func NewErrorMissingConnection() *Error { + return &Error{err: &ErrorMissingConnection{}} +} + +func (e ErrorMissingConnection) destroy() { +} + +func (err ErrorMissingConnection) Error() string { + return fmt.Sprintf("MissingConnection: %s", err.message) +} + +func (self ErrorMissingConnection) Is(target error) bool { + return target == ErrErrorMissingConnection +} + +type ErrorInvalidPublicKey struct { + message string +} + +func NewErrorInvalidPublicKey() *Error { + return &Error{err: &ErrorInvalidPublicKey{}} +} + +func (e ErrorInvalidPublicKey) destroy() { +} + +func (err ErrorInvalidPublicKey) Error() string { + return fmt.Sprintf("InvalidPublicKey: %s", err.message) +} + +func (self ErrorInvalidPublicKey) Is(target error) bool { + return target == ErrErrorInvalidPublicKey +} + +type FfiConverterError struct{} + +var FfiConverterErrorINSTANCE = FfiConverterError{} + +func (c FfiConverterError) Lift(eb RustBufferI) *Error { + return LiftFromRustBuffer[*Error](c, eb) +} + +func (c FfiConverterError) Lower(value *Error) C.RustBuffer { + return LowerIntoRustBuffer[*Error](c, value) +} + +func (c FfiConverterError) Read(reader io.Reader) *Error { + errorID := readUint32(reader) + + message := FfiConverterStringINSTANCE.Read(reader) + switch errorID { + case 1: + return &Error{&ErrorIrohBind{message}} + case 2: + return &Error{&ErrorInvalidUrl{message}} + case 3: + return &Error{&ErrorIrohConnect{message}} + case 4: + return &Error{&ErrorInvalidNetworkAddress{message}} + case 5: + return &Error{&ErrorOpenStream{message}} + case 6: + return &Error{&ErrorSendMessage{message}} + case 7: + return &Error{&ErrorNewConnection{message}} + case 8: + return &Error{&ErrorMissingConnection{message}} + case 9: + return &Error{&ErrorInvalidPublicKey{message}} + default: + panic(fmt.Sprintf("Unknown error code %d in FfiConverterError.Read()", errorID)) + } + +} + +func (c FfiConverterError) Write(writer io.Writer, value *Error) { + switch variantValue := value.err.(type) { + case *ErrorIrohBind: + writeInt32(writer, 1) + case *ErrorInvalidUrl: + writeInt32(writer, 2) + case *ErrorIrohConnect: + writeInt32(writer, 3) + case *ErrorInvalidNetworkAddress: + writeInt32(writer, 4) + case *ErrorOpenStream: + writeInt32(writer, 5) + case *ErrorSendMessage: + writeInt32(writer, 6) + case *ErrorNewConnection: + writeInt32(writer, 7) + case *ErrorMissingConnection: + writeInt32(writer, 8) + case *ErrorInvalidPublicKey: + writeInt32(writer, 9) + default: + _ = variantValue + panic(fmt.Sprintf("invalid error value `%v` in FfiConverterError.Write", value)) + } +} + +type FfiDestroyerError struct{} + +func (_ FfiDestroyerError) Destroy(value *Error) { + switch variantValue := value.err.(type) { + case ErrorIrohBind: + variantValue.destroy() + case ErrorInvalidUrl: + variantValue.destroy() + case ErrorIrohConnect: + variantValue.destroy() + case ErrorInvalidNetworkAddress: + variantValue.destroy() + case ErrorOpenStream: + variantValue.destroy() + case ErrorSendMessage: + variantValue.destroy() + case ErrorNewConnection: + variantValue.destroy() + case ErrorMissingConnection: + variantValue.destroy() + case ErrorInvalidPublicKey: + variantValue.destroy() + default: + _ = variantValue + panic(fmt.Sprintf("invalid error value `%v` in FfiDestroyerError.Destroy", value)) + } +} + type FfiConverterOptionalString struct{} var FfiConverterOptionalStringINSTANCE = FfiConverterOptionalString{} diff --git a/pkg/iroh_streamplace/iroh_streamplace_test.go b/pkg/iroh_streamplace/iroh_streamplace_test.go index 79dc6c2b..118a8543 100644 --- a/pkg/iroh_streamplace/iroh_streamplace_test.go +++ b/pkg/iroh_streamplace/iroh_streamplace_test.go @@ -17,22 +17,26 @@ func (handler TestHandler) HandleData(node *iroh.PublicKey, data []byte) { } func TestBasicRoundtrip(t *testing.T) { - sender := iroh.NewSenderEndpoint() + sender, err := iroh.NewSenderEndpoint() + assert.Nil(t, err) messages := make(chan []byte, 5) handler := TestHandler{messages: messages} - receiver := iroh.NewReceiverEndpoint(&handler) + receiver, err := iroh.NewReceiverEndpoint(&handler) + assert.Nil(t, err) receiverAddr := receiver.NodeAddr() receiverId := receiverAddr.NodeId() // add peer - sender.AddPeer(receiverAddr) + err = sender.AddPeer(receiverAddr) + assert.Nil(t, err) // send a few messages for i := range 5 { - sender.Send(receiverId, []byte{byte(i), 0, 0, 0}) + err = sender.Send(receiverId, []byte{byte(i), 0, 0, 0}) + assert.Nil(t, err) } // make sure the receiver got them diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 00000000..4ac25ff7 --- /dev/null +++ b/src/error.rs @@ -0,0 +1,26 @@ +/// An Error. +#[derive(Debug, snafu::Snafu, uniffi::Error)] +#[uniffi(flat_error)] +#[snafu(visibility(pub(crate)))] +pub enum Error { + #[snafu(display("Bind failure"), context(false))] + IrohBind { source: iroh::endpoint::BindError }, + #[snafu(display("Invalid URL"), context(false))] + InvalidUrl { source: url::ParseError }, + #[snafu(display("Failed to connect"), context(false))] + IrohConnect { + source: iroh::endpoint::ConnectError, + }, + #[snafu(display("Invalid network address"), context(false))] + InvalidNetworkAddress { source: std::net::AddrParseError }, + #[snafu(display("Failed to open stream"))] + OpenStream { source: anyhow::Error }, + #[snafu(display("Failed to send message"))] + SendMessage { source: imsg::StreamError }, + #[snafu(display("Failed to create connection"))] + NewConnection { source: anyhow::Error }, + #[snafu(display("No connection available"))] + MissingConnection, + #[snafu(display("Invalid public key"))] + InvalidPublicKey, +} diff --git a/src/key.rs b/src/key.rs index b318a326..37fab52f 100644 --- a/src/key.rs +++ b/src/key.rs @@ -1,5 +1,7 @@ use std::str::FromStr; +use crate::error::{Error, InvalidPublicKeySnafu}; + /// A public key. /// /// The key itself is just a 32 byte array, but a key has associated crypto @@ -37,21 +39,20 @@ impl PublicKey { /// Make a PublicKey from base32 string #[uniffi::constructor] - pub fn from_string(s: String) -> Self { - // TODO: error - let key = iroh::PublicKey::from_str(&s).unwrap(); - key.into() + pub fn from_string(s: String) -> Result { + let key = iroh::PublicKey::from_str(&s).map_err(|_| InvalidPublicKeySnafu.build())?; + Ok(key.into()) } /// Make a PublicKey from byte array #[uniffi::constructor] - pub fn from_bytes(bytes: Vec) -> Self { + pub fn from_bytes(bytes: Vec) -> Result { if bytes.len() != 32 { - panic!("the PublicKey must be 32 bytes in length"); + InvalidPublicKeySnafu.fail()?; } let bytes: [u8; 32] = bytes.try_into().expect("checked above"); - let key = iroh::PublicKey::from_bytes(&bytes).unwrap(); - key.into() + let key = iroh::PublicKey::from_bytes(&bytes).map_err(|_| InvalidPublicKeySnafu.build())?; + Ok(key.into()) } /// Convert to a base32 string limited to the first 10 bytes for a friendly string @@ -85,7 +86,7 @@ mod tests { let bytes = b"\x52\x3c\x79\x96\xba\xd7\x74\x24\xe9\x67\x86\xcf\x7a\x72\x05\x11\x53\x37\xa5\xb4\x56\x5c\xd2\x55\x06\xa0\xf2\x97\xb1\x91\xa5\xea"; // // create key from string - let key = PublicKey::from_string(key_str.clone()); + let key = PublicKey::from_string(key_str.clone()).unwrap(); // // test methods are as expected assert_eq!(key_str, key.to_string()); @@ -93,7 +94,7 @@ mod tests { assert_eq!(fmt_str, key.fmt_short()); // // create key from bytes - let key_0 = PublicKey::from_bytes(bytes.to_vec()); + let key_0 = PublicKey::from_bytes(bytes.to_vec()).unwrap(); // // test methods are as expected assert_eq!(key_str, key_0.to_string()); diff --git a/src/lib.rs b/src/lib.rs index a124d0c1..387c6acb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,6 @@ uniffi::setup_scaffolding!(); +pub mod error; pub mod key; pub mod receiver; pub mod sender; diff --git a/src/receiver.rs b/src/receiver.rs index dba8d796..6d8ac6c3 100644 --- a/src/receiver.rs +++ b/src/receiver.rs @@ -6,6 +6,7 @@ use tokio::task::JoinSet; use tracing::{debug, warn}; use crate::ALPN; +use crate::error::Error; use crate::key::PublicKey; use crate::utils::NodeAddr; @@ -19,15 +20,13 @@ pub struct ReceiverEndpoint { impl ReceiverEndpoint { /// Create a new receiver endpoint. #[uniffi::constructor(async_runtime = "tokio")] - pub async fn new(handler: Arc) -> ReceiverEndpoint { - // TODO: error handling + pub async fn new(handler: Arc) -> Result { let endpoint = iroh::Endpoint::builder() .discovery_n0() .discovery_local_network() .alpns(vec![ALPN.to_vec()]) .bind() - .await - .unwrap(); + .await?; let ep = endpoint.clone(); let handle = task::spawn(async move { @@ -67,10 +66,10 @@ impl ReceiverEndpoint { tasks.abort_all(); }); - ReceiverEndpoint { + Ok(ReceiverEndpoint { endpoint, _handle: AbortOnDropHandle::new(handle), - } + }) } #[uniffi::method(async_runtime = "tokio")] @@ -100,7 +99,7 @@ mod tests { .with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) .init(); - let sender = SenderEndpoint::new().await; + let sender = SenderEndpoint::new().await.unwrap(); let (s, mut r) = tokio::sync::mpsc::channel(5); @@ -120,7 +119,9 @@ mod tests { } let handler = TestHandler { messages: s }; - let receiver = ReceiverEndpoint::new(Arc::new(handler.clone())).await; + let receiver = ReceiverEndpoint::new(Arc::new(handler.clone())) + .await + .unwrap(); let receiver_addr = receiver.node_addr().await; println!("recv addr: {:?}", receiver_addr); @@ -129,11 +130,12 @@ mod tests { // add peer sender .add_peer(&NodeAddr::new(&receiver_id, None, Vec::new())) - .await; + .await + .unwrap(); // send a few messages for i in 0u8..5 { - sender.send(&receiver_id, &[i, 0, 0, 0]).await; + sender.send(&receiver_id, &[i, 0, 0, 0]).await.unwrap(); } // make sure the receiver got them diff --git a/src/sender.rs b/src/sender.rs index a4fdfcb2..4ac5381b 100644 --- a/src/sender.rs +++ b/src/sender.rs @@ -2,9 +2,13 @@ use std::collections::HashMap; use bytes::Bytes; use iroh::{NodeId, Watcher}; +use snafu::{OptionExt, ResultExt}; use tokio::sync::Mutex; use crate::ALPN; +use crate::error::{ + Error, MissingConnectionSnafu, NewConnectionSnafu, OpenStreamSnafu, SendMessageSnafu, +}; use crate::key::PublicKey; use crate::utils::NodeAddr; @@ -18,45 +22,51 @@ pub struct SenderEndpoint { impl SenderEndpoint { /// Create a new sender endpoint. #[uniffi::constructor(async_runtime = "tokio")] - pub async fn new() -> SenderEndpoint { - // TODO: error handling + pub async fn new() -> Result { let endpoint = iroh::Endpoint::builder() .discovery_n0() .discovery_local_network() .bind() - .await - .unwrap(); - SenderEndpoint { + .await?; + Ok(SenderEndpoint { endpoint, connections: Default::default(), - } + }) } #[uniffi::method(async_runtime = "tokio")] - pub async fn add_peer(&self, addr: &NodeAddr) { - let addr: iroh::NodeAddr = addr.clone().try_into().unwrap(); + pub async fn add_peer(&self, addr: &NodeAddr) -> Result<(), Error> { + let addr: iroh::NodeAddr = addr.clone().try_into()?; let mut conns = self.connections.lock().await; let node_id = addr.node_id; if conns.contains_key(&node_id) { - return; + return Ok(()); } - let conn = self.endpoint.connect(addr, ALPN).await.unwrap(); - let conn = imsg::Connection::new(conn).await.unwrap(); + let conn = self.endpoint.connect(addr, ALPN).await?; + let conn = imsg::Connection::new(conn) + .await + .context(NewConnectionSnafu)?; conns.insert(node_id, conn); + Ok(()) } #[uniffi::method(async_runtime = "tokio")] - pub async fn send(&self, node_id: &PublicKey, data: &[u8]) { + pub async fn send(&self, node_id: &PublicKey, data: &[u8]) -> Result<(), Error> { let node_id: NodeId = node_id.into(); - let Some(conn) = self.connections.lock().await.get(&node_id).cloned() else { - panic!("no connection"); - }; + let conn = self + .connections + .lock() + .await + .get(&node_id) + .cloned() + .context(MissingConnectionSnafu)?; // TODO: store streams - let stream = conn.open_stream().await.unwrap(); + let stream = conn.open_stream().await.context(OpenStreamSnafu)?; let data = Bytes::copy_from_slice(data); - stream.send_msg(data).await.unwrap(); + stream.send_msg(data).await.context(SendMessageSnafu)?; + Ok(()) } #[uniffi::method(async_runtime = "tokio")] diff --git a/src/utils.rs b/src/utils.rs index f683235a..2a95b731 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,6 +1,7 @@ use std::str::FromStr; use std::sync::Arc; +use crate::error::Error; use crate::key::PublicKey; /// A peer and it's addressing information. @@ -44,19 +45,18 @@ impl NodeAddr { } impl TryFrom for iroh::NodeAddr { - type Error = (); + type Error = Error; fn try_from(value: NodeAddr) -> Result { let mut node_addr = iroh::NodeAddr::new((&*value.node_id).into()); let addresses = value .direct_addresses() .into_iter() - .map(|addr| std::net::SocketAddr::from_str(&addr)) - .collect::, _>>() - .map_err(|_| ())?; + .map(|addr| std::net::SocketAddr::from_str(&addr).map_err(Error::from)) + .collect::, _>>()?; if let Some(derp_url) = value.relay_url() { - let url = url::Url::parse(&derp_url).map_err(|_| ())?; + let url = url::Url::parse(&derp_url)?; node_addr = node_addr.with_relay_url(url.into()); } -- 2.51.2 From 0b3bbbf8912a1d2d6a843a1473fed0d295567f81 Mon Sep 17 00:00:00 2001 From: dignifiedquire Date: Wed, 13 Aug 2025 16:10:41 +0200 Subject: [PATCH 15/15] feat: unify endpoint handling --- .../iroh_streamplace/iroh_streamplace.go | 273 +++++++++++++----- .../iroh_streamplace/iroh_streamplace.h | 130 +++++---- pkg/iroh_streamplace/iroh_streamplace_test.go | 8 +- src/endpoint.rs | 33 +++ src/lib.rs | 1 + src/receiver.rs | 41 ++- src/sender.rs | 28 +- 7 files changed, 351 insertions(+), 163 deletions(-) create mode 100644 src/endpoint.rs diff --git a/pkg/iroh_streamplace/generated/iroh_streamplace/iroh_streamplace.go b/pkg/iroh_streamplace/generated/iroh_streamplace/iroh_streamplace.go index 79366fce..5d58f8b7 100644 --- a/pkg/iroh_streamplace/generated/iroh_streamplace/iroh_streamplace.go +++ b/pkg/iroh_streamplace/generated/iroh_streamplace/iroh_streamplace.go @@ -358,6 +358,15 @@ func uniffiCheckChecksums() { panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_method_datahandler_handle_data: UniFFI API checksum mismatch") } } + { + checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_iroh_streamplace_checksum_method_endpoint_node_addr() + }) + if checksum != 17254 { + // If this happens try cleaning and rebuilding your project + panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_method_endpoint_node_addr: UniFFI API checksum mismatch") + } + } { checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { return C.uniffi_iroh_streamplace_checksum_method_nodeaddr_direct_addresses() @@ -423,38 +432,47 @@ func uniffiCheckChecksums() { } { checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { - return C.uniffi_iroh_streamplace_checksum_method_receiverendpoint_node_addr() + return C.uniffi_iroh_streamplace_checksum_method_receiver_node_addr() }) - if checksum != 2125 { + if checksum != 10730 { // If this happens try cleaning and rebuilding your project - panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_method_receiverendpoint_node_addr: UniFFI API checksum mismatch") + panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_method_receiver_node_addr: UniFFI API checksum mismatch") } } { checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { - return C.uniffi_iroh_streamplace_checksum_method_senderendpoint_add_peer() + return C.uniffi_iroh_streamplace_checksum_method_sender_add_peer() }) - if checksum != 5255 { + if checksum != 34321 { // If this happens try cleaning and rebuilding your project - panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_method_senderendpoint_add_peer: UniFFI API checksum mismatch") + panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_method_sender_add_peer: UniFFI API checksum mismatch") } } { checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { - return C.uniffi_iroh_streamplace_checksum_method_senderendpoint_node_addr() + return C.uniffi_iroh_streamplace_checksum_method_sender_node_addr() }) - if checksum != 56355 { + if checksum != 38541 { // If this happens try cleaning and rebuilding your project - panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_method_senderendpoint_node_addr: UniFFI API checksum mismatch") + panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_method_sender_node_addr: UniFFI API checksum mismatch") } } { checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { - return C.uniffi_iroh_streamplace_checksum_method_senderendpoint_send() + return C.uniffi_iroh_streamplace_checksum_method_sender_send() }) - if checksum != 20180 { + if checksum != 24369 { // If this happens try cleaning and rebuilding your project - panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_method_senderendpoint_send: UniFFI API checksum mismatch") + panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_method_sender_send: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_iroh_streamplace_checksum_constructor_endpoint_new() + }) + if checksum != 60672 { + // If this happens try cleaning and rebuilding your project + panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_constructor_endpoint_new: UniFFI API checksum mismatch") } } { @@ -486,20 +504,20 @@ func uniffiCheckChecksums() { } { checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { - return C.uniffi_iroh_streamplace_checksum_constructor_receiverendpoint_new() + return C.uniffi_iroh_streamplace_checksum_constructor_receiver_new() }) - if checksum != 45400 { + if checksum != 35153 { // If this happens try cleaning and rebuilding your project - panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_constructor_receiverendpoint_new: UniFFI API checksum mismatch") + panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_constructor_receiver_new: UniFFI API checksum mismatch") } } { checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { - return C.uniffi_iroh_streamplace_checksum_constructor_senderendpoint_new() + return C.uniffi_iroh_streamplace_checksum_constructor_sender_new() }) - if checksum != 47627 { + if checksum != 27594 { // If this happens try cleaning and rebuilding your project - panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_constructor_senderendpoint_new: UniFFI API checksum mismatch") + panic("iroh_streamplace: uniffi_iroh_streamplace_checksum_constructor_sender_new: UniFFI API checksum mismatch") } } } @@ -883,6 +901,117 @@ func (c FfiConverterDataHandler) register() { C.uniffi_iroh_streamplace_fn_init_callback_vtable_datahandler(&UniffiVTableCallbackInterfaceDataHandlerINSTANCE) } +type EndpointInterface interface { + NodeAddr() *NodeAddr +} +type Endpoint struct { + ffiObject FfiObject +} + +// Create a new endpoint. +func NewEndpoint() (*Endpoint, *Error) { + res, err := uniffiRustCallAsync[Error]( + FfiConverterErrorINSTANCE, + // completeFn + func(handle C.uint64_t, status *C.RustCallStatus) unsafe.Pointer { + res := C.ffi_iroh_streamplace_rust_future_complete_pointer(handle, status) + return res + }, + // liftFn + func(ffi unsafe.Pointer) *Endpoint { + return FfiConverterEndpointINSTANCE.Lift(ffi) + }, + C.uniffi_iroh_streamplace_fn_constructor_endpoint_new(), + // pollFn + func(handle C.uint64_t, continuation C.UniffiRustFutureContinuationCallback, data C.uint64_t) { + C.ffi_iroh_streamplace_rust_future_poll_pointer(handle, continuation, data) + }, + // freeFn + func(handle C.uint64_t) { + C.ffi_iroh_streamplace_rust_future_free_pointer(handle) + }, + ) + + return res, err +} + +func (_self *Endpoint) NodeAddr() *NodeAddr { + _pointer := _self.ffiObject.incrementPointer("*Endpoint") + defer _self.ffiObject.decrementPointer() + res, _ := uniffiRustCallAsync[struct{}]( + nil, + // completeFn + func(handle C.uint64_t, status *C.RustCallStatus) unsafe.Pointer { + res := C.ffi_iroh_streamplace_rust_future_complete_pointer(handle, status) + return res + }, + // liftFn + func(ffi unsafe.Pointer) *NodeAddr { + return FfiConverterNodeAddrINSTANCE.Lift(ffi) + }, + C.uniffi_iroh_streamplace_fn_method_endpoint_node_addr( + _pointer), + // pollFn + func(handle C.uint64_t, continuation C.UniffiRustFutureContinuationCallback, data C.uint64_t) { + C.ffi_iroh_streamplace_rust_future_poll_pointer(handle, continuation, data) + }, + // freeFn + func(handle C.uint64_t) { + C.ffi_iroh_streamplace_rust_future_free_pointer(handle) + }, + ) + + return res +} +func (object *Endpoint) Destroy() { + runtime.SetFinalizer(object, nil) + object.ffiObject.destroy() +} + +type FfiConverterEndpoint struct{} + +var FfiConverterEndpointINSTANCE = FfiConverterEndpoint{} + +func (c FfiConverterEndpoint) Lift(pointer unsafe.Pointer) *Endpoint { + result := &Endpoint{ + newFfiObject( + pointer, + func(pointer unsafe.Pointer, status *C.RustCallStatus) unsafe.Pointer { + return C.uniffi_iroh_streamplace_fn_clone_endpoint(pointer, status) + }, + func(pointer unsafe.Pointer, status *C.RustCallStatus) { + C.uniffi_iroh_streamplace_fn_free_endpoint(pointer, status) + }, + ), + } + runtime.SetFinalizer(result, (*Endpoint).Destroy) + return result +} + +func (c FfiConverterEndpoint) Read(reader io.Reader) *Endpoint { + return c.Lift(unsafe.Pointer(uintptr(readUint64(reader)))) +} + +func (c FfiConverterEndpoint) Lower(value *Endpoint) unsafe.Pointer { + // TODO: this is bad - all synchronization from ObjectRuntime.go is discarded here, + // because the pointer will be decremented immediately after this function returns, + // and someone will be left holding onto a non-locked pointer. + pointer := value.ffiObject.incrementPointer("*Endpoint") + defer value.ffiObject.decrementPointer() + return pointer + +} + +func (c FfiConverterEndpoint) Write(writer io.Writer, value *Endpoint) { + writeUint64(writer, uint64(uintptr(c.Lower(value)))) +} + +type FfiDestroyerEndpoint struct{} + +func (_ FfiDestroyerEndpoint) Destroy(value *Endpoint) { + value.Destroy() +} + // A peer and it's addressing information. type NodeAddrInterface interface { // Get the direct addresses of this peer. @@ -1140,15 +1269,15 @@ func (_ FfiDestroyerPublicKey) Destroy(value *PublicKey) { value.Destroy() } -type ReceiverEndpointInterface interface { +type ReceiverInterface interface { NodeAddr() *NodeAddr } -type ReceiverEndpoint struct { +type Receiver struct { ffiObject FfiObject } -// Create a new receiver endpoint. -func NewReceiverEndpoint(handler DataHandler) (*ReceiverEndpoint, *Error) { +// Create a new receiver. +func NewReceiver(endpoint *Endpoint, handler DataHandler) (*Receiver, *Error) { res, err := uniffiRustCallAsync[Error]( FfiConverterErrorINSTANCE, // completeFn @@ -1157,10 +1286,10 @@ func NewReceiverEndpoint(handler DataHandler) (*ReceiverEndpoint, *Error) { return res }, // liftFn - func(ffi unsafe.Pointer) *ReceiverEndpoint { - return FfiConverterReceiverEndpointINSTANCE.Lift(ffi) + func(ffi unsafe.Pointer) *Receiver { + return FfiConverterReceiverINSTANCE.Lift(ffi) }, - C.uniffi_iroh_streamplace_fn_constructor_receiverendpoint_new(FfiConverterDataHandlerINSTANCE.Lower(handler)), + C.uniffi_iroh_streamplace_fn_constructor_receiver_new(FfiConverterEndpointINSTANCE.Lower(endpoint), FfiConverterDataHandlerINSTANCE.Lower(handler)), // pollFn func(handle C.uint64_t, continuation C.UniffiRustFutureContinuationCallback, data C.uint64_t) { C.ffi_iroh_streamplace_rust_future_poll_pointer(handle, continuation, data) @@ -1174,8 +1303,8 @@ func NewReceiverEndpoint(handler DataHandler) (*ReceiverEndpoint, *Error) { return res, err } -func (_self *ReceiverEndpoint) NodeAddr() *NodeAddr { - _pointer := _self.ffiObject.incrementPointer("*ReceiverEndpoint") +func (_self *Receiver) NodeAddr() *NodeAddr { + _pointer := _self.ffiObject.incrementPointer("*Receiver") defer _self.ffiObject.decrementPointer() res, _ := uniffiRustCallAsync[struct{}]( nil, @@ -1188,7 +1317,7 @@ func (_self *ReceiverEndpoint) NodeAddr() *NodeAddr { func(ffi unsafe.Pointer) *NodeAddr { return FfiConverterNodeAddrINSTANCE.Lift(ffi) }, - C.uniffi_iroh_streamplace_fn_method_receiverendpoint_node_addr( + C.uniffi_iroh_streamplace_fn_method_receiver_node_addr( _pointer), // pollFn func(handle C.uint64_t, continuation C.UniffiRustFutureContinuationCallback, data C.uint64_t) { @@ -1202,66 +1331,66 @@ func (_self *ReceiverEndpoint) NodeAddr() *NodeAddr { return res } -func (object *ReceiverEndpoint) Destroy() { +func (object *Receiver) Destroy() { runtime.SetFinalizer(object, nil) object.ffiObject.destroy() } -type FfiConverterReceiverEndpoint struct{} +type FfiConverterReceiver struct{} -var FfiConverterReceiverEndpointINSTANCE = FfiConverterReceiverEndpoint{} +var FfiConverterReceiverINSTANCE = FfiConverterReceiver{} -func (c FfiConverterReceiverEndpoint) Lift(pointer unsafe.Pointer) *ReceiverEndpoint { - result := &ReceiverEndpoint{ +func (c FfiConverterReceiver) Lift(pointer unsafe.Pointer) *Receiver { + result := &Receiver{ newFfiObject( pointer, func(pointer unsafe.Pointer, status *C.RustCallStatus) unsafe.Pointer { - return C.uniffi_iroh_streamplace_fn_clone_receiverendpoint(pointer, status) + return C.uniffi_iroh_streamplace_fn_clone_receiver(pointer, status) }, func(pointer unsafe.Pointer, status *C.RustCallStatus) { - C.uniffi_iroh_streamplace_fn_free_receiverendpoint(pointer, status) + C.uniffi_iroh_streamplace_fn_free_receiver(pointer, status) }, ), } - runtime.SetFinalizer(result, (*ReceiverEndpoint).Destroy) + runtime.SetFinalizer(result, (*Receiver).Destroy) return result } -func (c FfiConverterReceiverEndpoint) Read(reader io.Reader) *ReceiverEndpoint { +func (c FfiConverterReceiver) Read(reader io.Reader) *Receiver { return c.Lift(unsafe.Pointer(uintptr(readUint64(reader)))) } -func (c FfiConverterReceiverEndpoint) Lower(value *ReceiverEndpoint) unsafe.Pointer { +func (c FfiConverterReceiver) Lower(value *Receiver) unsafe.Pointer { // TODO: this is bad - all synchronization from ObjectRuntime.go is discarded here, // because the pointer will be decremented immediately after this function returns, // and someone will be left holding onto a non-locked pointer. - pointer := value.ffiObject.incrementPointer("*ReceiverEndpoint") + pointer := value.ffiObject.incrementPointer("*Receiver") defer value.ffiObject.decrementPointer() return pointer } -func (c FfiConverterReceiverEndpoint) Write(writer io.Writer, value *ReceiverEndpoint) { +func (c FfiConverterReceiver) Write(writer io.Writer, value *Receiver) { writeUint64(writer, uint64(uintptr(c.Lower(value)))) } -type FfiDestroyerReceiverEndpoint struct{} +type FfiDestroyerReceiver struct{} -func (_ FfiDestroyerReceiverEndpoint) Destroy(value *ReceiverEndpoint) { +func (_ FfiDestroyerReceiver) Destroy(value *Receiver) { value.Destroy() } -type SenderEndpointInterface interface { +type SenderInterface interface { AddPeer(addr *NodeAddr) *Error NodeAddr() *NodeAddr Send(nodeId *PublicKey, data []byte) *Error } -type SenderEndpoint struct { +type Sender struct { ffiObject FfiObject } -// Create a new sender endpoint. -func NewSenderEndpoint() (*SenderEndpoint, *Error) { +// Create a new sender. +func NewSender(endpoint *Endpoint) (*Sender, *Error) { res, err := uniffiRustCallAsync[Error]( FfiConverterErrorINSTANCE, // completeFn @@ -1270,10 +1399,10 @@ func NewSenderEndpoint() (*SenderEndpoint, *Error) { return res }, // liftFn - func(ffi unsafe.Pointer) *SenderEndpoint { - return FfiConverterSenderEndpointINSTANCE.Lift(ffi) + func(ffi unsafe.Pointer) *Sender { + return FfiConverterSenderINSTANCE.Lift(ffi) }, - C.uniffi_iroh_streamplace_fn_constructor_senderendpoint_new(), + C.uniffi_iroh_streamplace_fn_constructor_sender_new(FfiConverterEndpointINSTANCE.Lower(endpoint)), // pollFn func(handle C.uint64_t, continuation C.UniffiRustFutureContinuationCallback, data C.uint64_t) { C.ffi_iroh_streamplace_rust_future_poll_pointer(handle, continuation, data) @@ -1287,8 +1416,8 @@ func NewSenderEndpoint() (*SenderEndpoint, *Error) { return res, err } -func (_self *SenderEndpoint) AddPeer(addr *NodeAddr) *Error { - _pointer := _self.ffiObject.incrementPointer("*SenderEndpoint") +func (_self *Sender) AddPeer(addr *NodeAddr) *Error { + _pointer := _self.ffiObject.incrementPointer("*Sender") defer _self.ffiObject.decrementPointer() _, err := uniffiRustCallAsync[Error]( FfiConverterErrorINSTANCE, @@ -1299,7 +1428,7 @@ func (_self *SenderEndpoint) AddPeer(addr *NodeAddr) *Error { }, // liftFn func(_ struct{}) struct{} { return struct{}{} }, - C.uniffi_iroh_streamplace_fn_method_senderendpoint_add_peer( + C.uniffi_iroh_streamplace_fn_method_sender_add_peer( _pointer, FfiConverterNodeAddrINSTANCE.Lower(addr)), // pollFn func(handle C.uint64_t, continuation C.UniffiRustFutureContinuationCallback, data C.uint64_t) { @@ -1314,8 +1443,8 @@ func (_self *SenderEndpoint) AddPeer(addr *NodeAddr) *Error { return err } -func (_self *SenderEndpoint) NodeAddr() *NodeAddr { - _pointer := _self.ffiObject.incrementPointer("*SenderEndpoint") +func (_self *Sender) NodeAddr() *NodeAddr { + _pointer := _self.ffiObject.incrementPointer("*Sender") defer _self.ffiObject.decrementPointer() res, _ := uniffiRustCallAsync[struct{}]( nil, @@ -1328,7 +1457,7 @@ func (_self *SenderEndpoint) NodeAddr() *NodeAddr { func(ffi unsafe.Pointer) *NodeAddr { return FfiConverterNodeAddrINSTANCE.Lift(ffi) }, - C.uniffi_iroh_streamplace_fn_method_senderendpoint_node_addr( + C.uniffi_iroh_streamplace_fn_method_sender_node_addr( _pointer), // pollFn func(handle C.uint64_t, continuation C.UniffiRustFutureContinuationCallback, data C.uint64_t) { @@ -1343,8 +1472,8 @@ func (_self *SenderEndpoint) NodeAddr() *NodeAddr { return res } -func (_self *SenderEndpoint) Send(nodeId *PublicKey, data []byte) *Error { - _pointer := _self.ffiObject.incrementPointer("*SenderEndpoint") +func (_self *Sender) Send(nodeId *PublicKey, data []byte) *Error { + _pointer := _self.ffiObject.incrementPointer("*Sender") defer _self.ffiObject.decrementPointer() _, err := uniffiRustCallAsync[Error]( FfiConverterErrorINSTANCE, @@ -1355,7 +1484,7 @@ func (_self *SenderEndpoint) Send(nodeId *PublicKey, data []byte) *Error { }, // liftFn func(_ struct{}) struct{} { return struct{}{} }, - C.uniffi_iroh_streamplace_fn_method_senderendpoint_send( + C.uniffi_iroh_streamplace_fn_method_sender_send( _pointer, FfiConverterPublicKeyINSTANCE.Lower(nodeId), FfiConverterBytesINSTANCE.Lower(data)), // pollFn func(handle C.uint64_t, continuation C.UniffiRustFutureContinuationCallback, data C.uint64_t) { @@ -1369,52 +1498,52 @@ func (_self *SenderEndpoint) Send(nodeId *PublicKey, data []byte) *Error { return err } -func (object *SenderEndpoint) Destroy() { +func (object *Sender) Destroy() { runtime.SetFinalizer(object, nil) object.ffiObject.destroy() } -type FfiConverterSenderEndpoint struct{} +type FfiConverterSender struct{} -var FfiConverterSenderEndpointINSTANCE = FfiConverterSenderEndpoint{} +var FfiConverterSenderINSTANCE = FfiConverterSender{} -func (c FfiConverterSenderEndpoint) Lift(pointer unsafe.Pointer) *SenderEndpoint { - result := &SenderEndpoint{ +func (c FfiConverterSender) Lift(pointer unsafe.Pointer) *Sender { + result := &Sender{ newFfiObject( pointer, func(pointer unsafe.Pointer, status *C.RustCallStatus) unsafe.Pointer { - return C.uniffi_iroh_streamplace_fn_clone_senderendpoint(pointer, status) + return C.uniffi_iroh_streamplace_fn_clone_sender(pointer, status) }, func(pointer unsafe.Pointer, status *C.RustCallStatus) { - C.uniffi_iroh_streamplace_fn_free_senderendpoint(pointer, status) + C.uniffi_iroh_streamplace_fn_free_sender(pointer, status) }, ), } - runtime.SetFinalizer(result, (*SenderEndpoint).Destroy) + runtime.SetFinalizer(result, (*Sender).Destroy) return result } -func (c FfiConverterSenderEndpoint) Read(reader io.Reader) *SenderEndpoint { +func (c FfiConverterSender) Read(reader io.Reader) *Sender { return c.Lift(unsafe.Pointer(uintptr(readUint64(reader)))) } -func (c FfiConverterSenderEndpoint) Lower(value *SenderEndpoint) unsafe.Pointer { +func (c FfiConverterSender) Lower(value *Sender) unsafe.Pointer { // TODO: this is bad - all synchronization from ObjectRuntime.go is discarded here, // because the pointer will be decremented immediately after this function returns, // and someone will be left holding onto a non-locked pointer. - pointer := value.ffiObject.incrementPointer("*SenderEndpoint") + pointer := value.ffiObject.incrementPointer("*Sender") defer value.ffiObject.decrementPointer() return pointer } -func (c FfiConverterSenderEndpoint) Write(writer io.Writer, value *SenderEndpoint) { +func (c FfiConverterSender) Write(writer io.Writer, value *Sender) { writeUint64(writer, uint64(uintptr(c.Lower(value)))) } -type FfiDestroyerSenderEndpoint struct{} +type FfiDestroyerSender struct{} -func (_ FfiDestroyerSenderEndpoint) Destroy(value *SenderEndpoint) { +func (_ FfiDestroyerSender) Destroy(value *Sender) { value.Destroy() } diff --git a/pkg/iroh_streamplace/generated/iroh_streamplace/iroh_streamplace.h b/pkg/iroh_streamplace/generated/iroh_streamplace/iroh_streamplace.h index 809d9cae..5cdfcd5c 100644 --- a/pkg/iroh_streamplace/generated/iroh_streamplace/iroh_streamplace.h +++ b/pkg/iroh_streamplace/generated/iroh_streamplace/iroh_streamplace.h @@ -420,6 +420,27 @@ void uniffi_iroh_streamplace_fn_init_callback_vtable_datahandler(UniffiVTableCal uint64_t uniffi_iroh_streamplace_fn_method_datahandler_handle_data(void* ptr, void* peer, RustBuffer data ); #endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CLONE_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CLONE_ENDPOINT +void* uniffi_iroh_streamplace_fn_clone_endpoint(void* ptr, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_FREE_ENDPOINT +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_FREE_ENDPOINT +void uniffi_iroh_streamplace_fn_free_endpoint(void* ptr, RustCallStatus *out_status +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CONSTRUCTOR_ENDPOINT_NEW +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CONSTRUCTOR_ENDPOINT_NEW +uint64_t uniffi_iroh_streamplace_fn_constructor_endpoint_new(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_ENDPOINT_NODE_ADDR +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_ENDPOINT_NODE_ADDR +uint64_t uniffi_iroh_streamplace_fn_method_endpoint_node_addr(void* ptr +); +#endif #ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CLONE_NODEADDR #define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CLONE_NODEADDR void* uniffi_iroh_streamplace_fn_clone_nodeaddr(void* ptr, RustCallStatus *out_status @@ -495,55 +516,54 @@ RustBuffer uniffi_iroh_streamplace_fn_method_publickey_to_bytes(void* ptr, RustC RustBuffer uniffi_iroh_streamplace_fn_method_publickey_uniffi_trait_display(void* ptr, RustCallStatus *out_status ); #endif -#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CLONE_RECEIVERENDPOINT -#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CLONE_RECEIVERENDPOINT -void* uniffi_iroh_streamplace_fn_clone_receiverendpoint(void* ptr, RustCallStatus *out_status +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CLONE_RECEIVER +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CLONE_RECEIVER +void* uniffi_iroh_streamplace_fn_clone_receiver(void* ptr, RustCallStatus *out_status ); #endif -#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_FREE_RECEIVERENDPOINT -#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_FREE_RECEIVERENDPOINT -void uniffi_iroh_streamplace_fn_free_receiverendpoint(void* ptr, RustCallStatus *out_status +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_FREE_RECEIVER +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_FREE_RECEIVER +void uniffi_iroh_streamplace_fn_free_receiver(void* ptr, RustCallStatus *out_status ); #endif -#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CONSTRUCTOR_RECEIVERENDPOINT_NEW -#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CONSTRUCTOR_RECEIVERENDPOINT_NEW -uint64_t uniffi_iroh_streamplace_fn_constructor_receiverendpoint_new(void* handler +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CONSTRUCTOR_RECEIVER_NEW +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CONSTRUCTOR_RECEIVER_NEW +uint64_t uniffi_iroh_streamplace_fn_constructor_receiver_new(void* endpoint, void* handler ); #endif -#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_RECEIVERENDPOINT_NODE_ADDR -#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_RECEIVERENDPOINT_NODE_ADDR -uint64_t uniffi_iroh_streamplace_fn_method_receiverendpoint_node_addr(void* ptr +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_RECEIVER_NODE_ADDR +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_RECEIVER_NODE_ADDR +uint64_t uniffi_iroh_streamplace_fn_method_receiver_node_addr(void* ptr ); #endif -#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CLONE_SENDERENDPOINT -#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CLONE_SENDERENDPOINT -void* uniffi_iroh_streamplace_fn_clone_senderendpoint(void* ptr, RustCallStatus *out_status +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CLONE_SENDER +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CLONE_SENDER +void* uniffi_iroh_streamplace_fn_clone_sender(void* ptr, RustCallStatus *out_status ); #endif -#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_FREE_SENDERENDPOINT -#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_FREE_SENDERENDPOINT -void uniffi_iroh_streamplace_fn_free_senderendpoint(void* ptr, RustCallStatus *out_status +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_FREE_SENDER +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_FREE_SENDER +void uniffi_iroh_streamplace_fn_free_sender(void* ptr, RustCallStatus *out_status ); #endif -#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CONSTRUCTOR_SENDERENDPOINT_NEW -#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CONSTRUCTOR_SENDERENDPOINT_NEW -uint64_t uniffi_iroh_streamplace_fn_constructor_senderendpoint_new(void - +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CONSTRUCTOR_SENDER_NEW +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_CONSTRUCTOR_SENDER_NEW +uint64_t uniffi_iroh_streamplace_fn_constructor_sender_new(void* endpoint ); #endif -#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_SENDERENDPOINT_ADD_PEER -#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_SENDERENDPOINT_ADD_PEER -uint64_t uniffi_iroh_streamplace_fn_method_senderendpoint_add_peer(void* ptr, void* addr +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_SENDER_ADD_PEER +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_SENDER_ADD_PEER +uint64_t uniffi_iroh_streamplace_fn_method_sender_add_peer(void* ptr, void* addr ); #endif -#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_SENDERENDPOINT_NODE_ADDR -#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_SENDERENDPOINT_NODE_ADDR -uint64_t uniffi_iroh_streamplace_fn_method_senderendpoint_node_addr(void* ptr +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_SENDER_NODE_ADDR +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_SENDER_NODE_ADDR +uint64_t uniffi_iroh_streamplace_fn_method_sender_node_addr(void* ptr ); #endif -#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_SENDERENDPOINT_SEND -#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_SENDERENDPOINT_SEND -uint64_t uniffi_iroh_streamplace_fn_method_senderendpoint_send(void* ptr, void* node_id, RustBuffer data +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_SENDER_SEND +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_FN_METHOD_SENDER_SEND +uint64_t uniffi_iroh_streamplace_fn_method_sender_send(void* ptr, void* node_id, RustBuffer data ); #endif #ifndef UNIFFI_FFIDEF_FFI_IROH_STREAMPLACE_RUSTBUFFER_ALLOC @@ -830,6 +850,12 @@ void ffi_iroh_streamplace_rust_future_complete_void(uint64_t handle, RustCallSta #define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_DATAHANDLER_HANDLE_DATA uint16_t uniffi_iroh_streamplace_checksum_method_datahandler_handle_data(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_ENDPOINT_NODE_ADDR +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_ENDPOINT_NODE_ADDR +uint16_t uniffi_iroh_streamplace_checksum_method_endpoint_node_addr(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_NODEADDR_DIRECT_ADDRESSES @@ -874,27 +900,33 @@ uint16_t uniffi_iroh_streamplace_checksum_method_publickey_to_bytes(void ); #endif -#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_RECEIVERENDPOINT_NODE_ADDR -#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_RECEIVERENDPOINT_NODE_ADDR -uint16_t uniffi_iroh_streamplace_checksum_method_receiverendpoint_node_addr(void +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_RECEIVER_NODE_ADDR +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_RECEIVER_NODE_ADDR +uint16_t uniffi_iroh_streamplace_checksum_method_receiver_node_addr(void + +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_SENDER_ADD_PEER +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_SENDER_ADD_PEER +uint16_t uniffi_iroh_streamplace_checksum_method_sender_add_peer(void ); #endif -#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_SENDERENDPOINT_ADD_PEER -#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_SENDERENDPOINT_ADD_PEER -uint16_t uniffi_iroh_streamplace_checksum_method_senderendpoint_add_peer(void +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_SENDER_NODE_ADDR +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_SENDER_NODE_ADDR +uint16_t uniffi_iroh_streamplace_checksum_method_sender_node_addr(void ); #endif -#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_SENDERENDPOINT_NODE_ADDR -#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_SENDERENDPOINT_NODE_ADDR -uint16_t uniffi_iroh_streamplace_checksum_method_senderendpoint_node_addr(void +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_SENDER_SEND +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_SENDER_SEND +uint16_t uniffi_iroh_streamplace_checksum_method_sender_send(void ); #endif -#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_SENDERENDPOINT_SEND -#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_METHOD_SENDERENDPOINT_SEND -uint16_t uniffi_iroh_streamplace_checksum_method_senderendpoint_send(void +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_CONSTRUCTOR_ENDPOINT_NEW +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_CONSTRUCTOR_ENDPOINT_NEW +uint16_t uniffi_iroh_streamplace_checksum_constructor_endpoint_new(void ); #endif @@ -916,15 +948,15 @@ uint16_t uniffi_iroh_streamplace_checksum_constructor_publickey_from_string(void ); #endif -#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_CONSTRUCTOR_RECEIVERENDPOINT_NEW -#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_CONSTRUCTOR_RECEIVERENDPOINT_NEW -uint16_t uniffi_iroh_streamplace_checksum_constructor_receiverendpoint_new(void +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_CONSTRUCTOR_RECEIVER_NEW +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_CONSTRUCTOR_RECEIVER_NEW +uint16_t uniffi_iroh_streamplace_checksum_constructor_receiver_new(void ); #endif -#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_CONSTRUCTOR_SENDERENDPOINT_NEW -#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_CONSTRUCTOR_SENDERENDPOINT_NEW -uint16_t uniffi_iroh_streamplace_checksum_constructor_senderendpoint_new(void +#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_CONSTRUCTOR_SENDER_NEW +#define UNIFFI_FFIDEF_UNIFFI_IROH_STREAMPLACE_CHECKSUM_CONSTRUCTOR_SENDER_NEW +uint16_t uniffi_iroh_streamplace_checksum_constructor_sender_new(void ); #endif diff --git a/pkg/iroh_streamplace/iroh_streamplace_test.go b/pkg/iroh_streamplace/iroh_streamplace_test.go index 118a8543..b795c453 100644 --- a/pkg/iroh_streamplace/iroh_streamplace_test.go +++ b/pkg/iroh_streamplace/iroh_streamplace_test.go @@ -17,13 +17,17 @@ func (handler TestHandler) HandleData(node *iroh.PublicKey, data []byte) { } func TestBasicRoundtrip(t *testing.T) { - sender, err := iroh.NewSenderEndpoint() + ep1, err := iroh.NewEndpoint() + assert.Nil(t, err) + sender, err := iroh.NewSender(ep1) assert.Nil(t, err) messages := make(chan []byte, 5) handler := TestHandler{messages: messages} - receiver, err := iroh.NewReceiverEndpoint(&handler) + ep2, err := iroh.NewEndpoint() + assert.Nil(t, err) + receiver, err := iroh.NewReceiver(ep2, &handler) assert.Nil(t, err) receiverAddr := receiver.NodeAddr() diff --git a/src/endpoint.rs b/src/endpoint.rs new file mode 100644 index 00000000..6f55da67 --- /dev/null +++ b/src/endpoint.rs @@ -0,0 +1,33 @@ +use iroh::Watcher; + +use crate::ALPN; +use crate::error::Error; +use crate::utils::NodeAddr; + +#[derive(uniffi::Object, Debug, Clone)] +pub struct Endpoint { + pub(crate) endpoint: iroh::Endpoint, +} + +#[uniffi::export] +impl Endpoint { + /// Create a new endpoint. + #[uniffi::constructor(async_runtime = "tokio")] + pub async fn new() -> Result { + let endpoint = iroh::Endpoint::builder() + .discovery_n0() + .discovery_local_network() + .alpns(vec![ALPN.to_vec()]) + .bind() + .await?; + + Ok(Self { endpoint }) + } + + #[uniffi::method(async_runtime = "tokio")] + pub async fn node_addr(&self) -> NodeAddr { + let _ = self.endpoint.home_relay().initialized().await; + let addr = self.endpoint.node_addr().initialized().await; + addr.into() + } +} diff --git a/src/lib.rs b/src/lib.rs index 387c6acb..673e75cf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,6 @@ uniffi::setup_scaffolding!(); +pub mod endpoint; pub mod error; pub mod key; pub mod receiver; diff --git a/src/receiver.rs b/src/receiver.rs index 6d8ac6c3..d1564a6b 100644 --- a/src/receiver.rs +++ b/src/receiver.rs @@ -1,34 +1,29 @@ use std::sync::Arc; -use iroh::Watcher; use n0_future::task::{self, AbortOnDropHandle}; use tokio::task::JoinSet; use tracing::{debug, warn}; -use crate::ALPN; +use crate::endpoint::Endpoint; use crate::error::Error; use crate::key::PublicKey; use crate::utils::NodeAddr; #[derive(uniffi::Object)] -pub struct ReceiverEndpoint { - endpoint: iroh::Endpoint, +pub struct Receiver { + endpoint: Endpoint, _handle: AbortOnDropHandle<()>, } #[uniffi::export] -impl ReceiverEndpoint { - /// Create a new receiver endpoint. +impl Receiver { + /// Create a new receiver. #[uniffi::constructor(async_runtime = "tokio")] - pub async fn new(handler: Arc) -> Result { - let endpoint = iroh::Endpoint::builder() - .discovery_n0() - .discovery_local_network() - .alpns(vec![ALPN.to_vec()]) - .bind() - .await?; - - let ep = endpoint.clone(); + pub async fn new( + endpoint: &Endpoint, + handler: Arc, + ) -> Result { + let ep = endpoint.endpoint.clone(); let handle = task::spawn(async move { let mut tasks = JoinSet::default(); @@ -66,17 +61,15 @@ impl ReceiverEndpoint { tasks.abort_all(); }); - Ok(ReceiverEndpoint { - endpoint, + Ok(Receiver { + endpoint: endpoint.clone(), _handle: AbortOnDropHandle::new(handle), }) } #[uniffi::method(async_runtime = "tokio")] pub async fn node_addr(&self) -> NodeAddr { - let _ = self.endpoint.home_relay().initialized().await; - let addr = self.endpoint.node_addr().initialized().await; - addr.into() + self.endpoint.node_addr().await } } @@ -89,7 +82,7 @@ pub trait DataHandler: Send + Sync { #[cfg(test)] mod tests { - use crate::sender::SenderEndpoint; + use crate::sender::Sender; use super::*; @@ -99,7 +92,8 @@ mod tests { .with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) .init(); - let sender = SenderEndpoint::new().await.unwrap(); + let ep1 = Endpoint::new().await.unwrap(); + let sender = Sender::new(&ep1).await.unwrap(); let (s, mut r) = tokio::sync::mpsc::channel(5); @@ -119,7 +113,8 @@ mod tests { } let handler = TestHandler { messages: s }; - let receiver = ReceiverEndpoint::new(Arc::new(handler.clone())) + let ep2 = Endpoint::new().await.unwrap(); + let receiver = Receiver::new(&ep2, Arc::new(handler.clone())) .await .unwrap(); diff --git a/src/sender.rs b/src/sender.rs index 4ac5381b..028c1458 100644 --- a/src/sender.rs +++ b/src/sender.rs @@ -1,11 +1,12 @@ use std::collections::HashMap; use bytes::Bytes; -use iroh::{NodeId, Watcher}; +use iroh::NodeId; use snafu::{OptionExt, ResultExt}; use tokio::sync::Mutex; use crate::ALPN; +use crate::endpoint::Endpoint; use crate::error::{ Error, MissingConnectionSnafu, NewConnectionSnafu, OpenStreamSnafu, SendMessageSnafu, }; @@ -13,23 +14,18 @@ use crate::key::PublicKey; use crate::utils::NodeAddr; #[derive(uniffi::Object)] -pub struct SenderEndpoint { - endpoint: iroh::Endpoint, +pub struct Sender { + endpoint: Endpoint, connections: Mutex>, } #[uniffi::export] -impl SenderEndpoint { - /// Create a new sender endpoint. +impl Sender { + /// Create a new sender. #[uniffi::constructor(async_runtime = "tokio")] - pub async fn new() -> Result { - let endpoint = iroh::Endpoint::builder() - .discovery_n0() - .discovery_local_network() - .bind() - .await?; - Ok(SenderEndpoint { - endpoint, + pub async fn new(endpoint: &Endpoint) -> Result { + Ok(Sender { + endpoint: endpoint.clone(), connections: Default::default(), }) } @@ -43,7 +39,7 @@ impl SenderEndpoint { if conns.contains_key(&node_id) { return Ok(()); } - let conn = self.endpoint.connect(addr, ALPN).await?; + let conn = self.endpoint.endpoint.connect(addr, ALPN).await?; let conn = imsg::Connection::new(conn) .await .context(NewConnectionSnafu)?; @@ -71,8 +67,6 @@ impl SenderEndpoint { #[uniffi::method(async_runtime = "tokio")] pub async fn node_addr(&self) -> NodeAddr { - let _ = self.endpoint.home_relay().initialized().await; - let addr = self.endpoint.node_addr().initialized().await; - addr.into() + self.endpoint.node_addr().await } }