From fd7e73a7f081e9bc0a44adeb91c6d20e9699d4ad Mon Sep 17 00:00:00 2001 From: Ivan FB <128452529+Ivansete-status@users.noreply.github.com> Date: Thu, 28 Nov 2024 10:35:41 +0100 Subject: [PATCH] Tic tac toe example (#104) * update nwaku vendor to v0.33.1 * build.rs: add negentropy dependency and cmdCount cmdLine dependencies * fix: call waku_setup when instantiating waku_new * Properly decode a Vec * First commit tic-tac-toe * adding some simple game logic to coordinate the turns a little * some logic to panic if a proper event callback hasn't been set * restoring back the type state pattern introduced by Richard * new PubsubTopic type * fix clippy issues --------- Co-authored-by: Richard Ramos --- Cargo.lock | 2 + examples/Cargo.lock | 2122 ++++++++++++++++++++- examples/Cargo.toml | 3 +- examples/basic/Cargo.toml | 1 + examples/basic/src/main.rs | 85 +- examples/tic-tac-toe-gui/Cargo.toml | 17 + examples/tic-tac-toe-gui/src/main.rs | 374 ++++ waku-bindings/Cargo.toml | 2 + waku-bindings/src/general/contenttopic.rs | 134 ++ waku-bindings/src/general/mod.rs | 131 +- waku-bindings/src/general/pubsubtopic.rs | 16 + waku-bindings/src/lib.rs | 18 +- waku-bindings/src/node/config.rs | 29 +- waku-bindings/src/node/context.rs | 62 +- waku-bindings/src/node/events.rs | 29 +- waku-bindings/src/node/filter.rs | 100 + waku-bindings/src/node/lightpush.rs | 49 + waku-bindings/src/node/management.rs | 30 +- waku-bindings/src/node/mod.rs | 111 +- waku-bindings/src/node/peers.rs | 2 +- waku-bindings/src/node/relay.rs | 28 +- waku-bindings/src/utils.rs | 17 +- waku-bindings/tests/node.rs | 176 +- waku-sys/Cargo.toml | 2 +- waku-sys/build.rs | 22 + waku-sys/src/cmd.c | 13 + waku-sys/vendor | 2 +- 27 files changed, 3226 insertions(+), 351 deletions(-) create mode 100644 examples/tic-tac-toe-gui/Cargo.toml create mode 100644 examples/tic-tac-toe-gui/src/main.rs create mode 100644 waku-bindings/src/general/contenttopic.rs create mode 100644 waku-bindings/src/general/pubsubtopic.rs create mode 100644 waku-bindings/src/node/filter.rs create mode 100644 waku-bindings/src/node/lightpush.rs create mode 100644 waku-sys/src/cmd.c diff --git a/Cargo.lock b/Cargo.lock index cfd6ca6..06bdc08 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -380,6 +380,7 @@ name = "basic" version = "0.1.0" dependencies = [ "futures", + "serde_json", "tokio", "tokio-util", "waku-bindings", @@ -3059,6 +3060,7 @@ dependencies = [ "multiaddr", "once_cell", "rand", + "regex", "rln", "secp256k1 0.26.0", "serde", diff --git a/examples/Cargo.lock b/examples/Cargo.lock index 7d24d74..5627c99 100644 --- a/examples/Cargo.lock +++ b/examples/Cargo.lock @@ -2,6 +2,91 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "ab_glyph" +version = "0.2.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3672c180e71eeaaac3a541fbbc5f5ad4def8b747c595ad30d674e43049f7b0" +dependencies = [ + "ab_glyph_rasterizer", + "owned_ttf_parser", +] + +[[package]] +name = "ab_glyph_rasterizer" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" + +[[package]] +name = "accesskit" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76eb1adf08c5bcaa8490b9851fd53cca27fa9880076f178ea9d29f05196728a8" + +[[package]] +name = "accesskit_consumer" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04bb4d9e4772fe0d47df57d0d5dbe5d85dd05e2f37ae1ddb6b105e76be58fb00" +dependencies = [ + "accesskit", +] + +[[package]] +name = "accesskit_macos" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "134d0acf6acb667c89d3332999b1a5df4edbc8d6113910f392ebb73f2b03bb56" +dependencies = [ + "accesskit", + "accesskit_consumer", + "objc2 0.3.0-beta.3.patch-leaks.3", + "once_cell", +] + +[[package]] +name = "accesskit_unix" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e084cb5168790c0c112626175412dc5ad127083441a8248ae49ddf6725519e83" +dependencies = [ + "accesskit", + "accesskit_consumer", + "async-channel 1.9.0", + "atspi", + "futures-lite 1.13.0", + "serde", + "zbus", +] + +[[package]] +name = "accesskit_windows" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eac0a7f2d7cd7a93b938af401d3d8e8b7094217989a7c25c55a953023436e31" +dependencies = [ + "accesskit", + "accesskit_consumer", + "arrayvec", + "once_cell", + "paste", + "windows", +] + +[[package]] +name = "accesskit_winit" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "825d23acee1bd6d25cbaa3ca6ed6e73faf24122a774ec33d52c5c86c6ab423c0" +dependencies = [ + "accesskit", + "accesskit_macos", + "accesskit_unix", + "accesskit_windows", + "winit", +] + [[package]] name = "addr2line" version = "0.21.0" @@ -17,6 +102,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + [[package]] name = "aead" version = "0.5.2" @@ -90,6 +181,30 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +[[package]] +name = "android-activity" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64529721f27c2314ced0890ce45e469574a73e5e6fdd6e9da1860eb29285f5e0" +dependencies = [ + "android-properties", + "bitflags 1.3.2", + "cc", + "jni-sys", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys", + "num_enum 0.6.1", +] + +[[package]] +name = "android-properties" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" + [[package]] name = "android-tzdata" version = "0.1.1" @@ -105,6 +220,21 @@ dependencies = [ "libc", ] +[[package]] +name = "arboard" +version = "3.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df099ccb16cd014ff054ac1bf392c67feeef57164b05c42f037cd40f5d4357f4" +dependencies = [ + "clipboard-win", + "log", + "objc2 0.5.2", + "objc2-app-kit", + "objc2-foundation", + "parking_lot 0.12.1", + "x11rb", +] + [[package]] name = "ark-bn254" version = "0.4.0" @@ -319,6 +449,231 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "async-broadcast" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c48ccdbf6ca6b121e0f586cbc0e73ae440e56c67c30fa0873b4e110d9c26d2b" +dependencies = [ + "event-listener 2.5.3", + "futures-core", +] + +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener 2.5.3", + "futures-core", +] + +[[package]] +name = "async-channel" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-executor" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand 2.0.1", + "futures-lite 2.5.0", + "slab", +] + +[[package]] +name = "async-fs" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" +dependencies = [ + "async-lock 2.8.0", + "autocfg", + "blocking", + "futures-lite 1.13.0", +] + +[[package]] +name = "async-io" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" +dependencies = [ + "async-lock 2.8.0", + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-lite 1.13.0", + "log", + "parking", + "polling 2.8.0", + "rustix 0.37.27", + "slab", + "socket2 0.4.10", + "waker-fn", +] + +[[package]] +name = "async-io" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d6baa8f0178795da0e71bc42c9e5d13261aac7ee549853162e66a241ba17964" +dependencies = [ + "async-lock 3.4.0", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite 2.5.0", + "parking", + "polling 3.7.2", + "rustix 0.38.31", + "slab", + "tracing", + "windows-sys 0.52.0", +] + +[[package]] +name = "async-lock" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" +dependencies = [ + "event-listener 2.5.3", +] + +[[package]] +name = "async-lock" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +dependencies = [ + "event-listener 5.3.1", + "event-listener-strategy", + "pin-project-lite", +] + +[[package]] +name = "async-process" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" +dependencies = [ + "async-io 1.13.0", + "async-lock 2.8.0", + "async-signal", + "blocking", + "cfg-if", + "event-listener 3.1.0", + "futures-lite 1.13.0", + "rustix 0.38.31", + "windows-sys 0.48.0", +] + +[[package]] +name = "async-recursion" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "async-signal" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfb3634b73397aa844481f814fad23bbf07fdb0eabec10f2eb95e58944b1ec32" +dependencies = [ + "async-io 2.3.3", + "async-lock 3.4.0", + "atomic-waker", + "cfg-if", + "futures-core", + "futures-io", + "rustix 0.38.31", + "signal-hook-registry", + "slab", + "windows-sys 0.52.0", +] + +[[package]] +name = "async-task" +version = "4.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" + +[[package]] +name = "async-trait" +version = "0.1.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "atomic_refcell" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41e67cd8309bbd06cd603a9e693a784ac2e5d1e955f11286e355089fcab3047c" + +[[package]] +name = "atspi" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "674e7a3376837b2e7d12d34d58ac47073c491dc3bf6f71a7adaf687d4d817faa" +dependencies = [ + "async-recursion", + "async-trait", + "atspi-macros", + "enumflags2", + "futures-lite 1.13.0", + "serde", + "tracing", + "zbus", + "zbus_names", +] + +[[package]] +name = "atspi-macros" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb4870a32c0eaa17e35bca0e6b16020635157121fb7d45593d242c295bc768" +dependencies = [ + "quote", + "syn 1.0.109", +] + [[package]] name = "atty" version = "0.2.14" @@ -346,7 +701,7 @@ dependencies = [ "cc", "cfg-if", "libc", - "miniz_oxide", + "miniz_oxide 0.7.2", "object 0.32.2", "rustc-demangle", ] @@ -386,8 +741,9 @@ name = "basic" version = "0.1.0" dependencies = [ "futures", + "serde_json", "tokio", - "tokio-util", + "tokio-util 0.7.10", "waku-bindings", ] @@ -421,9 +777,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "bitvec" @@ -446,6 +802,12 @@ dependencies = [ "digest", ] +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + [[package]] name = "block-buffer" version = "0.10.4" @@ -455,6 +817,47 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-sys" +version = "0.1.0-beta.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa55741ee90902547802152aaf3f8e5248aab7e21468089560d4c8840561146" +dependencies = [ + "objc-sys 0.2.0-beta.2", +] + +[[package]] +name = "block2" +version = "0.2.0-alpha.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dd9e63c1744f755c2f60332b88de39d341e5e86239014ad839bd71c106dec42" +dependencies = [ + "block-sys", + "objc2-encode 2.0.0-pre.2", +] + +[[package]] +name = "block2" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" +dependencies = [ + "objc2 0.5.2", +] + +[[package]] +name = "blocking" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" +dependencies = [ + "async-channel 2.3.1", + "async-task", + "futures-io", + "futures-lite 2.5.0", + "piper", +] + [[package]] name = "bs58" version = "0.4.0" @@ -489,6 +892,26 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "bytemuck" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcfcc3cd946cb52f0bbfdbbcfa2f4e24f75ebb6c0e1002f7c25904fada18b9ec" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + [[package]] name = "byteorder" version = "1.4.3" @@ -501,6 +924,20 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +[[package]] +name = "calloop" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e0d00eb1ea24371a97d2da6201c6747a633dc6dc1988ef503403b4c59504a8" +dependencies = [ + "bitflags 1.3.2", + "log", + "nix 0.25.1", + "slotmap", + "thiserror", + "vec_map", +] + [[package]] name = "cast" version = "0.3.0" @@ -512,6 +949,15 @@ name = "cc" version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02f341c093d19155a6e41631ce5971aac4e9a868262212153124c15fa22d1cdc" +dependencies = [ + "libc", +] + +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" [[package]] name = "cexpr" @@ -528,6 +974,21 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "cgl" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ced0551234e87afee12411d535648dd89d2e7f34c78b753395567aff3d447ff" +dependencies = [ + "libc", +] + [[package]] name = "chrono" version = "0.4.34" @@ -572,6 +1033,45 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "clipboard-win" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15efe7a882b08f34e38556b14f2fb3daa98769d06c7f0c1b076dfd0d983bc892" +dependencies = [ + "error-code", +] + +[[package]] +name = "cocoa" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f425db7937052c684daec3bd6375c8abe2d146dca4b8b143d6db777c39138f3a" +dependencies = [ + "bitflags 1.3.2", + "block", + "cocoa-foundation", + "core-foundation", + "core-graphics", + "foreign-types", + "libc", + "objc", +] + +[[package]] +name = "cocoa-foundation" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7" +dependencies = [ + "bitflags 1.3.2", + "block", + "core-foundation", + "core-graphics-types", + "libc", + "objc", +] + [[package]] name = "color-eyre" version = "0.6.2" @@ -599,6 +1099,31 @@ dependencies = [ "tracing-error", ] +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "const-oid" version = "0.9.6" @@ -634,12 +1159,46 @@ dependencies = [ "unicode-segmentation", ] +[[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.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +[[package]] +name = "core-graphics" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-graphics-types", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "libc", +] + [[package]] name = "core2" version = "0.4.0" @@ -859,6 +1418,16 @@ dependencies = [ "cipher", ] +[[package]] +name = "ctrlc" +version = "3.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "672465ae37dc1bc6380a6547a8883d5dd397b0f1faaad4f265726cc7042a5345" +dependencies = [ + "nix 0.28.0", + "windows-sys 0.52.0", +] + [[package]] name = "darling" version = "0.20.8" @@ -951,6 +1520,27 @@ dependencies = [ "subtle", ] +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + +[[package]] +name = "dlib" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" +dependencies = [ + "libloading 0.8.2", +] + +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + [[package]] name = "ecdsa" version = "0.14.8" @@ -963,6 +1553,88 @@ dependencies = [ "signature", ] +[[package]] +name = "ecolor" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e479a7fa3f23d4e794f8b2f8b3568dd4e47886ad1b12c9c095e141cb591eb63" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "eframe" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4596583a2c680c55b6feaa748f74890c4f9cb9c7cb69d6117110444cb65b2f" +dependencies = [ + "bytemuck", + "cocoa", + "egui", + "egui-winit", + "egui_glow", + "glow", + "glutin", + "glutin-winit", + "image", + "js-sys", + "log", + "objc", + "percent-encoding", + "raw-window-handle", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winapi", + "winit", +] + +[[package]] +name = "egui" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3aef8ec3ae1b772f340170c65bf27d5b8c28f543a0116c844d2ac08d01123e7" +dependencies = [ + "accesskit", + "ahash 0.8.6", + "epaint", + "log", + "nohash-hasher", +] + +[[package]] +name = "egui-winit" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a49155fd4a0a4fb21224407a91de0030847972ef90fc64edb63621caea61cb2" +dependencies = [ + "accesskit_winit", + "arboard", + "egui", + "instant", + "log", + "raw-window-handle", + "smithay-clipboard", + "webbrowser", + "winit", +] + +[[package]] +name = "egui_glow" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f8c2752cdf1b0ef5fcda59a898cacabad974d4f5880e92a420b2c917022da64" +dependencies = [ + "bytemuck", + "egui", + "glow", + "log", + "memoffset 0.6.5", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "either" version = "1.10.0" @@ -989,6 +1661,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "emath" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3857d743a6e0741cdd60b622a74c7a36ea75f5f8f11b793b41d905d2c9721a4b" +dependencies = [ + "bytemuck", +] + [[package]] name = "enr" version = "0.7.0" @@ -1029,6 +1710,27 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "enumflags2" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d" +dependencies = [ + "enumflags2_derive", + "serde", +] + +[[package]] +name = "enumflags2_derive" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + [[package]] name = "enumset" version = "1.1.3" @@ -1050,6 +1752,29 @@ dependencies = [ "syn 2.0.52", ] +[[package]] +name = "epaint" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09333964d4d57f40a85338ba3ca5ed4716070ab184dcfed966b35491c5c64f3b" +dependencies = [ + "ab_glyph", + "ahash 0.8.6", + "atomic_refcell", + "bytemuck", + "ecolor", + "emath", + "log", + "nohash-hasher", + "parking_lot 0.12.1", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "errno" version = "0.3.8" @@ -1060,6 +1785,50 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "error-code" +version = "3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d9305ccc6942a704f4335694ecd3de2ea531b114ac2d51f5f843750787a92f" + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "event-listener" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener" +version = "5.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" +dependencies = [ + "event-listener 5.3.1", + "pin-project-lite", +] + [[package]] name = "eyre" version = "0.6.8" @@ -1076,12 +1845,30 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + [[package]] name = "fastrand" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +[[package]] +name = "fdeflate" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07c6f4c64c1d33a3111c4466f7365ebdcc37c5bd1ea0d62aae2e3d722aacbedb" +dependencies = [ + "simd-adler32", +] + [[package]] name = "ff" version = "0.12.1" @@ -1092,12 +1879,37 @@ dependencies = [ "subtle", ] +[[package]] +name = "flate2" +version = "1.0.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" +dependencies = [ + "crc32fast", + "miniz_oxide 0.8.0", +] + [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -1171,6 +1983,34 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "fastrand 1.9.0", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + +[[package]] +name = "futures-lite" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cef40d21ae2c515b51041df9ed313ed21e572df340ea58a922a0aefe7e8891a1" +dependencies = [ + "fastrand 2.0.1", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + [[package]] name = "futures-macro" version = "0.3.30" @@ -1231,6 +2071,16 @@ dependencies = [ "version_check", ] +[[package]] +name = "gethostname" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818" +dependencies = [ + "libc", + "windows-targets 0.48.5", +] + [[package]] name = "getrandom" version = "0.2.12" @@ -1259,7 +2109,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" dependencies = [ "fallible-iterator", - "indexmap", + "indexmap 1.9.3", "stable_deref_trait", ] @@ -1269,12 +2119,99 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +[[package]] +name = "gl_generator" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" +dependencies = [ + "khronos_api", + "log", + "xml-rs", +] + [[package]] name = "glob" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "glow" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca0fe580e4b60a8ab24a868bc08e2f03cbcb20d3d676601fa909386713333728" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "glutin" +version = "0.30.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc93b03242719b8ad39fb26ed2b01737144ce7bd4bfc7adadcef806596760fe" +dependencies = [ + "bitflags 1.3.2", + "cfg_aliases", + "cgl", + "core-foundation", + "dispatch", + "glutin_egl_sys", + "glutin_glx_sys", + "glutin_wgl_sys", + "libloading 0.7.4", + "objc2 0.3.0-beta.3.patch-leaks.3", + "once_cell", + "raw-window-handle", + "wayland-sys 0.30.1", + "windows-sys 0.45.0", + "x11-dl", +] + +[[package]] +name = "glutin-winit" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "629a873fc04062830bfe8f97c03773bcd7b371e23bcc465d0a61448cd1588fa4" +dependencies = [ + "cfg_aliases", + "glutin", + "raw-window-handle", + "winit", +] + +[[package]] +name = "glutin_egl_sys" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af784eb26c5a68ec85391268e074f0aa618c096eadb5d6330b0911cf34fe57c5" +dependencies = [ + "gl_generator", + "windows-sys 0.45.0", +] + +[[package]] +name = "glutin_glx_sys" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b53cb5fe568964aa066a3ba91eac5ecbac869fb0842cd0dc9e412434f1a1494" +dependencies = [ + "gl_generator", + "x11-dl", +] + +[[package]] +name = "glutin_wgl_sys" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef89398e90033fc6bc65e9bd42fd29bbbfd483bda5b56dc5562f455550618165" +dependencies = [ + "gl_generator", +] + [[package]] name = "group" version = "0.12.1" @@ -1329,6 +2266,12 @@ dependencies = [ "allocator-api2", ] +[[package]] +name = "hashbrown" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -1344,6 +2287,12 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "379dada1584ad501b383485dd706b8afb7a70fcbc7f4da7d780638a5a6124a60" +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + [[package]] name = "hex" version = "0.4.3" @@ -1407,6 +2356,19 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "image" +version = "0.24.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "num-traits", + "png", +] + [[package]] name = "include_dir" version = "0.7.3" @@ -1443,6 +2405,16 @@ dependencies = [ "serde", ] +[[package]] +name = "indexmap" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +dependencies = [ + "equivalent", + "hashbrown 0.15.1", +] + [[package]] name = "inout" version = "0.1.3" @@ -1459,6 +2431,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi 0.3.8", + "libc", + "windows-sys 0.48.0", ] [[package]] @@ -1476,6 +2462,28 @@ version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + [[package]] name = "js-sys" version = "0.3.68" @@ -1506,6 +2514,12 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "khronos_api" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" + [[package]] name = "lazy_static" version = "1.4.0" @@ -1550,6 +2564,23 @@ dependencies = [ "windows-targets 0.52.4", ] +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.6.0", + "libc", + "redox_syscall 0.5.7", +] + +[[package]] +name = "linux-raw-sys" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + [[package]] name = "linux-raw-sys" version = "0.4.13" @@ -1578,7 +2609,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b6a72dfa44fe15b5e76b94307eeb2ff995a8c5b283b55008940c02e0c5b634d" dependencies = [ - "indexmap", + "indexmap 1.9.3", "loupe-derive", "rustversion", ] @@ -1602,6 +2633,15 @@ dependencies = [ "libc", ] +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + [[package]] name = "memchr" version = "2.7.1" @@ -1626,6 +2666,24 @@ dependencies = [ "autocfg", ] +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -1641,6 +2699,16 @@ dependencies = [ "adler", ] +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", + "simd-adler32", +] + [[package]] name = "mio" version = "0.8.10" @@ -1648,6 +2716,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" dependencies = [ "libc", + "log", "wasi", "windows-sys 0.48.0", ] @@ -1701,9 +2770,9 @@ dependencies = [ [[package]] name = "multihash-derive" -version = "0.8.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d6d4752e6230d8ef7adf7bd5d8c4b1f6561c1014c5ba9a37445ccefe18aa1db" +checksum = "fc076939022111618a5026d3be019fd8b366e76314538ff9a1b59ffbcbf98bcd" dependencies = [ "proc-macro-crate", "proc-macro-error", @@ -1713,6 +2782,90 @@ dependencies = [ "synstructure", ] +[[package]] +name = "ndk" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0" +dependencies = [ + "bitflags 1.3.2", + "jni-sys", + "ndk-sys", + "num_enum 0.5.11", + "raw-window-handle", + "thiserror", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[package]] +name = "ndk-sys" +version = "0.4.1+23.1.7779620" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cf2aae958bd232cac5069850591667ad422d263686d75b52a065f9badeee5a3" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "nix" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset 0.6.5", +] + +[[package]] +name = "nix" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" +dependencies = [ + "autocfg", + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset 0.6.5", +] + +[[package]] +name = "nix" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset 0.7.1", +] + +[[package]] +name = "nix" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "cfg_aliases", + "libc", +] + +[[package]] +name = "nohash-hasher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" + [[package]] name = "nom" version = "7.1.3" @@ -1809,6 +2962,182 @@ dependencies = [ "libc", ] +[[package]] +name = "num_enum" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +dependencies = [ + "num_enum_derive 0.5.11", +] + +[[package]] +name = "num_enum" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" +dependencies = [ + "num_enum_derive 0.6.1", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "num_enum_derive" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + +[[package]] +name = "objc-sys" +version = "0.2.0-beta.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b9834c1e95694a05a828b59f55fa2afec6288359cda67146126b3f90a55d7" + +[[package]] +name = "objc-sys" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" + +[[package]] +name = "objc2" +version = "0.3.0-beta.3.patch-leaks.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e01640f9f2cb1220bbe80325e179e532cb3379ebcd1bf2279d703c19fe3a468" +dependencies = [ + "block2 0.2.0-alpha.6", + "objc-sys 0.2.0-beta.2", + "objc2-encode 2.0.0-pre.2", +] + +[[package]] +name = "objc2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" +dependencies = [ + "objc-sys 0.3.5", + "objc2-encode 4.0.3", +] + +[[package]] +name = "objc2-app-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" +dependencies = [ + "bitflags 2.6.0", + "block2 0.5.1", + "libc", + "objc2 0.5.2", + "objc2-core-data", + "objc2-core-image", + "objc2-foundation", + "objc2-quartz-core", +] + +[[package]] +name = "objc2-core-data" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" +dependencies = [ + "bitflags 2.6.0", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-image" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation", + "objc2-metal", +] + +[[package]] +name = "objc2-encode" +version = "2.0.0-pre.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abfcac41015b00a120608fdaa6938c44cb983fee294351cc4bac7638b4e50512" +dependencies = [ + "objc-sys 0.2.0-beta.2", +] + +[[package]] +name = "objc2-encode" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7891e71393cd1f227313c9379a26a584ff3d7e6e7159e988851f0934c993f0f8" + +[[package]] +name = "objc2-foundation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" +dependencies = [ + "bitflags 2.6.0", + "block2 0.5.1", + "libc", + "objc2 0.5.2", +] + +[[package]] +name = "objc2-metal" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" +dependencies = [ + "bitflags 2.6.0", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" +dependencies = [ + "bitflags 2.6.0", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation", + "objc2-metal", +] + [[package]] name = "object" version = "0.28.4" @@ -1817,7 +3146,7 @@ checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" dependencies = [ "crc32fast", "hashbrown 0.11.2", - "indexmap", + "indexmap 1.9.3", "memchr", ] @@ -1848,12 +3177,46 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" +[[package]] +name = "orbclient" +version = "0.3.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba0b26cec2e24f08ed8bb31519a9333140a6599b867dac464bb150bdb796fd43" +dependencies = [ + "libredox", +] + +[[package]] +name = "ordered-stream" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" +dependencies = [ + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "owned_ttf_parser" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec719bbf3b2a81c109a4e20b1f129b5566b7dce654bc3872f6a05abf82b2c4" +dependencies = [ + "ttf-parser", +] + [[package]] name = "owo-colors" version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" +[[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.11.2" @@ -1932,6 +3295,17 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "piper" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" +dependencies = [ + "atomic-waker", + "fastrand 2.0.1", + "futures-io", +] + [[package]] name = "pkcs8" version = "0.9.0" @@ -1942,6 +3316,12 @@ dependencies = [ "spki", ] +[[package]] +name = "pkg-config" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" + [[package]] name = "plotters" version = "0.3.5" @@ -1979,6 +3359,50 @@ dependencies = [ "rayon", ] +[[package]] +name = "png" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52f9d46a34a05a6a57566bc2bfae066ef07585a6e3fa30fbbdff5936380623f0" +dependencies = [ + "bitflags 1.3.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide 0.8.0", +] + +[[package]] +name = "polling" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" +dependencies = [ + "autocfg", + "bitflags 1.3.2", + "cfg-if", + "concurrent-queue", + "libc", + "log", + "pin-project-lite", + "windows-sys 0.48.0", +] + +[[package]] +name = "polling" +version = "3.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3ed00ed3fbf728b5816498ecd316d1716eecaced9c0c8d2c5a6740ca214985b" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi 0.4.0", + "pin-project-lite", + "rustix 0.38.31", + "tracing", + "windows-sys 0.52.0", +] + [[package]] name = "polyval" version = "0.6.1" @@ -1999,12 +3423,12 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro-crate" -version = "1.1.3" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" dependencies = [ - "thiserror", - "toml", + "once_cell", + "toml_edit", ] [[package]] @@ -2105,6 +3529,12 @@ dependencies = [ "getrandom", ] +[[package]] +name = "raw-window-handle" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" + [[package]] name = "rayon" version = "1.7.0" @@ -2134,6 +3564,15 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "redox_syscall" version = "0.4.1" @@ -2143,6 +3582,15 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +dependencies = [ + "bitflags 2.6.0", +] + [[package]] name = "regalloc" version = "0.0.34" @@ -2317,16 +3765,30 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "0.37.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" +dependencies = [ + "bitflags 1.3.2", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", +] + [[package]] name = "rustix" version = "0.38.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "errno", "libc", - "linux-raw-sys", + "linux-raw-sys 0.4.13", "windows-sys 0.52.0", ] @@ -2351,12 +3813,31 @@ dependencies = [ "winapi-util", ] +[[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 = "sctk-adwaita" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda4e97be1fd174ccc2aae81c8b694e803fa99b34e8fd0f057a9d70698e3ed09" +dependencies = [ + "ab_glyph", + "log", + "memmap2", + "smithay-client-toolkit", + "tiny-skia", +] + [[package]] name = "seahash" version = "4.1.0" @@ -2482,6 +3963,28 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_repr" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + +[[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 = "sha2" version = "0.10.8" @@ -2537,6 +4040,12 @@ dependencies = [ "rand_core", ] +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + [[package]] name = "simdutf8" version = "0.1.4" @@ -2568,6 +4077,15 @@ dependencies = [ "parking_lot 0.11.2", ] +[[package]] +name = "slotmap" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" +dependencies = [ + "version_check", +] + [[package]] name = "smallvec" version = "1.13.1" @@ -2585,6 +4103,45 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "smithay-client-toolkit" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "870427e30b8f2cbe64bf43ec4b86e88fe39b0a84b3f15efd9c9c2d020bc86eb9" +dependencies = [ + "bitflags 1.3.2", + "calloop", + "dlib", + "lazy_static", + "log", + "memmap2", + "nix 0.24.3", + "pkg-config", + "wayland-client", + "wayland-cursor", + "wayland-protocols", +] + +[[package]] +name = "smithay-clipboard" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a345c870a1fae0b1b779085e81b51e614767c239e93503588e54c5b17f4b0e8" +dependencies = [ + "smithay-client-toolkit", + "wayland-client", +] + +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "socket2" version = "0.5.6" @@ -2644,6 +4201,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "strict-num" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" + [[package]] name = "strsim" version = "0.10.0" @@ -2709,8 +4272,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", - "fastrand", - "rustix", + "fastrand 2.0.1", + "rustix 0.38.31", "windows-sys 0.52.0", ] @@ -2753,6 +4316,22 @@ dependencies = [ "once_cell", ] +[[package]] +name = "tic-tac-toe-gui" +version = "0.1.0" +dependencies = [ + "ark-std", + "ctrlc", + "eframe", + "egui", + "secp256k1 0.26.0", + "serde", + "serde_json", + "tokio", + "tokio-util 0.6.10", + "waku-bindings", +] + [[package]] name = "tiny-keccak" version = "2.0.2" @@ -2762,6 +4341,31 @@ dependencies = [ "crunchy", ] +[[package]] +name = "tiny-skia" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df8493a203431061e901613751931f047d1971337153f96d0e5e363d6dbf6a67" +dependencies = [ + "arrayref", + "arrayvec", + "bytemuck", + "cfg-if", + "png", + "tiny-skia-path", +] + +[[package]] +name = "tiny-skia-path" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adbfb5d3f3dd57a0e11d12f4f13d4ebbbc1b5c15b7ab0a156d030b21da5f677c" +dependencies = [ + "arrayref", + "bytemuck", + "strict-num", +] + [[package]] name = "tinytemplate" version = "1.2.1" @@ -2801,7 +4405,7 @@ dependencies = [ "parking_lot 0.12.1", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.5.6", "tokio-macros", "windows-sys 0.48.0", ] @@ -2817,6 +4421,20 @@ dependencies = [ "syn 2.0.52", ] +[[package]] +name = "tokio-util" +version = "0.6.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36943ee01a6d67977dd3f84a5a1d2efeb4ada3a1ae771cadfaa535d9d9fc6507" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "log", + "pin-project-lite", + "tokio", +] + [[package]] name = "tokio-util" version = "0.7.10" @@ -2833,12 +4451,20 @@ dependencies = [ ] [[package]] -name = "toml" -version = "0.5.11" +name = "toml_datetime" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "serde", + "indexmap 2.6.0", + "toml_datetime", + "winnow", ] [[package]] @@ -2904,12 +4530,29 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "ttf-parser" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5902c5d130972a0000f60860bfbf46f7ca3db5391eddfedd1b8728bd9dc96c0e" + [[package]] name = "typenum" version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "uds_windows" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" +dependencies = [ + "memoffset 0.9.1", + "tempfile", + "winapi", +] + [[package]] name = "unicode-bidi" version = "0.3.15" @@ -2988,12 +4631,24 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + [[package]] name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "waker-fn" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" + [[package]] name = "waku-bindings" version = "0.5.0" @@ -3006,6 +4661,7 @@ dependencies = [ "multiaddr", "once_cell", "rand", + "regex", "rln", "secp256k1 0.26.0", "serde", @@ -3013,6 +4669,7 @@ dependencies = [ "serde_json", "smart-default", "sscanf", + "tokio", "url", "waku-sys", ] @@ -3066,6 +4723,18 @@ dependencies = [ "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877b9c3f61ceea0e56331985743b13f3d25c406a7098d45180fb5f09bc19ed97" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.91" @@ -3111,7 +4780,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea8d8361c9d006ea3d7797de7bd6b1492ffd0f91a22430cfda6c1658ad57bedf" dependencies = [ "cfg-if", - "indexmap", + "indexmap 1.9.3", "js-sys", "loupe", "more-asserts", @@ -3299,7 +4968,7 @@ checksum = "39df01ea05dc0a9bab67e054c7cb01521e53b35a7bb90bd02eca564ed0b2667f" dependencies = [ "backtrace", "enum-iterator", - "indexmap", + "indexmap 1.9.3", "loupe", "more-asserts", "rkyv", @@ -3318,12 +4987,12 @@ dependencies = [ "cfg-if", "corosensei", "enum-iterator", - "indexmap", + "indexmap 1.9.3", "lazy_static", "libc", "loupe", "mach", - "memoffset", + "memoffset 0.6.5", "more-asserts", "region", "rkyv", @@ -3363,6 +5032,91 @@ dependencies = [ "wast", ] +[[package]] +name = "wayland-client" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f3b068c05a039c9f755f881dc50f01732214f5685e379829759088967c46715" +dependencies = [ + "bitflags 1.3.2", + "downcast-rs", + "libc", + "nix 0.24.3", + "scoped-tls", + "wayland-commons", + "wayland-scanner", + "wayland-sys 0.29.5", +] + +[[package]] +name = "wayland-commons" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8691f134d584a33a6606d9d717b95c4fa20065605f798a3f350d78dced02a902" +dependencies = [ + "nix 0.24.3", + "once_cell", + "smallvec", + "wayland-sys 0.29.5", +] + +[[package]] +name = "wayland-cursor" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6865c6b66f13d6257bef1cd40cbfe8ef2f150fb8ebbdb1e8e873455931377661" +dependencies = [ + "nix 0.24.3", + "wayland-client", + "xcursor", +] + +[[package]] +name = "wayland-protocols" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b950621f9354b322ee817a23474e479b34be96c2e909c14f7bc0100e9a970bc6" +dependencies = [ + "bitflags 1.3.2", + "wayland-client", + "wayland-commons", + "wayland-scanner", +] + +[[package]] +name = "wayland-scanner" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f4303d8fa22ab852f789e75a967f0a2cdc430a607751c0499bada3e451cbd53" +dependencies = [ + "proc-macro2", + "quote", + "xml-rs", +] + +[[package]] +name = "wayland-sys" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be12ce1a3c39ec7dba25594b97b42cb3195d54953ddb9d3d95a7c3902bc6e9d4" +dependencies = [ + "dlib", + "lazy_static", + "pkg-config", +] + +[[package]] +name = "wayland-sys" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b2a02ac608e07132978689a6f9bf4214949c85998c247abadd4f4129b1aa06" +dependencies = [ + "dlib", + "lazy_static", + "log", + "pkg-config", +] + [[package]] name = "web-sys" version = "0.3.68" @@ -3373,6 +5127,23 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webbrowser" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db67ae75a9405634f5882791678772c94ff5f16a66535aae186e26aa0841fc8b" +dependencies = [ + "core-foundation", + "home", + "jni", + "log", + "ndk-context", + "objc", + "raw-window-handle", + "url", + "web-sys", +] + [[package]] name = "which" version = "4.4.2" @@ -3382,7 +5153,7 @@ dependencies = [ "either", "home", "once_cell", - "rustix", + "rustix 0.38.31", ] [[package]] @@ -3416,6 +5187,17 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-targets 0.48.5", +] + [[package]] name = "windows-core" version = "0.52.0" @@ -3425,6 +5207,28 @@ dependencies = [ "windows-targets 0.52.4", ] +[[package]] +name = "windows-implement" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e2ee588991b9e7e6c8338edf3333fbe4da35dc72092643958ebb43f0ab2c49c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "windows-interface" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6fb8df20c9bcaa8ad6ab513f7b40104840c8867d5751126e4df3b08388d0cc7" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "windows-sys" version = "0.33.0" @@ -3438,6 +5242,15 @@ dependencies = [ "windows_x86_64_msvc 0.33.0", ] +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -3456,6 +5269,21 @@ dependencies = [ "windows-targets 0.52.4", ] +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + [[package]] name = "windows-targets" version = "0.48.5" @@ -3486,6 +5314,12 @@ dependencies = [ "windows_x86_64_msvc 0.52.4", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -3504,6 +5338,12 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd761fd3eb9ab8cc1ed81e56e567f02dd82c4c837e48ac3b2181b9ffc5060807" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -3522,6 +5362,12 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cab0cf703a96bab2dc0c02c0fa748491294bf9b7feb27e1f4f96340f208ada0e" +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -3540,6 +5386,12 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cfdbe89cc9ad7ce618ba34abc34bbb6c36d99e96cae2245b7943cd75ee773d0" +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -3558,6 +5410,12 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4dd9b0c0e9ece7bb22e84d70d01b71c6d6248b81a3c60d11869451b4cb24784" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -3570,6 +5428,12 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -3588,6 +5452,12 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff1e4aa646495048ec7f3ffddc411e1d829c026a2ec62b39da15c1055e406eaa" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -3600,6 +5470,50 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +[[package]] +name = "winit" +version = "0.28.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9596d90b45384f5281384ab204224876e8e8bf7d58366d9b795ad99aa9894b94" +dependencies = [ + "android-activity", + "bitflags 1.3.2", + "cfg_aliases", + "core-foundation", + "core-graphics", + "dispatch", + "instant", + "libc", + "log", + "mio", + "ndk", + "objc2 0.3.0-beta.3.patch-leaks.3", + "once_cell", + "orbclient", + "percent-encoding", + "raw-window-handle", + "redox_syscall 0.3.5", + "sctk-adwaita", + "smithay-client-toolkit", + "wasm-bindgen", + "wayland-client", + "wayland-commons", + "wayland-protocols", + "wayland-scanner", + "web-sys", + "windows-sys 0.45.0", + "x11-dl", +] + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + [[package]] name = "wyz" version = "0.5.1" @@ -3609,6 +5523,122 @@ dependencies = [ "tap", ] +[[package]] +name = "x11-dl" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" +dependencies = [ + "libc", + "once_cell", + "pkg-config", +] + +[[package]] +name = "x11rb" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12" +dependencies = [ + "gethostname", + "rustix 0.38.31", + "x11rb-protocol", +] + +[[package]] +name = "x11rb-protocol" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d" + +[[package]] +name = "xcursor" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef33da6b1660b4ddbfb3aef0ade110c8b8a781a3b6382fa5f2b5b040fd55f61" + +[[package]] +name = "xdg-home" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca91dcf8f93db085f3a0a29358cd0b9d670915468f4290e8b85d118a34211ab8" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "xml-rs" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af310deaae937e48a26602b730250b4949e125f468f11e6990be3e5304ddd96f" + +[[package]] +name = "zbus" +version = "3.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "675d170b632a6ad49804c8cf2105d7c31eddd3312555cffd4b740e08e97c25e6" +dependencies = [ + "async-broadcast", + "async-executor", + "async-fs", + "async-io 1.13.0", + "async-lock 2.8.0", + "async-process", + "async-recursion", + "async-task", + "async-trait", + "blocking", + "byteorder", + "derivative", + "enumflags2", + "event-listener 2.5.3", + "futures-core", + "futures-sink", + "futures-util", + "hex", + "nix 0.26.4", + "once_cell", + "ordered-stream", + "rand", + "serde", + "serde_repr", + "sha1", + "static_assertions", + "tracing", + "uds_windows", + "winapi", + "xdg-home", + "zbus_macros", + "zbus_names", + "zvariant", +] + +[[package]] +name = "zbus_macros" +version = "3.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7131497b0f887e8061b430c530240063d33bf9455fa34438f388a245da69e0a5" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "regex", + "syn 1.0.109", + "zvariant_utils", +] + +[[package]] +name = "zbus_names" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "437d738d3750bed6ca9b8d423ccc7a8eb284f6b1d6d4e225a0e4e6258d864c8d" +dependencies = [ + "serde", + "static_assertions", + "zvariant", +] + [[package]] name = "zerocopy" version = "0.7.32" @@ -3662,3 +5692,41 @@ dependencies = [ "serde", "sled", ] + +[[package]] +name = "zvariant" +version = "3.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eef2be88ba09b358d3b58aca6e41cd853631d44787f319a1383ca83424fb2db" +dependencies = [ + "byteorder", + "enumflags2", + "libc", + "serde", + "static_assertions", + "zvariant_derive", +] + +[[package]] +name = "zvariant_derive" +version = "3.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37c24dc0bed72f5f90d1f8bb5b07228cbf63b3c6e9f82d82559d4bae666e7ed9" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", + "zvariant_utils", +] + +[[package]] +name = "zvariant_utils" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7234f0d811589db492d16893e3f21e8e2fd282e6d01b0cddee310322062cc200" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] diff --git a/examples/Cargo.toml b/examples/Cargo.toml index e8afe15..a679a1a 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -1,5 +1,6 @@ [workspace] members = [ - "basic" + "basic", + "tic-tac-toe-gui" ] diff --git a/examples/basic/Cargo.toml b/examples/basic/Cargo.toml index 3a75fb7..29ddd5e 100644 --- a/examples/basic/Cargo.toml +++ b/examples/basic/Cargo.toml @@ -10,3 +10,4 @@ futures = "0.3.30" tokio = { version = "1.36.0", features = ["full"] } tokio-util = { version = "0.7.10", features = ["rt"] } waku = { path = "../../waku-bindings", package = "waku-bindings" } +serde_json = "1.0" diff --git a/examples/basic/src/main.rs b/examples/basic/src/main.rs index 5193431..f7b9a1d 100644 --- a/examples/basic/src/main.rs +++ b/examples/basic/src/main.rs @@ -3,53 +3,78 @@ use std::str::from_utf8; use std::time::SystemTime; use tokio::time::{sleep, Duration}; use waku::{ - waku_destroy, waku_new, Encoding, Event, WakuContentTopic, WakuMessage, WakuNodeConfig, + general::pubsubtopic::PubsubTopic, waku_new, Encoding, Event, LibwakuResponse, + WakuContentTopic, WakuMessage, WakuNodeConfig, }; #[tokio::main] async fn main() -> Result<(), Error> { let node1 = waku_new(Some(WakuNodeConfig { - port: Some(60010), // TODO: use any available port. + tcp_port: Some(60010), // TODO: use any available port. ..Default::default() })) .expect("should instantiate"); let node2 = waku_new(Some(WakuNodeConfig { - port: Some(60020), // TODO: use any available port. + tcp_port: Some(60020), // TODO: use any available port. ..Default::default() })) .expect("should instantiate"); + // ======================================================================== + // Setting an event callback to be executed each time a message is received + node2 + .set_event_callback(|response| { + if let LibwakuResponse::Success(v) = response { + let event: Event = + serde_json::from_str(v.unwrap().as_str()).expect("Parsing event to succeed"); + + match event { + Event::WakuMessage(evt) => { + println!("WakuMessage event received: {:?}", evt.waku_message); + let message = evt.waku_message; + let payload = message.payload.to_vec(); + let msg = from_utf8(&payload).expect("should be valid message"); + println!("::::::::::::::::::::::::::::::::::::::::::::::::::::"); + println!("Message Received in NODE 2: {}", msg); + println!("::::::::::::::::::::::::::::::::::::::::::::::::::::"); + } + Event::Unrecognized(err) => panic!("Unrecognized waku event: {:?}", err), + _ => panic!("event case not expected"), + }; + } + }) + .expect("set event call back working"); + + node1 + .set_event_callback(|response| { + if let LibwakuResponse::Success(v) = response { + let event: Event = + serde_json::from_str(v.unwrap().as_str()).expect("Parsing event to succeed"); + + match event { + Event::WakuMessage(evt) => { + println!("WakuMessage event received: {:?}", evt.waku_message); + let message = evt.waku_message; + let payload = message.payload.to_vec(); + let msg = from_utf8(&payload).expect("should be valid message"); + println!("::::::::::::::::::::::::::::::::::::::::::::::::::::"); + println!("Message Received in NODE 1: {}", msg); + println!("::::::::::::::::::::::::::::::::::::::::::::::::::::"); + } + Event::Unrecognized(err) => panic!("Unrecognized waku event: {:?}", err), + _ => panic!("event case not expected"), + }; + } + }) + .expect("set event call back working"); + let node1 = node1.start().expect("node1 should start"); let node2 = node2.start().expect("node2 should start"); - // ======================================================================== - // Setting an event callback to be executed each time a message is received - node2.set_event_callback(move |event| { - if let Event::WakuMessage(message) = event { - let message = message.waku_message; - let payload = message.payload.to_vec(); - let msg = from_utf8(&payload).expect("should be valid message"); - println!("::::::::::::::::::::::::::::::::::::::::::::::::::::"); - println!("Message Received in NODE 2: {}", msg); - println!("::::::::::::::::::::::::::::::::::::::::::::::::::::"); - } - }); - - node1.set_event_callback(move |event| { - if let Event::WakuMessage(message) = event { - let message = message.waku_message; - let payload = message.payload.to_vec(); - let msg = from_utf8(&payload).expect("should be valid message"); - println!("::::::::::::::::::::::::::::::::::::::::::::::::::::"); - println!("Message Received in NODE 1: {}", msg); - println!("::::::::::::::::::::::::::::::::::::::::::::::::::::"); - } - }); - // ======================================================================== // Subscribe to pubsub topic - let topic = "test".to_string(); + let topic = PubsubTopic::new("test"); node1 .relay_subscribe(&topic) @@ -109,8 +134,8 @@ async fn main() -> Result<(), Error> { // ======================================================================== // Free resources - waku_destroy(node1).expect("should deallocate"); - waku_destroy(node2).expect("should deallocate"); + node1.waku_destroy().expect("should deallocate"); + node2.waku_destroy().expect("should deallocate"); Ok(()) } diff --git a/examples/tic-tac-toe-gui/Cargo.toml b/examples/tic-tac-toe-gui/Cargo.toml new file mode 100644 index 0000000..21e41d9 --- /dev/null +++ b/examples/tic-tac-toe-gui/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "tic-tac-toe-gui" +version = "0.1.0" +edition = "2021" + +[dependencies] +waku = { path = "../../waku-bindings", package = "waku-bindings" } +serde_json = "1.0" +serde = { version = "1.0", features = ["derive"] } +ark-std = "0.4" +ctrlc = "3.2.4" +tokio = { version = "1", features = ["full"] } +tokio-util = "0.6" # for utility functions if needed +egui = "0.22" +eframe = "0.22" +secp256k1 = { version = "0.26", features = ["rand", "recovery", "serde"] } + diff --git a/examples/tic-tac-toe-gui/src/main.rs b/examples/tic-tac-toe-gui/src/main.rs new file mode 100644 index 0000000..553e5dc --- /dev/null +++ b/examples/tic-tac-toe-gui/src/main.rs @@ -0,0 +1,374 @@ +use eframe::egui; +use serde::{Deserialize, Serialize}; +use std::str::from_utf8; +use std::sync::{Arc, Mutex}; +use std::time::{SystemTime, Duration}; + +use tokio::sync::mpsc; +use waku::{ + waku_new, Encoding, Event, LibwakuResponse, WakuContentTopic, + WakuMessage, WakuNodeConfig, WakuNodeHandle, Initialized, Running, + general::pubsubtopic::PubsubTopic, +}; + +#[derive(Serialize, Deserialize, PartialEq, Debug, Copy, Clone)] +enum Player { + X, + O, +} + +#[derive(Serialize, Deserialize, Clone)] +struct GameState { + board: [[Option; 3]; 3], + current_turn: Player, + moves_left: usize, +} + +struct TicTacToeApp { + game_state: Arc>, + waku: WakuNodeHandle, + game_topic: PubsubTopic, + tx: mpsc::Sender, // Sender to send `msg` to main thread + player_role: Option, // Store the player's role (X or O) +} + +impl TicTacToeApp { + fn new( + waku: WakuNodeHandle, + game_topic: PubsubTopic, + game_state: Arc>, + tx: mpsc::Sender, + ) -> Self { + Self { + game_state, + waku, + game_topic, + tx, + player_role: None, + } + } + + fn start(self) -> TicTacToeApp { + let tx_clone = self.tx.clone(); + + let my_closure = move |response| { + if let LibwakuResponse::Success(v) = response { + let event: Event = + serde_json::from_str(v.unwrap().as_str()).expect("Parsing event to succeed"); + + match event { + Event::WakuMessage(evt) => { + // println!("WakuMessage event received: {:?}", evt.waku_message); + let message = evt.waku_message; + let payload = message.payload.to_vec(); + match from_utf8(&payload) { + Ok(msg) => { + // Lock succeeded, proceed to send the message + if tx_clone.blocking_send(msg.to_string()).is_err() { + eprintln!("Failed to send message to async task"); + } + } + Err(e) => { + eprintln!("Failed to decode payload as UTF-8: {}", e); + // Handle the error as needed, or just log and skip + } + } + } + Event::Unrecognized(err) => panic!("Unrecognized waku event: {:?}", err), + _ => panic!("event case not expected"), + }; + } + }; + + // Establish a closure that handles the incoming messages + self.waku.set_event_callback(my_closure).expect("set event call back working"); + + let _ = self.waku.version(); + + // Start the waku node + let waku = self.waku.start().expect("waku should start"); + + // Subscribe to desired topic using the relay protocol + // self.waku.relay_subscribe(&self.game_topic.to_string()).expect("waku should subscribe"); + + let ctopic = WakuContentTopic::new("waku", "2", "tictactoegame", Encoding::Proto); + let content_topics = vec![ctopic]; + waku.filter_subscribe(&self.game_topic, content_topics).expect("waku should subscribe"); + + // Connect to hard-coded node + // let target_node_multi_addr = + // "/ip4/159.223.242.94/tcp/30303/p2p/16Uiu2HAmAUdrQ3uwzuE4Gy4D56hX6uLKEeerJAnhKEHZ3DxF1EfT" + // // "/dns4/store-01.do-ams3.status.prod.status.im/tcp/30303/p2p/16Uiu2HAmAUdrQ3uwzuE4Gy4D56hX6uLKEeerJAnhKEHZ3DxF1EfT" + // // "/ip4/24.144.78.119/tcp/30303/p2p/16Uiu2HAm3xVDaz6SRJ6kErwC21zBJEZjavVXg7VSkoWzaV1aMA3F" + // .parse::().expect("parse multiaddress"); + + // self.waku.connect(&target_node_multi_addr, None) + // .expect("waku should connect to other node"); + + TicTacToeApp { + game_state: self.game_state, + waku: waku, + game_topic: self.game_topic, + tx: self.tx, + player_role: self.player_role, + } + } +} + +impl TicTacToeApp { + fn send_game_state(&self, game_state: &GameState) { + let serialized_game_state = serde_json::to_string(game_state).unwrap(); + let content_topic = WakuContentTopic::new("waku", "2", "tictactoegame", Encoding::Proto); + + let message = WakuMessage::new( + &serialized_game_state, + content_topic, + 0, + SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .unwrap() + .as_millis() + .try_into() + .unwrap(), + Vec::new(), + false, + ); + + // self.waku.relay_publish_message(&message, &self.game_topic.to_string(), None) + // .expect("Failed to send message"); + self.waku.lightpush_publish_message(&message, &self.game_topic).expect("Failed to send message"); + } + + fn make_move(&mut self, row: usize, col: usize) { + if let Ok(mut game_state) = self.game_state.try_lock() { + + if let Some(my_role) = self.player_role { + if (*game_state).current_turn != my_role { + return; // skip click if not my turn + } + } + + if (*game_state).board[row][col].is_none() && (*game_state).moves_left > 0 { + (*game_state).board[row][col] = Some((*game_state).current_turn); + (*game_state).moves_left -= 1; + + if let Some(winner) = self.check_winner(&game_state) { + (*game_state).current_turn = winner; + } else { + (*game_state).current_turn = match (*game_state).current_turn { + Player::X => Player::O, + Player::O => Player::X, + }; + } + + self.send_game_state(&game_state); // Send updated state after a move + } + } + } + + fn check_winner(&self, game_state: &GameState) -> Option { + // Check rows, columns, and diagonals + for i in 0..3 { + if game_state.board[i][0] == game_state.board[i][1] && + game_state.board[i][1] == game_state.board[i][2] { + if let Some(player) = game_state.board[i][0] { + return Some(player); + } + } + if game_state.board[0][i] == game_state.board[1][i] && + game_state.board[1][i] == game_state.board[2][i] { + if let Some(player) = game_state.board[0][i] { + return Some(player); + } + } + } + if game_state.board[0][0] == game_state.board[1][1] && + game_state.board[1][1] == game_state.board[2][2] { + if let Some(player) = game_state.board[0][0] { + return Some(player); + } + } + if game_state.board[0][2] == game_state.board[1][1] && + game_state.board[1][1] == game_state.board[2][0] { + if let Some(player) = game_state.board[0][2] { + return Some(player); + } + } + None + } + + fn reset_game(&mut self) { + self.game_state = Arc::new(Mutex::new(GameState { + board: [[None; 3]; 3], + current_turn: Player::X, + moves_left: 9, + })); + self.player_role = None + } +} + +impl eframe::App for TicTacToeApp { + fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { + + // Request a repaint every second + ctx.request_repaint_after(Duration::from_secs(1)); + + egui::CentralPanel::default().show(ctx, |ui| { + ui.heading("Tic-Tac-Toe"); + + // If the player hasn't selected a role, show the role selection buttons + if self.player_role.is_none() { + ui.label("Select your role:"); + + if ui.button("Play as X").clicked() { + self.player_role = Some(Player::X); + } + + if ui.button("Play as O").clicked() { + self.player_role = Some(Player::O); + if let Ok(mut game_state) = self.game_state.try_lock() { + (*game_state).current_turn = Player::X; // player X should start + } + } + + return; // Exit early until a role is selected + } + + let player_role = self.player_role.unwrap(); // Safe to unwrap because we've ensured it's Some + + // Main game UI + ui.label(format!("You are playing as: {:?}", player_role)); + + // Draw the game board and handle the game state + let board_size = ui.available_size(); + let cell_size = board_size.x / 4.0; + + ui.horizontal(|ui| { + for row in 0..3 { + ui.vertical(|ui| { + for col in 0..3 { + let label; + { + if let Ok(game_state) = self.game_state.try_lock() { + label = match game_state.board[row][col] { + Some(Player::X) => "X", + Some(Player::O) => "O", + None => "-", + }; + } + else { + label = "#"; + } + } + + let button = ui.add(egui::Button::new(label).min_size(egui::vec2(cell_size, cell_size)).sense(egui::Sense::click())); + + if button.clicked() { + self.make_move(row, col); + } + } + }); + if row < 2 { + ui.add_space(4.0); + } + } + }); + + if let Ok(game_state) = self.game_state.try_lock() { + if let Some(winner) = self.check_winner(&game_state) { + ui.label(format!( + "Player {} wins!", + match winner { + Player::X => "X", + Player::O => "O", + } + )); + } else if game_state.moves_left == 0 { + ui.label("It's a tie!"); + } else { + ui.label(format!( + "Player {}'s turn", + match game_state.current_turn { + Player::X => "X", + Player::O => "O", + } + )); + } + } + + if ui.add(egui::Button::new("Restart Game")).clicked() { + self.reset_game(); + } + }); + } +} + +#[tokio::main] +async fn main() -> eframe::Result<()> { + let (tx, mut rx) = mpsc::channel::(3200); // Channel to communicate between threads + + let game_topic = PubsubTopic::new("/waku/2/rs/16/32"); + // Create a Waku instance + let waku = waku_new(Some(WakuNodeConfig { + tcp_port: Some(60010), + cluster_id: Some(16), + shards: vec![1, 32, 64, 128, 256], + // node_key: Some(SecretKey::from_str("2fc0515879e52b7b73297cfd6ab3abf7c344ef84b7a90ff6f4cc19e05a198027").unwrap()), + max_message_size: Some("1024KiB".to_string()), + relay_topics: vec![String::from(&game_topic)], + log_level: Some("DEBUG"), // Supported: TRACE, DEBUG, INFO, NOTICE, WARN, ERROR or FATAL + + keep_alive: Some(true), + + // Discovery + dns_discovery: Some(true), + dns_discovery_url: Some("enrtree://AMOJVZX4V6EXP7NTJPMAYJYST2QP6AJXYW76IU6VGJS7UVSNDYZG4@boot.prod.status.nodes.status.im"), + // discv5_discovery: Some(true), + // discv5_udp_port: Some(9001), + // discv5_enr_auto_update: Some(false), + + ..Default::default() + })) + .expect("should instantiate"); + + let game_state = GameState { + board: [[None; 3]; 3], + current_turn: Player::X, + moves_left: 9, + }; + let shared_state = Arc::new(Mutex::new(game_state)); + + let clone = shared_state.clone(); + let app = TicTacToeApp::new(waku, game_topic, clone, tx); + + let app = app.start(); + + let clone = shared_state.clone(); + // Listen for messages in the main thread + tokio::spawn(async move { + while let Some(msg) = rx.recv().await { + // println!("MSG received: {}", msg); + // Handle the received message, e.g., update the UI or game state + if let Ok(parsed_value) = serde_json::from_str::(&msg) + { + if let Ok(mut unclocked_game_state) = clone.lock(){ + *unclocked_game_state = parsed_value; + } + } + else { + eprintln!("Failed to parse JSON"); + } + } + }); + + eframe::run_native( + "Tic-Tac-Toe Multiplayer via Waku", + eframe::NativeOptions { + initial_window_size: Some(egui::vec2(400.0, 400.0)), + ..Default::default() + }, + Box::new(|_cc| Box::new(app)), + )?; + + Ok(()) +} diff --git a/waku-bindings/Cargo.toml b/waku-bindings/Cargo.toml index d709db1..58c5830 100644 --- a/waku-bindings/Cargo.toml +++ b/waku-bindings/Cargo.toml @@ -31,6 +31,8 @@ waku-sys = { version = "0.5.0", path = "../waku-sys" } libc = "0.2" serde-aux = "4.3.1" rln = "0.3.4" +tokio = { version = "1", features = ["full"] } +regex = "1" [dev-dependencies] futures = "0.3.25" diff --git a/waku-bindings/src/general/contenttopic.rs b/waku-bindings/src/general/contenttopic.rs new file mode 100644 index 0000000..381f57a --- /dev/null +++ b/waku-bindings/src/general/contenttopic.rs @@ -0,0 +1,134 @@ +// std +use std::borrow::Cow; +use std::fmt::{Display, Formatter}; +use std::str::FromStr; + +use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer}; + +use sscanf::{scanf, RegexRepresentation}; + +/// WakuMessage encoding scheme +#[derive(Clone, Debug, Eq, PartialEq, Default)] +pub enum Encoding { + #[default] + Proto, + Rlp, + Rfc26, + Unknown(String), +} + +impl Display for Encoding { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let s = match self { + Encoding::Proto => "proto", + Encoding::Rlp => "rlp", + Encoding::Rfc26 => "rfc26", + Encoding::Unknown(value) => value, + }; + f.write_str(s) + } +} + +impl FromStr for Encoding { + type Err = std::io::Error; + + fn from_str(s: &str) -> std::result::Result { + match s.to_lowercase().as_str() { + "proto" => Ok(Self::Proto), + "rlp" => Ok(Self::Rlp), + "rfc26" => Ok(Self::Rfc26), + encoding => Ok(Self::Unknown(encoding.to_string())), + } + } +} + +impl RegexRepresentation for Encoding { + const REGEX: &'static str = r"\w"; +} + +/// A waku content topic `/{application_name}/{version}/{content_topic_name}/{encdoing}` +#[derive(Clone, Debug, Eq, PartialEq, Default)] +pub struct WakuContentTopic { + pub application_name: Cow<'static, str>, + pub version: Cow<'static, str>, + pub content_topic_name: Cow<'static, str>, + pub encoding: Encoding, +} + +impl WakuContentTopic { + pub const fn new( + application_name: &'static str, + version: &'static str, + content_topic_name: &'static str, + encoding: Encoding, + ) -> Self { + Self { + application_name: Cow::Borrowed(application_name), + version: Cow::Borrowed(version), + content_topic_name: Cow::Borrowed(content_topic_name), + encoding, + } + } + + pub fn join_content_topics(topics: Vec) -> String { + topics + .iter() + .map(|topic| topic.to_string()) + .collect::>() + .join(",") + } +} + +impl FromStr for WakuContentTopic { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + if let Ok((application_name, version, content_topic_name, encoding)) = + scanf!(s, "/{}/{}/{}/{:/.+?/}", String, String, String, Encoding) + { + Ok(WakuContentTopic { + application_name: Cow::Owned(application_name), + version: Cow::Owned(version), + content_topic_name: Cow::Owned(content_topic_name), + encoding, + }) + } else { + Err( + format!( + "Wrong pub-sub topic format. Should be `/{{application-name}}/{{version-of-the-application}}/{{content-topic-name}}/{{encoding}}`. Got: {s}" + ) + ) + } + } +} + +impl Display for WakuContentTopic { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!( + f, + "/{}/{}/{}/{}", + self.application_name, self.version, self.content_topic_name, self.encoding + ) + } +} + +impl Serialize for WakuContentTopic { + fn serialize(&self, serializer: S) -> std::result::Result + where + S: Serializer, + { + self.to_string().serialize(serializer) + } +} + +impl<'de> Deserialize<'de> for WakuContentTopic { + fn deserialize(deserializer: D) -> std::result::Result + where + D: Deserializer<'de>, + { + let as_string: String = String::deserialize(deserializer)?; + as_string + .parse::() + .map_err(D::Error::custom) + } +} diff --git a/waku-bindings/src/general/mod.rs b/waku-bindings/src/general/mod.rs index bd880a7..90a6724 100644 --- a/waku-bindings/src/general/mod.rs +++ b/waku-bindings/src/general/mod.rs @@ -1,26 +1,24 @@ //! Waku [general](https://rfc.vac.dev/spec/36/#general) types -// std -use std::borrow::Cow; -use std::fmt::{Display, Formatter}; -use std::str::FromStr; +pub mod contenttopic; +pub mod pubsubtopic; + // crates -use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer}; +use contenttopic::WakuContentTopic; +use serde::{Deserialize, Serialize}; use serde_aux::prelude::*; -use sscanf::{scanf, RegexRepresentation}; /// Waku message version pub type WakuMessageVersion = usize; /// Waku message hash, hex encoded sha256 digest of the message pub type MessageHash = String; -/// Waku response, just a `Result` with an `String` error. pub type Result = std::result::Result; // TODO: Properly type and deserialize payload form base64 encoded string /// Waku message in JSON format. /// as per the [specification](https://rfc.vac.dev/spec/36/#jsonmessage-type) -#[derive(Clone, Serialize, Deserialize, Debug)] +#[derive(Clone, Serialize, Deserialize, Debug, Default)] #[serde(rename_all = "camelCase")] pub struct WakuMessage { #[serde(with = "base64_serde", default = "Vec::new")] @@ -66,123 +64,6 @@ impl WakuMessage { } } -/// WakuMessage encoding scheme -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum Encoding { - Proto, - Rlp, - Rfc26, - Unknown(String), -} - -impl Display for Encoding { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - let s = match self { - Encoding::Proto => "proto", - Encoding::Rlp => "rlp", - Encoding::Rfc26 => "rfc26", - Encoding::Unknown(value) => value, - }; - f.write_str(s) - } -} - -impl FromStr for Encoding { - type Err = std::io::Error; - - fn from_str(s: &str) -> std::result::Result { - match s.to_lowercase().as_str() { - "proto" => Ok(Self::Proto), - "rlp" => Ok(Self::Rlp), - "rfc26" => Ok(Self::Rfc26), - encoding => Ok(Self::Unknown(encoding.to_string())), - } - } -} - -impl RegexRepresentation for Encoding { - const REGEX: &'static str = r"\w"; -} - -/// A waku content topic `/{application_name}/{version}/{content_topic_name}/{encdoing}` -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct WakuContentTopic { - pub application_name: Cow<'static, str>, - pub version: Cow<'static, str>, - pub content_topic_name: Cow<'static, str>, - pub encoding: Encoding, -} - -impl WakuContentTopic { - pub const fn new( - application_name: &'static str, - version: &'static str, - content_topic_name: &'static str, - encoding: Encoding, - ) -> Self { - Self { - application_name: Cow::Borrowed(application_name), - version: Cow::Borrowed(version), - content_topic_name: Cow::Borrowed(content_topic_name), - encoding, - } - } -} - -impl FromStr for WakuContentTopic { - type Err = String; - - fn from_str(s: &str) -> std::result::Result { - if let Ok((application_name, version, content_topic_name, encoding)) = - scanf!(s, "/{}/{}/{}/{:/.+?/}", String, String, String, Encoding) - { - Ok(WakuContentTopic { - application_name: Cow::Owned(application_name), - version: Cow::Owned(version), - content_topic_name: Cow::Owned(content_topic_name), - encoding, - }) - } else { - Err( - format!( - "Wrong pub-sub topic format. Should be `/{{application-name}}/{{version-of-the-application}}/{{content-topic-name}}/{{encoding}}`. Got: {s}" - ) - ) - } - } -} - -impl Display for WakuContentTopic { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!( - f, - "/{}/{}/{}/{}", - self.application_name, self.version, self.content_topic_name, self.encoding - ) - } -} - -impl Serialize for WakuContentTopic { - fn serialize(&self, serializer: S) -> std::result::Result - where - S: Serializer, - { - self.to_string().serialize(serializer) - } -} - -impl<'de> Deserialize<'de> for WakuContentTopic { - fn deserialize(deserializer: D) -> std::result::Result - where - D: Deserializer<'de>, - { - let as_string: String = String::deserialize(deserializer)?; - as_string - .parse::() - .map_err(D::Error::custom) - } -} - mod base64_serde { use base64::Engine; use serde::de::Error; diff --git a/waku-bindings/src/general/pubsubtopic.rs b/waku-bindings/src/general/pubsubtopic.rs new file mode 100644 index 0000000..c3adc56 --- /dev/null +++ b/waku-bindings/src/general/pubsubtopic.rs @@ -0,0 +1,16 @@ +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct PubsubTopic(String); + +impl PubsubTopic { + // Constructor to create a new MyString + pub fn new(value: &str) -> Self { + PubsubTopic(value.to_string()) + } +} + +// to allow conversion from `PubsubTopic` to `String` +impl From<&PubsubTopic> for String { + fn from(topic: &PubsubTopic) -> Self { + topic.0.to_string() + } +} diff --git a/waku-bindings/src/lib.rs b/waku-bindings/src/lib.rs index eee8841..dc14d4b 100644 --- a/waku-bindings/src/lib.rs +++ b/waku-bindings/src/lib.rs @@ -1,9 +1,12 @@ //! # Waku //! //! Implementation on top of [`waku-bindings`](https://rfc.vac.dev/spec/36/) -mod general; -mod node; -mod utils; +pub mod general; +pub mod node; +pub mod utils; + +// Re-export the LibwakuResponse type to make it accessible outside this module +pub use utils::LibwakuResponse; // Required so functions inside libwaku can call RLN functions even if we // use it within the bindings functions @@ -12,10 +15,9 @@ mod utils; use rln; pub use node::{ - waku_create_content_topic, waku_destroy, waku_new, Event, Initialized, Key, Multiaddr, - PublicKey, RLNConfig, Running, SecretKey, WakuMessageEvent, WakuNodeConfig, WakuNodeHandle, + waku_create_content_topic, waku_new, Event, Initialized, Key, Multiaddr, PublicKey, RLNConfig, + Running, SecretKey, WakuMessageEvent, WakuNodeConfig, WakuNodeHandle, }; -pub use general::{ - Encoding, MessageHash, Result, WakuContentTopic, WakuMessage, WakuMessageVersion, -}; +pub use general::contenttopic::{Encoding, WakuContentTopic}; +pub use general::{MessageHash, Result, WakuMessage, WakuMessageVersion}; diff --git a/waku-bindings/src/node/config.rs b/waku-bindings/src/node/config.rs index eb9e5c0..8d26f3b 100644 --- a/waku-bindings/src/node/config.rs +++ b/waku-bindings/src/node/config.rs @@ -16,20 +16,45 @@ pub struct WakuNodeConfig { pub host: Option, /// Libp2p TCP listening port. Default `60000`. Use `0` for **random** #[default(Some(60000))] - pub port: Option, + pub tcp_port: Option, /// Secp256k1 private key in Hex format (`0x123...abc`). Default random #[serde(with = "secret_key_serde", rename = "key")] pub node_key: Option, /// Cluster id that the node is running in #[default(Some(0))] pub cluster_id: Option, - /// Enable relay protocol. Default `true` + + /// Relay protocol #[default(Some(true))] pub relay: Option, pub relay_topics: Vec, + #[default(vec![1])] + pub shards: Vec, + #[serde(skip_serializing_if = "Option::is_none")] + pub max_message_size: Option, + /// RLN configuration #[serde(skip_serializing_if = "Option::is_none")] pub rln_relay: Option, + + // Discovery + #[default(Some(false))] + pub dns_discovery: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub dns_discovery_url: Option<&'static str>, + + #[default(Some(false))] + pub discv5_discovery: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub discv5_udp_port: Option, + #[default(Some(false))] + pub discv5_enr_auto_update: Option, + + // other settings + #[serde(skip_serializing_if = "Option::is_none")] + pub log_level: Option<&'static str>, + #[serde(skip_serializing_if = "Option::is_none")] + pub keep_alive: Option, } /// RLN Relay configuration diff --git a/waku-bindings/src/node/context.rs b/waku-bindings/src/node/context.rs index 846ae67..5305a4a 100644 --- a/waku-bindings/src/node/context.rs +++ b/waku-bindings/src/node/context.rs @@ -1,6 +1,62 @@ -// crates -use libc::c_void; +use std::ffi::c_void; +use std::ptr::null_mut; +use std::sync::{Arc, Mutex}; + +use crate::utils::{get_trampoline, LibwakuResponse}; + +type LibwakuResponseClosure = dyn FnMut(LibwakuResponse) + Send + Sync; pub struct WakuNodeContext { - pub obj_ptr: *mut c_void, + obj_ptr: *mut c_void, + msg_observer: Arc>>, +} + +impl WakuNodeContext { + pub fn new(obj_ptr: *mut c_void) -> Self { + let me = Self { + obj_ptr, + msg_observer: Arc::new(Mutex::new(Box::new(|_| {}))), + }; + + // By default we set a callback that will panic if the user didn't specify a valid callback. + // And by valid callback we mean a callback that can properly handle the waku events. + me.waku_set_event_callback(WakuNodeContext::panic_callback) + .expect("correctly set default callback"); + me + } + + // default callback that does nothing. A valid callback should be set + fn panic_callback(_response: LibwakuResponse) { + panic!("callback not set. Please use waku_set_event_callback to set a valid callback") + } + + pub fn get_ptr(&self) -> *mut c_void { + self.obj_ptr + } + + pub fn reset_ptr(mut self) { + self.obj_ptr = null_mut(); + } + + /// Register callback to act as event handler and receive application events, + /// which are used to react to asynchronous events in Waku + pub fn waku_set_event_callback( + &self, + closure: F, + ) -> Result<(), String> { + if let Ok(mut boxed_closure) = self.msg_observer.lock() { + *boxed_closure = Box::new(closure); + unsafe { + let cb = get_trampoline(&(*boxed_closure)); + waku_sys::waku_set_event_callback( + self.obj_ptr, + cb, + &mut (*boxed_closure) as *mut _ as *mut c_void, + ) + }; + Ok(()) + } else { + Err("Failed to acquire lock in waku_set_event_callback!".to_string()) + } + } } diff --git a/waku-bindings/src/node/events.rs b/waku-bindings/src/node/events.rs index fd71b7a..2ee759c 100644 --- a/waku-bindings/src/node/events.rs +++ b/waku-bindings/src/node/events.rs @@ -4,20 +4,18 @@ //! An example of an asynchronous event that might be emitted is receiving a message. //! When an event is emitted, this callback will be triggered receiving an [`Event`] -// std -use std::ffi::c_void; // crates use serde::{Deserialize, Serialize}; // internal use crate::general::WakuMessage; -use crate::node::context::WakuNodeContext; -use crate::utils::{get_trampoline, LibwakuResponse}; +use std::str; + use crate::MessageHash; /// Waku event /// For now just WakuMessage is supported #[non_exhaustive] -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Debug)] #[serde(tag = "eventType", rename_all = "camelCase")] pub enum Event { #[serde(rename = "message")] @@ -26,7 +24,7 @@ pub enum Event { } /// Type of `event` field for a `message` event -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Debug)] #[serde(rename_all = "camelCase")] pub struct WakuMessageEvent { /// The pubsub topic on which the message was received @@ -37,25 +35,6 @@ pub struct WakuMessageEvent { pub waku_message: WakuMessage, } -/// Register callback to act as event handler and receive application events, -/// which are used to react to asynchronous events in Waku -pub fn waku_set_event_callback(ctx: &WakuNodeContext, mut f: F) { - let cb = |response: LibwakuResponse| { - if let LibwakuResponse::Success(v) = response { - let data: Event = - serde_json::from_str(v.unwrap().as_str()).expect("Parsing event to succeed"); - f(data); - }; - }; - - unsafe { - let mut closure = cb; - let cb = get_trampoline(&closure); - - waku_sys::waku_set_event_callback(ctx.obj_ptr, cb, &mut closure as *mut _ as *mut c_void) - }; -} - #[cfg(test)] mod tests { use crate::Event; diff --git a/waku-bindings/src/node/filter.rs b/waku-bindings/src/node/filter.rs new file mode 100644 index 0000000..9bf0208 --- /dev/null +++ b/waku-bindings/src/node/filter.rs @@ -0,0 +1,100 @@ +//! Waku filter protocol related methods + +// std +use std::ffi::CString; +// crates +use libc::*; +// internal +use crate::general::contenttopic::WakuContentTopic; +use crate::general::pubsubtopic::PubsubTopic; +use crate::general::Result; +use crate::node::context::WakuNodeContext; +use crate::utils::{get_trampoline, handle_no_response, LibwakuResponse}; + +pub fn waku_filter_subscribe( + ctx: &WakuNodeContext, + pubsub_topic: &PubsubTopic, + content_topics: Vec, +) -> Result<()> { + let content_topics = WakuContentTopic::join_content_topics(content_topics); + + let pubsub_topic_ptr = CString::new(String::from(pubsub_topic)) + .expect("CString should build properly from pubsub topic") + .into_raw(); + let content_topics_ptr = CString::new(content_topics) + .expect("CString should build properly from content topic") + .into_raw(); + + let mut result: LibwakuResponse = Default::default(); + let result_cb = |r: LibwakuResponse| result = r; + let code = unsafe { + let mut closure = result_cb; + let cb = get_trampoline(&closure); + let out = waku_sys::waku_filter_subscribe( + ctx.get_ptr(), + pubsub_topic_ptr, + content_topics_ptr, + cb, + &mut closure as *mut _ as *mut c_void, + ); + + drop(CString::from_raw(pubsub_topic_ptr)); + drop(CString::from_raw(content_topics_ptr)); + + out + }; + + handle_no_response(code, result) +} + +pub fn waku_filter_unsubscribe( + ctx: &WakuNodeContext, + pubsub_topic: &PubsubTopic, + content_topics: Vec, // comma-separated list of content topics +) -> Result<()> { + let content_topics_topics = WakuContentTopic::join_content_topics(content_topics); + + let pubsub_topic_ptr = CString::new(String::from(pubsub_topic)) + .expect("CString should build properly from pubsub topic") + .into_raw(); + let content_topics_topics_ptr = CString::new(content_topics_topics) + .expect("CString should build properly from content topic") + .into_raw(); + + let mut result: LibwakuResponse = Default::default(); + let result_cb = |r: LibwakuResponse| result = r; + let code = unsafe { + let mut closure = result_cb; + let cb = get_trampoline(&closure); + let out = waku_sys::waku_filter_unsubscribe( + ctx.get_ptr(), + pubsub_topic_ptr, + content_topics_topics_ptr, + cb, + &mut closure as *mut _ as *mut c_void, + ); + + drop(CString::from_raw(pubsub_topic_ptr)); + drop(CString::from_raw(content_topics_topics_ptr)); + + out + }; + + handle_no_response(code, result) +} + +pub fn waku_filter_unsubscribe_all(ctx: &WakuNodeContext) -> Result<()> { + let mut result: LibwakuResponse = Default::default(); + let result_cb = |r: LibwakuResponse| result = r; + let code = unsafe { + let mut closure = result_cb; + let cb = get_trampoline(&closure); + waku_sys::waku_filter_unsubscribe_all( + ctx.get_ptr(), + cb, + &mut closure as *mut _ as *mut c_void, + ) + }; + + handle_no_response(code, result) +} diff --git a/waku-bindings/src/node/lightpush.rs b/waku-bindings/src/node/lightpush.rs new file mode 100644 index 0000000..925c01c --- /dev/null +++ b/waku-bindings/src/node/lightpush.rs @@ -0,0 +1,49 @@ +//! Waku lightpush protocol related methods + +// std +use std::ffi::CString; +// crates +use libc::*; +// internal +use crate::general::{MessageHash, Result, WakuMessage}; +use crate::node::context::WakuNodeContext; +use crate::utils::{get_trampoline, handle_response, LibwakuResponse}; + +use crate::general::pubsubtopic::PubsubTopic; + +pub fn waku_lightpush_publish_message( + ctx: &WakuNodeContext, + message: &WakuMessage, + pubsub_topic: &PubsubTopic, +) -> Result { + let message_ptr = CString::new( + serde_json::to_string(&message) + .expect("WakuMessages should always be able to success serializing"), + ) + .expect("CString should build properly from the serialized waku message") + .into_raw(); + let pubsub_topic_ptr = CString::new(String::from(pubsub_topic)) + .expect("CString should build properly from pubsub topic") + .into_raw(); + + let mut result: LibwakuResponse = Default::default(); + let result_cb = |r: LibwakuResponse| result = r; + let code = unsafe { + let mut closure = result_cb; + let cb = get_trampoline(&closure); + let out = waku_sys::waku_lightpush_publish( + ctx.get_ptr(), + pubsub_topic_ptr, + message_ptr, + cb, + &mut closure as *mut _ as *mut c_void, + ); + + drop(CString::from_raw(message_ptr)); + drop(CString::from_raw(pubsub_topic_ptr)); + + out + }; + + handle_response(code, result) +} diff --git a/waku-bindings/src/node/management.rs b/waku-bindings/src/node/management.rs index 3e4cd59..eb30998 100644 --- a/waku-bindings/src/node/management.rs +++ b/waku-bindings/src/node/management.rs @@ -10,13 +10,17 @@ use super::config::WakuNodeConfig; use crate::general::Result; use crate::node::context::WakuNodeContext; use crate::utils::LibwakuResponse; +use crate::utils::WakuDecode; use crate::utils::{get_trampoline, handle_json_response, handle_no_response, handle_response}; /// Instantiates a Waku node /// as per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_newchar-jsonconfig) pub fn waku_new(config: Option) -> Result { - let config = config.unwrap_or_default(); + unsafe { + waku_sys::waku_setup(); + } + let config = config.unwrap_or_default(); let config_ptr = CString::new( serde_json::to_string(&config) .expect("Serialization from properly built NodeConfig should never fail"), @@ -39,7 +43,7 @@ pub fn waku_new(config: Option) -> Result { match result { LibwakuResponse::MissingCallback => panic!("callback is required"), LibwakuResponse::Failure(v) => Err(v), - _ => Ok(WakuNodeContext { obj_ptr }), + _ => Ok(WakuNodeContext::new(obj_ptr)), } } @@ -49,7 +53,7 @@ pub fn waku_destroy(ctx: &WakuNodeContext) -> Result<()> { let code = unsafe { let mut closure = result_cb; let cb = get_trampoline(&closure); - waku_sys::waku_destroy(ctx.obj_ptr, cb, &mut closure as *mut _ as *mut c_void) + waku_sys::waku_destroy(ctx.get_ptr(), cb, &mut closure as *mut _ as *mut c_void) }; handle_no_response(code, result) @@ -63,7 +67,7 @@ pub fn waku_start(ctx: &WakuNodeContext) -> Result<()> { let code = unsafe { let mut closure = result_cb; let cb = get_trampoline(&closure); - waku_sys::waku_start(ctx.obj_ptr, cb, &mut closure as *mut _ as *mut c_void) + waku_sys::waku_start(ctx.get_ptr(), cb, &mut closure as *mut _ as *mut c_void) }; handle_no_response(code, result) @@ -77,7 +81,7 @@ pub fn waku_stop(ctx: &WakuNodeContext) -> Result<()> { let code = unsafe { let mut closure = result_cb; let cb = get_trampoline(&closure); - waku_sys::waku_stop(ctx.obj_ptr, cb, &mut closure as *mut _ as *mut c_void) + waku_sys::waku_stop(ctx.get_ptr(), cb, &mut closure as *mut _ as *mut c_void) }; handle_no_response(code, result) @@ -91,12 +95,23 @@ pub fn waku_version(ctx: &WakuNodeContext) -> Result { let code = unsafe { let mut closure = result_cb; let cb = get_trampoline(&closure); - waku_sys::waku_version(ctx.obj_ptr, cb, &mut closure as *mut _ as *mut c_void) + waku_sys::waku_version(ctx.get_ptr(), cb, &mut closure as *mut _ as *mut c_void) }; handle_response(code, result) } +// Implement WakuDecode for Vec +impl WakuDecode for Vec { + fn decode(input: &str) -> Result { + input + .split(',') + .map(|s| s.trim().parse::().map_err(|err| err.to_string())) + .collect::>>() // Collect results into a Vec + .map_err(|err| format!("could not parse Multiaddr: {}", err)) + } +} + /// Get the multiaddresses the Waku node is listening to /// as per [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_listen_addresses) pub fn waku_listen_addresses(ctx: &WakuNodeContext) -> Result> { @@ -105,7 +120,7 @@ pub fn waku_listen_addresses(ctx: &WakuNodeContext) -> Result> { let code = unsafe { let mut closure = result_cb; let cb = get_trampoline(&closure); - waku_sys::waku_listen_addresses(ctx.obj_ptr, cb, &mut closure as *mut _ as *mut c_void) + waku_sys::waku_listen_addresses(ctx.get_ptr(), cb, &mut closure as *mut _ as *mut c_void) }; handle_json_response(code, result) @@ -137,6 +152,7 @@ mod test { fn nwaku_version() { let node = waku_new(None).unwrap(); let version = waku_version(&node).expect("should return the version"); + print!("Current version: {}", version); assert!(!version.is_empty()); } } diff --git a/waku-bindings/src/node/mod.rs b/waku-bindings/src/node/mod.rs index 817e34b..72cda20 100644 --- a/waku-bindings/src/node/mod.rs +++ b/waku-bindings/src/node/mod.rs @@ -3,6 +3,8 @@ mod config; mod context; mod events; +mod filter; +mod lightpush; mod management; mod peers; mod relay; @@ -14,30 +16,27 @@ pub use secp256k1::{PublicKey, SecretKey}; use std::marker::PhantomData; use std::time::Duration; // internal +use crate::general::contenttopic::{Encoding, WakuContentTopic}; +pub use crate::general::pubsubtopic::PubsubTopic; use crate::general::{MessageHash, Result, WakuMessage}; -use context::WakuNodeContext; +use crate::utils::LibwakuResponse; +use crate::node::context::WakuNodeContext; pub use config::RLNConfig; pub use config::WakuNodeConfig; pub use events::{Event, WakuMessageEvent}; pub use relay::waku_create_content_topic; -/// Marker trait to disallow undesired waku node states in the handle -pub trait WakuNodeState {} +use std::time::SystemTime; -/// Waku node initialized state +// Define state marker types pub struct Initialized; - -/// Waku node running state pub struct Running; -impl WakuNodeState for Initialized {} -impl WakuNodeState for Running {} - /// Handle to the underliying waku node -pub struct WakuNodeHandle { +pub struct WakuNodeHandle { ctx: WakuNodeContext, - phantom: PhantomData, + _state: PhantomData, } /// Spawn a new Waku node with the given configuration (default configuration if `None` provided) @@ -45,12 +44,21 @@ pub struct WakuNodeHandle { pub fn waku_new(config: Option) -> Result> { Ok(WakuNodeHandle { ctx: management::waku_new(config)?, - phantom: PhantomData, + _state: PhantomData, }) } -pub fn waku_destroy(node: WakuNodeHandle) -> Result<()> { - management::waku_destroy(&node.ctx) +impl WakuNodeHandle { + /// Get the nwaku version + pub fn version(&self) -> Result { + management::waku_version(&self.ctx) + } + + pub fn waku_destroy(self) -> Result<()> { + let res = management::waku_destroy(&self.ctx); + self.ctx.reset_ptr(); + res + } } impl WakuNodeHandle { @@ -59,9 +67,16 @@ impl WakuNodeHandle { pub fn start(self) -> Result> { management::waku_start(&self.ctx).map(|_| WakuNodeHandle { ctx: self.ctx, - phantom: PhantomData, + _state: PhantomData, }) } + + pub fn set_event_callback( + &self, + closure: F, + ) -> Result<()> { + self.ctx.waku_set_event_callback(closure) + } } impl WakuNodeHandle { @@ -70,7 +85,7 @@ impl WakuNodeHandle { pub fn stop(self) -> Result> { management::waku_stop(&self.ctx).map(|_| WakuNodeHandle { ctx: self.ctx, - phantom: PhantomData, + _state: PhantomData, }) } @@ -80,11 +95,6 @@ impl WakuNodeHandle { management::waku_listen_addresses(&self.ctx) } - /// Get the nwaku version - pub fn version(&self) -> Result { - management::waku_version(&self.ctx) - } - /// Dial peer using a multiaddress /// If `timeout` as milliseconds doesn't fit into a `i32` it is clamped to [`i32::MAX`] /// If the function execution takes longer than `timeout` value, the execution will be canceled and an error returned. @@ -94,29 +104,78 @@ impl WakuNodeHandle { peers::waku_connect(&self.ctx, address, timeout) } + pub fn relay_publish_txt( + &self, + pubsub_topic: &PubsubTopic, + msg_txt: &String, + content_topic_name: &'static str, + timeout: Option, + ) -> Result { + let content_topic = WakuContentTopic::new("waku", "2", content_topic_name, Encoding::Proto); + let message = WakuMessage::new( + msg_txt, + content_topic, + 0, + SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .unwrap() + .as_millis() + .try_into() + .unwrap(), + Vec::new(), + false, + ); + + relay::waku_relay_publish_message(&self.ctx, &message, pubsub_topic, timeout) + } + /// Publish a message using Waku Relay. /// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_relay_publishchar-messagejson-char-pubsubtopic-int-timeoutms) /// The pubsub_topic parameter is optional and if not specified it will be derived from the contentTopic. pub fn relay_publish_message( &self, message: &WakuMessage, - pubsub_topic: &String, + pubsub_topic: &PubsubTopic, timeout: Option, ) -> Result { relay::waku_relay_publish_message(&self.ctx, message, pubsub_topic, timeout) } /// Subscribe to WakuRelay to receive messages matching a content filter. - pub fn relay_subscribe(&self, pubsub_topic: &String) -> Result<()> { + pub fn relay_subscribe(&self, pubsub_topic: &PubsubTopic) -> Result<()> { relay::waku_relay_subscribe(&self.ctx, pubsub_topic) } /// Closes the pubsub subscription to stop receiving messages matching a content filter. No more messages will be received from this pubsub topic - pub fn relay_unsubscribe(&self, pubsub_topic: &String) -> Result<()> { + pub fn relay_unsubscribe(&self, pubsub_topic: &PubsubTopic) -> Result<()> { relay::waku_relay_unsubscribe(&self.ctx, pubsub_topic) } - pub fn set_event_callback(&self, f: F) { - events::waku_set_event_callback(&self.ctx, f) + pub fn filter_subscribe( + &self, + pubsub_topic: &PubsubTopic, + content_topics: Vec, + ) -> Result<()> { + filter::waku_filter_subscribe(&self.ctx, pubsub_topic, content_topics) + } + + pub fn filter_unsubscribe( + &self, + pubsub_topic: &PubsubTopic, + content_topics: Vec, + ) -> Result<()> { + filter::waku_filter_unsubscribe(&self.ctx, pubsub_topic, content_topics) + } + + pub fn filter_unsubscribe_all(&self) -> Result<()> { + filter::waku_filter_unsubscribe_all(&self.ctx) + } + + pub fn lightpush_publish_message( + &self, + message: &WakuMessage, + pubsub_topic: &PubsubTopic, + ) -> Result { + lightpush::waku_lightpush_publish_message(&self.ctx, message, pubsub_topic) } } diff --git a/waku-bindings/src/node/peers.rs b/waku-bindings/src/node/peers.rs index 2fa1087..a5bf0ef 100644 --- a/waku-bindings/src/node/peers.rs +++ b/waku-bindings/src/node/peers.rs @@ -32,7 +32,7 @@ pub fn waku_connect( let mut closure = result_cb; let cb = get_trampoline(&closure); let out = waku_sys::waku_connect( - ctx.obj_ptr, + ctx.get_ptr(), address_ptr, timeout .map(|duration| duration.as_millis().try_into().unwrap_or(u32::MAX)) diff --git a/waku-bindings/src/node/relay.rs b/waku-bindings/src/node/relay.rs index e42caf4..d945a61 100644 --- a/waku-bindings/src/node/relay.rs +++ b/waku-bindings/src/node/relay.rs @@ -6,7 +6,9 @@ use std::time::Duration; // crates use libc::*; // internal -use crate::general::{Encoding, MessageHash, Result, WakuContentTopic, WakuMessage}; +use crate::general::contenttopic::{Encoding, WakuContentTopic}; +use crate::general::pubsubtopic::PubsubTopic; +use crate::general::{MessageHash, Result, WakuMessage}; use crate::node::context::WakuNodeContext; use crate::utils::{get_trampoline, handle_no_response, handle_response, LibwakuResponse}; @@ -36,7 +38,7 @@ pub fn waku_create_content_topic( let mut closure = result_cb; let cb = get_trampoline(&closure); let out = waku_sys::waku_content_topic( - ctx.obj_ptr, + ctx.get_ptr(), application_name_ptr, application_version, content_topic_name_ptr, @@ -60,18 +62,16 @@ pub fn waku_create_content_topic( pub fn waku_relay_publish_message( ctx: &WakuNodeContext, message: &WakuMessage, - pubsub_topic: &String, + pubsub_topic: &PubsubTopic, timeout: Option, ) -> Result { - let pubsub_topic = pubsub_topic.to_string(); - let message_ptr = CString::new( serde_json::to_string(&message) .expect("WakuMessages should always be able to success serializing"), ) .expect("CString should build properly from the serialized waku message") .into_raw(); - let pubsub_topic_ptr = CString::new(pubsub_topic) + let pubsub_topic_ptr = CString::new(String::from(pubsub_topic)) .expect("CString should build properly from pubsub topic") .into_raw(); @@ -81,7 +81,7 @@ pub fn waku_relay_publish_message( let mut closure = result_cb; let cb = get_trampoline(&closure); let out = waku_sys::waku_relay_publish( - ctx.obj_ptr, + ctx.get_ptr(), pubsub_topic_ptr, message_ptr, timeout @@ -105,9 +105,8 @@ pub fn waku_relay_publish_message( handle_response(code, result) } -pub fn waku_relay_subscribe(ctx: &WakuNodeContext, pubsub_topic: &String) -> Result<()> { - let pubsub_topic = pubsub_topic.to_string(); - let pubsub_topic_ptr = CString::new(pubsub_topic) +pub fn waku_relay_subscribe(ctx: &WakuNodeContext, pubsub_topic: &PubsubTopic) -> Result<()> { + let pubsub_topic_ptr = CString::new(String::from(pubsub_topic)) .expect("CString should build properly from pubsub topic") .into_raw(); @@ -117,7 +116,7 @@ pub fn waku_relay_subscribe(ctx: &WakuNodeContext, pubsub_topic: &String) -> Res let mut closure = result_cb; let cb = get_trampoline(&closure); let out = waku_sys::waku_relay_subscribe( - ctx.obj_ptr, + ctx.get_ptr(), pubsub_topic_ptr, cb, &mut closure as *mut _ as *mut c_void, @@ -131,9 +130,8 @@ pub fn waku_relay_subscribe(ctx: &WakuNodeContext, pubsub_topic: &String) -> Res handle_no_response(code, result) } -pub fn waku_relay_unsubscribe(ctx: &WakuNodeContext, pubsub_topic: &String) -> Result<()> { - let pubsub_topic = pubsub_topic.to_string(); - let pubsub_topic_ptr = CString::new(pubsub_topic) +pub fn waku_relay_unsubscribe(ctx: &WakuNodeContext, pubsub_topic: &PubsubTopic) -> Result<()> { + let pubsub_topic_ptr = CString::new(String::from(pubsub_topic)) .expect("CString should build properly from pubsub topic") .into_raw(); @@ -143,7 +141,7 @@ pub fn waku_relay_unsubscribe(ctx: &WakuNodeContext, pubsub_topic: &String) -> R let mut closure = result_cb; let cb = get_trampoline(&closure); let out = waku_sys::waku_relay_subscribe( - ctx.obj_ptr, + ctx.get_ptr(), pubsub_topic_ptr, cb, &mut closure as *mut _ as *mut c_void, diff --git a/waku-bindings/src/utils.rs b/waku-bindings/src/utils.rs index 8e50cba..760f774 100644 --- a/waku-bindings/src/utils.rs +++ b/waku-bindings/src/utils.rs @@ -1,6 +1,5 @@ use crate::general::Result; use core::str::FromStr; -use serde::de::DeserializeOwned; use std::convert::TryFrom; use std::{slice, str}; use waku_sys::WakuCallBack; @@ -32,9 +31,13 @@ impl TryFrom<(u32, &str)> for LibwakuResponse { } } -pub fn decode(input: String) -> Result { - serde_json::from_str(input.as_str()) - .map_err(|err| format!("could not deserialize waku response: {}", err)) +// Define the WakuDecode trait +pub trait WakuDecode: Sized { + fn decode(input: &str) -> Result; +} + +pub fn decode(input: String) -> Result { + T::decode(input.as_str()) } unsafe extern "C" fn trampoline( @@ -45,7 +48,7 @@ unsafe extern "C" fn trampoline( ) where F: FnMut(LibwakuResponse), { - let user_data = &mut *(user_data as *mut F); + let closure = &mut *(user_data as *mut F); let response = if data.is_null() { "" @@ -57,7 +60,7 @@ unsafe extern "C" fn trampoline( let result = LibwakuResponse::try_from((ret_code as u32, response)) .expect("invalid response obtained from libwaku"); - user_data(result); + closure(result); } pub fn get_trampoline(_closure: &F) -> WakuCallBack @@ -84,7 +87,7 @@ pub fn handle_no_response(code: i32, result: LibwakuResponse) -> Result<()> { } } -pub fn handle_json_response(code: i32, result: LibwakuResponse) -> Result { +pub fn handle_json_response(code: i32, result: LibwakuResponse) -> Result { match result { LibwakuResponse::Success(v) => decode(v.unwrap_or_default()), LibwakuResponse::Failure(v) => Err(v), diff --git a/waku-bindings/tests/node.rs b/waku-bindings/tests/node.rs index fee6100..d588928 100644 --- a/waku-bindings/tests/node.rs +++ b/waku-bindings/tests/node.rs @@ -1,16 +1,20 @@ +use multiaddr::Multiaddr; +use regex::Regex; use secp256k1::SecretKey; use serial_test::serial; use std::str::FromStr; +use std::sync::{Arc, Mutex}; use std::time::{Duration, SystemTime}; use std::{collections::HashSet, str::from_utf8}; -use tokio::sync::broadcast::{self, Sender}; use tokio::time; use tokio::time::sleep; +use waku_bindings::node::PubsubTopic; use waku_bindings::{ - waku_destroy, waku_new, Encoding, Event, MessageHash, Running, WakuContentTopic, WakuMessage, + waku_new, Encoding, Event, Initialized, MessageHash, WakuContentTopic, WakuMessage, WakuNodeConfig, WakuNodeHandle, }; -const ECHO_TIMEOUT: u64 = 10; +use waku_bindings::{LibwakuResponse, Running}; +const ECHO_TIMEOUT: u64 = 1000; const ECHO_MESSAGE: &str = "Hi from 🦀!"; const TEST_PUBSUBTOPIC: &str = "test"; @@ -18,40 +22,79 @@ fn try_publish_relay_messages( node: &WakuNodeHandle, msg: &WakuMessage, ) -> Result, String> { - let topic = TEST_PUBSUBTOPIC.to_string(); - Ok(HashSet::from([ - node.relay_publish_message(msg, &topic, None)? - ])) -} - -#[derive(Debug, Clone)] -struct Response { - hash: MessageHash, - payload: Vec, -} - -fn set_callback(node: &WakuNodeHandle, tx: Sender) { - node.set_event_callback(move |event| { - if let Event::WakuMessage(message) = event { - let hash = message.message_hash; - let message = message.waku_message; - let payload = message.payload.to_vec(); - - tx.send(Response { - hash: hash.to_string(), - payload, - }) - .expect("send response to the receiver"); - } - }); + Ok(HashSet::from([node.relay_publish_message( + msg, + &PubsubTopic::new(TEST_PUBSUBTOPIC), + None, + )?])) } async fn test_echo_messages( - node1: &WakuNodeHandle, - node2: &WakuNodeHandle, + node1: WakuNodeHandle, + node2: WakuNodeHandle, content: &'static str, content_topic: WakuContentTopic, -) { +) -> Result<(), String> { + // setting a naïve event handler to avoid appearing ERR messages in logs + node1 + .set_event_callback(&|_| {}) + .expect("set event call back working"); + + let rx_waku_message: Arc> = Arc::new(Mutex::new(WakuMessage::default())); + + let rx_waku_message_cloned = rx_waku_message.clone(); + let closure = move |response| { + if let LibwakuResponse::Success(v) = response { + let event: Event = + serde_json::from_str(v.unwrap().as_str()).expect("Parsing event to succeed"); + + match event { + Event::WakuMessage(evt) => { + if let Ok(mut msg_lock) = rx_waku_message_cloned.lock() { + *msg_lock = evt.waku_message; + } + } + Event::Unrecognized(err) => panic!("Unrecognized waku event: {:?}", err), + _ => panic!("event case not expected"), + }; + } + }; + + println!("Before setting event callback"); + + node2 + .set_event_callback(closure) + .expect("set event call back working"); // Set the event callback with the closure + + let node1 = node1.start()?; + let node2 = node2.start()?; + + node1 + .relay_subscribe(&PubsubTopic::new(TEST_PUBSUBTOPIC)) + .unwrap(); + node2 + .relay_subscribe(&PubsubTopic::new(TEST_PUBSUBTOPIC)) + .unwrap(); + + sleep(Duration::from_secs(3)).await; + + // Interconnect nodes + // Replace all matches with 127.0.0.1 to avoid issue with NAT or firewall. + let addresses1 = node1.listen_addresses().unwrap(); + let addresses1 = &addresses1[0].to_string(); + + let re = Regex::new(r"\b(?:\d{1,3}\.){3}\d{1,3}\b").unwrap(); + let addresses1 = re.replace_all(addresses1, "127.0.0.1").to_string(); + + let addresses1 = addresses1.parse::().expect("parse multiaddress"); + + println!("Connecting node1 to node2: {}", addresses1); + node2.connect(&addresses1, None).unwrap(); + + // Wait for mesh to form + sleep(Duration::from_secs(3)).await; + + dbg!("Before publish"); let message = WakuMessage::new( content, content_topic, @@ -65,51 +108,47 @@ async fn test_echo_messages( Vec::new(), false, ); + let _ids = try_publish_relay_messages(&node1, &message).expect("send relay messages"); - node1.set_event_callback(move |_event| {}); - - let (tx, mut rx) = broadcast::channel(1); - set_callback(node2, tx); - - let mut ids = try_publish_relay_messages(node1, &message).expect("send relay messages"); - while let Ok(res) = rx.recv().await { - if ids.take(&res.hash).is_some() { - let msg = from_utf8(&res.payload).expect("should be valid message"); - assert_eq!(content, msg); - } - - if ids.is_empty() { - break; + // Wait for the msg to arrive + let rx_waku_message_cloned = rx_waku_message.clone(); + for _ in 0..50 { + if let Ok(msg) = rx_waku_message_cloned.lock() { + // dbg!("The waku message value is: {:?}", msg); + let payload = msg.payload.to_vec(); + let payload_str = from_utf8(&payload).expect("should be valid message"); + if payload_str == ECHO_MESSAGE { + node1.stop()?; + node2.stop()?; + return Ok(()); + } + } else { + sleep(Duration::from_millis(100)).await; } } + + let node1 = node1.stop()?; + let node2 = node2.stop()?; + + node1.waku_destroy()?; + node2.waku_destroy()?; + + return Err("Unexpected test ending".to_string()); } #[tokio::test] #[serial] async fn default_echo() -> Result<(), String> { + println!("Test default_echo"); let node1 = waku_new(Some(WakuNodeConfig { - port: Some(60010), + tcp_port: Some(60010), ..Default::default() }))?; let node2 = waku_new(Some(WakuNodeConfig { - port: Some(60020), + tcp_port: Some(60020), ..Default::default() }))?; - let node1 = node1.start()?; - let node2 = node2.start()?; - - let addresses1 = node1.listen_addresses()?; - node2.connect(&addresses1[0], None)?; - - let topic = TEST_PUBSUBTOPIC.to_string(); - - node1.relay_subscribe(&topic)?; - node2.relay_subscribe(&topic)?; - - // Wait for mesh to form - sleep(Duration::from_secs(3)).await; - let content_topic = WakuContentTopic::new("toychat", "2", "huilong", Encoding::Proto); let sleep = time::sleep(Duration::from_secs(ECHO_TIMEOUT)); @@ -118,17 +157,11 @@ async fn default_echo() -> Result<(), String> { // Send and receive messages. Waits until all messages received. let got_all = tokio::select! { _ = sleep => false, - _ = test_echo_messages(&node1, &node2, ECHO_MESSAGE, content_topic) => true, + _ = test_echo_messages(node1, node2, ECHO_MESSAGE, content_topic) => true, }; assert!(got_all); - let node2 = node2.stop()?; - let node1 = node1.stop()?; - - waku_destroy(node1)?; - waku_destroy(node2)?; - Ok(()) } @@ -145,9 +178,8 @@ fn node_restart() { for _ in 0..3 { let node = waku_new(config.clone().into()).expect("default config should be valid"); - let node = node.start().expect("node should start with valid config"); - - node.stop().expect("node should stop"); + let node = node.stop().expect("node should stop"); + node.waku_destroy().expect("free resources"); } } diff --git a/waku-sys/Cargo.toml b/waku-sys/Cargo.toml index 07fe377..c1ddd07 100644 --- a/waku-sys/Cargo.toml +++ b/waku-sys/Cargo.toml @@ -36,4 +36,4 @@ crate-type = ["rlib"] [build-dependencies] bindgen = "0.64" -cc = "1.0" +cc = "1.0.73" diff --git a/waku-sys/build.rs b/waku-sys/build.rs index d2a1902..b41bba1 100644 --- a/waku-sys/build.rs +++ b/waku-sys/build.rs @@ -38,6 +38,7 @@ fn generate_bindgen_code(project_dir: &Path) { vendor_path.join("build").display() ); println!("cargo:rustc-link-lib=static=waku"); + println!( "cargo:rustc-link-search={}", vendor_path @@ -45,6 +46,7 @@ fn generate_bindgen_code(project_dir: &Path) { .display() ); println!("cargo:rustc-link-lib=static=miniupnpc"); + println!( "cargo:rustc-link-search={}", vendor_path @@ -52,8 +54,10 @@ fn generate_bindgen_code(project_dir: &Path) { .display() ); println!("cargo:rustc-link-lib=static=natpmp"); + println!("cargo:rustc-link-lib=dl"); println!("cargo:rustc-link-lib=m"); + println!( "cargo:rustc-link-search=native={}", vendor_path @@ -62,7 +66,25 @@ fn generate_bindgen_code(project_dir: &Path) { ); println!("cargo:rustc-link-lib=static=backtrace"); + println!("cargo:rustc-link-lib=stdc++"); + + println!( + "cargo:rustc-link-search={}", + vendor_path.join("vendor/negentropy/cpp").display() + ); + println!("cargo:rustc-link-lib=static=negentropy"); + + println!("cargo:rustc-link-lib=ssl"); + println!("cargo:rustc-link-lib=crypto"); + + cc::Build::new() + .file("src/cmd.c") // Compile the C file + .compile("cmditems"); // Compile it as a library + println!("cargo:rustc-link-lib=static=cmditems"); + // TODO: Determine if pthread is automatically included + println!("cargo:rustc-link-lib=pthread"); + // TODO: Test in other architectures // Generate waku bindings with bindgen diff --git a/waku-sys/src/cmd.c b/waku-sys/src/cmd.c new file mode 100644 index 0000000..4c9147a --- /dev/null +++ b/waku-sys/src/cmd.c @@ -0,0 +1,13 @@ + +/* + This file is needed to avoid errors like the following when linking the waku-sys lib crate: + <> + and + <> +*/ + +#include + +int cmdCount = 0; +char** cmdLine = NULL; + diff --git a/waku-sys/vendor b/waku-sys/vendor index 964d7ab..d814519 160000 --- a/waku-sys/vendor +++ b/waku-sys/vendor @@ -1 +1 @@ -Subproject commit 964d7ab7dc3dc38c9a05087b998a0cc7a1475cc0 +Subproject commit d814519578380bf01398c29424a5fd1005ed3a29