From 6dabc9f1e120bc4136ba2c32d820f7b6a17ad4d6 Mon Sep 17 00:00:00 2001 From: Rahul Garg Date: Mon, 8 Dec 2025 17:01:52 +0400 Subject: [PATCH] chore: update dependencies --- .github/workflows/rust.yml | 30 +- Cargo.lock | 366 ++++-------------- Cargo.toml | 7 +- rust/penview/src/render.rs | 4 +- rust/websocket-ffi/Cargo.toml | 1 - rust/websocket-ffi/src/client/ffi.rs | 24 +- .../websocket-ffi/src/client/inbound_event.rs | 51 +-- rust/websocket-ffi/src/client/mod.rs | 129 +++--- rust/websocket-ffi/src/client/registry.rs | 4 - rust/websocket-ffi/src/lib.rs | 2 +- rust/websocket-ffi/src/server/client.rs | 57 ++- rust/websocket-ffi/src/server/ffi.rs | 25 +- .../websocket-ffi/src/server/inbound_event.rs | 56 ++- rust/websocket-ffi/src/server/mod.rs | 94 ++--- 14 files changed, 290 insertions(+), 560 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 2526b79..a066c76 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -2,9 +2,9 @@ name: Rust on: push: - branches: [ "main" ] + branches: ["main"] pull_request: - branches: [ "main" ] + branches: ["main"] env: CARGO_TERM_COLOR: always @@ -14,22 +14,22 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v4 - - name: Install Rust toolchain - uses: dtolnay/rust-toolchain@stable + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable - - name: Cache cargo - uses: Swatinem/rust-cache@v2 + - name: Cache cargo + uses: Swatinem/rust-cache@v2 - - name: Fmt - run: cargo fmt --check + - name: Fmt + run: cargo fmt --check - - name: Clippy - run: cargo clippy -p penview -- -D warnings + - name: Clippy + run: cargo clippy -p penview -- -D warnings - - name: Build - run: cargo build -p penview --verbose + - name: Build + run: cargo build -p penview --verbose - - name: Run tests - run: cargo test -p penview --verbose + - name: Run tests + run: cargo test -p penview --verbose diff --git a/Cargo.lock b/Cargo.lock index fa1ec46..a8ca5de 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,15 +2,6 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "aho-corasick" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" -dependencies = [ - "memchr", -] - [[package]] name = "android_system_properties" version = "0.1.5" @@ -106,7 +97,7 @@ dependencies = [ "memchr", "proc-macro2", "quote", - "rustc-hash 2.1.1", + "rustc-hash", "serde", "serde_derive", "syn", @@ -165,7 +156,7 @@ dependencies = [ "sha1", "sync_wrapper", "tokio", - "tokio-tungstenite 0.28.0", + "tokio-tungstenite", "tower", "tower-layer", "tower-service", @@ -206,26 +197,6 @@ dependencies = [ "serde", ] -[[package]] -name = "bindgen" -version = "0.68.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "726e4313eb6ec35d2730258ad4e15b547ee75d6afaa1361a922e78e59b7d8078" -dependencies = [ - "bitflags 2.10.0", - "cexpr", - "clang-sys", - "lazy_static", - "lazycell", - "peeking_take_while", - "proc-macro2", - "quote", - "regex", - "rustc-hash 1.1.0", - "shlex", - "syn", -] - [[package]] name = "bitflags" version = "1.3.2" @@ -263,12 +234,6 @@ version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - [[package]] name = "bytes" version = "1.11.0" @@ -285,15 +250,6 @@ dependencies = [ "shlex", ] -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - [[package]] name = "cfg-if" version = "1.0.4" @@ -311,17 +267,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "clang-sys" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" -dependencies = [ - "glob", - "libc", - "libloading", -] - [[package]] name = "clap" version = "4.5.53" @@ -520,6 +465,12 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + [[package]] name = "equivalent" version = "1.0.2" @@ -670,12 +621,6 @@ dependencies = [ "wasip2", ] -[[package]] -name = "glob" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" - [[package]] name = "hashbrown" version = "0.16.1" @@ -1013,28 +958,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - [[package]] name = "libc" version = "0.2.178" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" -[[package]] -name = "libloading" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" -dependencies = [ - "cfg-if", - "windows-link", -] - [[package]] name = "libredox" version = "0.1.10" @@ -1045,17 +974,6 @@ dependencies = [ "libc", ] -[[package]] -name = "libuv-sys2" -version = "1.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d332e6b6d43b75734f0bf5f990a5177032d3d638db76d1acb6bf3688b9fad9f" -dependencies = [ - "bindgen", - "cc", - "pkg-config", -] - [[package]] name = "linux-raw-sys" version = "0.11.0" @@ -1124,7 +1042,7 @@ dependencies = [ "log-mdc", "mock_instant", "parking_lot", - "rand 0.9.2", + "rand", "serde", "serde-value", "serde_json", @@ -1164,12 +1082,6 @@ dependencies = [ "unicase", ] -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - [[package]] name = "mio" version = "1.1.1" @@ -1184,15 +1096,17 @@ dependencies = [ [[package]] name = "mlua" -version = "0.9.9" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d111deb18a9c9bd33e1541309f4742523bfab01d276bfa9a27519f6de9c11dc7" +checksum = "c1f5f8fbebc7db5f671671134b9321c4b9aa9adeafccfd9a8c020ae45c6a35d0" dependencies = [ "bstr", + "either", "mlua-sys", "num-traits", - "once_cell", - "rustc-hash 2.1.1", + "parking_lot", + "rustc-hash", + "rustversion", ] [[package]] @@ -1212,16 +1126,6 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dce6dd36094cac388f119d2e9dc82dc730ef91c32a6222170d630e5414b956e6" -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - [[package]] name = "notify" version = "8.2.0" @@ -1266,108 +1170,105 @@ dependencies = [ [[package]] name = "nvim-oxi" -version = "0.4.2" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c9aef30b9ac1033e2d176b76f5eabab48d710a25cf0aa01068b5224a179d88" +checksum = "54489e0e1515ff8fdbd07eb198ac1f8b082b849e2ed3b7607d6705e24b74af5c" dependencies = [ "mlua", - "oxi-api", - "oxi-libuv", - "oxi-luajit", - "oxi-macros", - "oxi-types", - "thiserror 1.0.69", + "nvim-oxi-api", + "nvim-oxi-libuv", + "nvim-oxi-luajit", + "nvim-oxi-macros", + "nvim-oxi-types", + "thiserror 2.0.17", ] [[package]] -name = "once_cell" -version = "1.21.3" +name = "nvim-oxi-api" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "89a662cfeae9de93b4a6a1779e9e37e15c354f8f9acc933e2d79105d601c8fd4" +dependencies = [ + "nvim-oxi-luajit", + "nvim-oxi-macros", + "nvim-oxi-types", + "serde", + "serde_repr", + "thiserror 2.0.17", +] [[package]] -name = "once_cell_polyfill" -version = "1.70.2" +name = "nvim-oxi-libuv" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" +checksum = "91360300b2f7e0d1aaf4fe42d06ec9096a21d4162614e601029e78f583d83203" +dependencies = [ + "nvim-oxi-luajit", + "thiserror 2.0.17", +] [[package]] -name = "open" -version = "5.3.3" +name = "nvim-oxi-luajit" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43bb73a7fa3799b198970490a51174027ba0d4ec504b03cd08caf513d40024bc" +checksum = "bba46ec2ab57e840cd33067e0d1d7c89c2c7feafd02bbbb11a90a4220491a1c9" dependencies = [ - "is-wsl", - "libc", - "pathdiff", + "thiserror 2.0.17", ] [[package]] -name = "ordered-float" -version = "2.10.1" +name = "nvim-oxi-macros" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c" +checksum = "b0c03daabc1d9efd2d5aff2746199b4ed60f2cc24c321d6fcb2aa023169b0f13" dependencies = [ - "num-traits", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "oxi-api" -version = "0.4.2" +name = "nvim-oxi-types" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e969161dafa13429fe816dfcbdd6cb138c3ed872e263f2a7cab3c41acd8cf174" +checksum = "2f079f687853419cf83879ab060d23171e31689d090a0c8d5c6aa0e3210c83ec" dependencies = [ - "oxi-luajit", - "oxi-macros", - "oxi-types", + "libc", + "nvim-oxi-luajit", "serde", - "serde_repr", - "thiserror 1.0.69", + "thiserror 2.0.17", ] [[package]] -name = "oxi-libuv" -version = "0.4.2" +name = "once_cell" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da0c7850edec97513b9f4d77ce9b2f3c80eb60b259c8035e334f3f290785b76" -dependencies = [ - "libuv-sys2", - "once_cell", - "oxi-luajit", - "thiserror 1.0.69", -] +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] -name = "oxi-luajit" -version = "0.4.2" +name = "once_cell_polyfill" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a644c4c3c35816a6eb174570fc54a968c6047b8b845c1f253c0184fd8aeb25ab" -dependencies = [ - "once_cell", - "thiserror 1.0.69", -] +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] -name = "oxi-macros" -version = "0.4.2" +name = "open" +version = "5.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae7527f018ccf611bf798ecae060c199ba921998125c836c7f236c2425ba0d89" +checksum = "43bb73a7fa3799b198970490a51174027ba0d4ec504b03cd08caf513d40024bc" dependencies = [ - "proc-macro2", - "quote", - "syn", + "is-wsl", + "libc", + "pathdiff", ] [[package]] -name = "oxi-types" -version = "0.4.2" +name = "ordered-float" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05813abd7733b9ef9618811d66627ce80db6b8321140613872989c6aae5c25db" +checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c" dependencies = [ - "libc", - "oxi-luajit", - "serde", - "thiserror 1.0.69", + "num-traits", ] [[package]] @@ -1399,15 +1300,9 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" -[[package]] -name = "peeking_take_while" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" - [[package]] name = "penview" -version = "0.1.0" +version = "0.1.1" dependencies = [ "anyhow", "askama", @@ -1513,35 +1408,14 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - [[package]] name = "rand" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ - "rand_chacha 0.9.0", - "rand_core 0.9.3", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", + "rand_chacha", + "rand_core", ] [[package]] @@ -1551,16 +1425,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core 0.9.3", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.16", + "rand_core", ] [[package]] @@ -1592,35 +1457,6 @@ dependencies = [ "thiserror 1.0.69", ] -[[package]] -name = "regex" -version = "1.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" - [[package]] name = "resolve-path" version = "0.1.0" @@ -1630,12 +1466,6 @@ dependencies = [ "dirs", ] -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - [[package]] name = "rustc-hash" version = "2.1.1" @@ -2012,18 +1842,6 @@ dependencies = [ "syn", ] -[[package]] -name = "tokio-tungstenite" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" -dependencies = [ - "futures-util", - "log", - "tokio", - "tungstenite 0.21.0", -] - [[package]] name = "tokio-tungstenite" version = "0.28.0" @@ -2033,7 +1851,7 @@ dependencies = [ "futures-util", "log", "tokio", - "tungstenite 0.28.0", + "tungstenite", ] [[package]] @@ -2122,25 +1940,6 @@ dependencies = [ "tracing-log", ] -[[package]] -name = "tungstenite" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" -dependencies = [ - "byteorder", - "bytes", - "data-encoding", - "http", - "httparse", - "log", - "rand 0.8.5", - "sha1", - "thiserror 1.0.69", - "url", - "utf-8", -] - [[package]] name = "tungstenite" version = "0.28.0" @@ -2152,7 +1951,7 @@ dependencies = [ "http", "httparse", "log", - "rand 0.9.2", + "rand", "sha1", "thiserror 2.0.17", "utf-8", @@ -2256,7 +2055,7 @@ checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" dependencies = [ "getrandom 0.3.4", "js-sys", - "rand 0.9.2", + "rand", "uuid-macro-internal", "wasm-bindgen", ] @@ -2356,7 +2155,7 @@ dependencies = [ [[package]] name = "websocket-ffi" -version = "0.1.0" +version = "0.1.1" dependencies = [ "futures-channel", "futures-util", @@ -2364,12 +2163,11 @@ dependencies = [ "log", "log-panics", "log4rs", - "mlua", "nvim-oxi", "parking_lot", "serde", "tokio", - "tokio-tungstenite 0.21.0", + "tokio-tungstenite", "url", "uuid", ] diff --git a/Cargo.toml b/Cargo.toml index d9cbc55..ea49a09 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ members = [ ] [workspace.package] -version = "0.1.0" +version = "0.1.1" edition = "2024" authors = ["Rahul Garg "] readme = "README.md" @@ -29,8 +29,7 @@ log = "0.4" log4rs = { version = "1.4", features = ["file_appender"] } log-panics = "2" notify = "8" -mlua = "0.9.7" -nvim-oxi = { version = "0.4.2", features = ["neovim-0-9", "libuv", "mlua"] } +nvim-oxi = { version = "0.6", features = ["neovim-0-11", "libuv", "mlua"] } open = "5" parking_lot = "0.12" pulldown-cmark = "0.13" @@ -38,7 +37,7 @@ resolve-path = "0.1.0" serde = { version = "1", features = ["derive"] } serde_json = "1" tokio = { version = "1", features = ["full"] } -tokio-tungstenite = { version = "0.21.0", features = [] } +tokio-tungstenite = "0.28" tracing = "0.1" tracing-subscriber = "0.3" url = "2" diff --git a/rust/penview/src/render.rs b/rust/penview/src/render.rs index df66d3d..52cd001 100644 --- a/rust/penview/src/render.rs +++ b/rust/penview/src/render.rs @@ -349,14 +349,14 @@ mod tests { // The directory of the current file is the parent directory of the file // So this should return true - assert_eq!(is_child_path(current_file, file), true); + assert!(is_child_path(current_file, file)); let current_file: PathBuf = PathBuf::from("/home/user/Notes/slipbox/"); let file: PathBuf = PathBuf::from("/home/user/Notes/not_child.md"); // The directory of the current file is the parent directory of the file // So this should return true - assert_ne!(is_child_path(current_file, file), true); + assert!(!is_child_path(current_file, file)); } #[test] diff --git a/rust/websocket-ffi/Cargo.toml b/rust/websocket-ffi/Cargo.toml index d97ef57..937154e 100644 --- a/rust/websocket-ffi/Cargo.toml +++ b/rust/websocket-ffi/Cargo.toml @@ -16,7 +16,6 @@ log.workspace = true log4rs.workspace = true log-panics.workspace = true lazy_static.workspace = true -mlua.workspace = true nvim-oxi.workspace = true parking_lot.workspace = true serde.workspace = true diff --git a/rust/websocket-ffi/src/client/ffi.rs b/rust/websocket-ffi/src/client/ffi.rs index 7298903..c0b29f4 100644 --- a/rust/websocket-ffi/src/client/ffi.rs +++ b/rust/websocket-ffi/src/client/ffi.rs @@ -1,20 +1,26 @@ -use std::collections::HashMap; - +use super::{WEBSOCKET_CLIENT_REGISTRY, WebsocketClient}; use nvim_oxi::{Dictionary, Function, Object}; +use std::collections::HashMap; use uuid::Uuid; -use super::WEBSOCKET_CLIENT_REGISTRY; -use super::WebsocketClient; - pub fn websocket_client_ffi() -> Dictionary { Dictionary::from_iter([ ( "connect", - Object::from(Function::from_fn(create_client_and_connect)), + Object::from(Function::<_, ()>::from_fn(create_client_and_connect)), + ), + ( + "disconnect", + Object::from(Function::<_, ()>::from_fn(disconnect)), + ), + ( + "send_data", + Object::from(Function::<_, ()>::from_fn(send_data)), + ), + ( + "get_clients", + Object::from(Function::<_, Dictionary>::from_fn(get_clients)), ), - ("disconnect", Object::from(Function::from_fn(disconnect))), - ("send_data", Object::from(Function::from_fn(send_data))), - ("get_clients", Object::from(Function::from_fn(get_clients))), ]) } diff --git a/rust/websocket-ffi/src/client/inbound_event.rs b/rust/websocket-ffi/src/client/inbound_event.rs index f786e09..891eb38 100644 --- a/rust/websocket-ffi/src/client/inbound_event.rs +++ b/rust/websocket-ffi/src/client/inbound_event.rs @@ -1,15 +1,13 @@ -use std::error::Error; - -use mlua::prelude::*; -use nvim_oxi::Object; -use nvim_oxi::conversion::ToObject; +use nvim_oxi::{ + mlua::{IntoLua, Lua, Result as LuaResult, Value as LuaValue}, + {Object, conversion::ToObject}, +}; #[derive(Clone, Debug)] pub enum WebsocketClientError { - ConnectionError(String), - DisconnectionError(String), - ReceiveMessageError(String), - SendMessageError(String), + Connection(String), + ReceiveMessage(String), + SendMessage(String), } #[derive(Clone, Debug)] @@ -20,51 +18,32 @@ pub enum WebsocketClientInboundEvent { Error(WebsocketClientError), } -// Not necessary (for now) impl ToObject for WebsocketClientError { fn to_object(self) -> Result { match self { - WebsocketClientError::ConnectionError(message) => Ok(Object::from(message)), - WebsocketClientError::DisconnectionError(message) => Ok(Object::from(message)), - WebsocketClientError::ReceiveMessageError(message) => Ok(Object::from(message)), - WebsocketClientError::SendMessageError(message) => Ok(Object::from(message)), + WebsocketClientError::Connection(message) => Ok(Object::from(message)), + WebsocketClientError::ReceiveMessage(message) => Ok(Object::from(message)), + WebsocketClientError::SendMessage(message) => Ok(Object::from(message)), } } } -impl<'lua> IntoLua<'lua> for WebsocketClientError { - fn into_lua(self, lua: &'lua Lua) -> LuaResult> { +impl IntoLua for WebsocketClientError { + fn into_lua(self, lua: &Lua) -> LuaResult { let vec = match self { - WebsocketClientError::ConnectionError(message) => { + WebsocketClientError::Connection(message) => { vec![("type", "connection_error"), ("message", message.leak())] } - WebsocketClientError::DisconnectionError(message) => { - vec![("type", "disconnection_error"), ("message", message.leak())] - } - WebsocketClientError::ReceiveMessageError(message) => { + WebsocketClientError::ReceiveMessage(message) => { vec![ ("type", "receive_message_error"), ("message", message.leak()), ] } - WebsocketClientError::SendMessageError(message) => { + WebsocketClientError::SendMessage(message) => { vec![("type", "send_message_error"), ("message", message.leak())] } }; Ok(LuaValue::Table(lua.create_table_from(vec)?)) } } - -// Unnecessary trait. Could have just wrap the received message in an enum instead -trait TryFromStr { - fn try_from_string(s: String) -> Result> - where - Self: Sized; -} - -impl TryFromStr for WebsocketClientInboundEvent { - // Blanket implementation already exists, cannot override TryFrom trait's try_from - fn try_from_string(s: String) -> Result> { - Ok(WebsocketClientInboundEvent::NewMessage(s)) - } -} diff --git a/rust/websocket-ffi/src/client/mod.rs b/rust/websocket-ffi/src/client/mod.rs index 9b444f1..a6f4f50 100644 --- a/rust/websocket-ffi/src/client/mod.rs +++ b/rust/websocket-ffi/src/client/mod.rs @@ -1,16 +1,18 @@ -use std::collections::HashMap; -use std::error::Error; -use std::sync::Arc; - -use futures_util::{SinkExt, StreamExt, TryFutureExt}; -use mlua::prelude::{LuaFunction, LuaTable}; -use nvim_oxi::libuv::AsyncHandle; -use nvim_oxi::{mlua::lua, schedule}; +use futures_util::{SinkExt, StreamExt}; +use nvim_oxi::{ + libuv::AsyncHandle, + mlua::{ + lua, + prelude::{LuaFunction, LuaTable}, + }, + schedule, +}; +use std::{collections::HashMap, error::Error}; use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender}; use url::Url; use uuid::Uuid; -use log::{debug, error, info, warn}; +use log::{debug, error, info}; use tokio_tungstenite::tungstenite::{self}; mod ffi; @@ -23,17 +25,13 @@ use registry::WEBSOCKET_CLIENT_REGISTRY; pub use super::ASYNC_RUNTIME; pub use ffi::websocket_client_ffi; -use tokio::task::JoinHandle; - struct WebsocketClient { id: Uuid, connect_addr: Url, - extra_headers: HashMap, close_connection_event_publisher: UnboundedSender, outbound_message_publisher: UnboundedSender, inbound_event_publisher: UnboundedSender, lua_handle: AsyncHandle, - task_handle: JoinHandle<()>, } async fn start_client( @@ -65,7 +63,7 @@ async fn start_client( "{}:{}", connect_addr .host_str() - .ok_or(WebsocketClientError::ConnectionError( + .ok_or(WebsocketClientError::Connection( "Host is not set".to_string() ))?, connect_addr.port().unwrap_or_else(|| { @@ -83,7 +81,7 @@ async fn start_client( .header("Sec-WebSocket-Version", 13) .uri(connect_addr.as_str()) .body(()) - .map_err(|err| WebsocketClientError::ConnectionError(err.to_string()))?; + .map_err(|err| WebsocketClientError::Connection(err.to_string()))?; for (key, value) in extra_headers.clone() { debug!("Adding header: {}={}", key, value); @@ -99,7 +97,7 @@ async fn start_client( let (ws_stream, _response) = tokio_tungstenite::connect_async(request) .await - .map_err(|err| WebsocketClientError::ConnectionError(err.to_string()))?; + .map_err(|err| WebsocketClientError::Connection(err.to_string()))?; info!("{} WebSocket handshake completed", connect_addr.as_str()); send_event(WebsocketClientInboundEvent::Connected); @@ -114,9 +112,9 @@ async fn start_client( if message.is_text() { let data = message.into_text().expect("Message received from server is not valid string"); info!("Received message: {}", data); - send_event(WebsocketClientInboundEvent::NewMessage(data)); + send_event(WebsocketClientInboundEvent::NewMessage(data.to_string())); } else if message.is_binary() { - send_event(WebsocketClientInboundEvent::Error(WebsocketClientError::ReceiveMessageError("Binary data is not supported".to_string()))); + send_event(WebsocketClientInboundEvent::Error(WebsocketClientError::ReceiveMessage("Binary data is not supported".to_string()))); error!("Binary data is not supported"); } else if message.is_close() { info!("Received close frame from server"); @@ -124,34 +122,24 @@ async fn start_client( } } Err(err) => { - send_event(WebsocketClientInboundEvent::Error(WebsocketClientError::ReceiveMessageError(err.to_string()))); + send_event(WebsocketClientInboundEvent::Error(WebsocketClientError::ReceiveMessage(err.to_string()))); error!("Failed to receive message: {}", err); } } } } close_event = close_connection_event_subscriber.recv() => { - if let Some(close_event) = close_event { - match close_event { - WebsocketClientCloseConnectionEvent::Graceful => { - if let Err(err) = ws_sender.send(tungstenite::Message::Close(None)).await { - send_event(WebsocketClientInboundEvent::Error(WebsocketClientError::ConnectionError(err.to_string()))); - error!("Failed to send close message: {}", err); - } - } - WebsocketClientCloseConnectionEvent::Forceful => { - warn!("Forcefully closing WebSocket connection"); - break - } - } + if close_event.is_some() && + let Err(err) = ws_sender.send(tungstenite::Message::Close(None)).await { + send_event(WebsocketClientInboundEvent::Error(WebsocketClientError::Connection(err.to_string()))); + error!("Failed to send close message: {}", err); } } message = outbound_message_receiver.recv() => { - if let Some(message) = message { - if let Err(err) = ws_sender.send(tungstenite::Message::Text(message)).await { - send_event(WebsocketClientInboundEvent::Error(WebsocketClientError::ConnectionError(err.to_string()))); + if let Some(message) = message && + let Err(err) = ws_sender.send(tungstenite::Message::Text(message.into())).await { + send_event(WebsocketClientInboundEvent::Error(WebsocketClientError::Connection(err.to_string()))); error!("Failed to forward message to websocket: {}", err); - } } } } @@ -190,38 +178,37 @@ impl WebsocketClient { schedule(move |_| { match event { WebsocketClientInboundEvent::Connected => { - if let Some(on_connect) = callbacks.on_connect.clone() { - on_connect.call::<_, ()>(id.to_string())?; + if let Some(ref on_connect) = callbacks.on_connect { + on_connect.call::<()>(id.to_string())?; } } WebsocketClientInboundEvent::Disconnected => { - if let Some(on_disconnect) = callbacks.on_disconnect { - on_disconnect.call::<_, ()>(id.to_string())?; + if let Some(ref on_disconnect) = callbacks.on_disconnect { + on_disconnect.call::<()>(id.to_string())?; } } WebsocketClientInboundEvent::NewMessage(message) => { - if let Some(on_message) = callbacks.on_message.clone() { - on_message.call::<_, ()>((id.to_string(), message))?; + if let Some(ref on_message) = callbacks.on_message { + on_message.call::<()>((id.to_string(), message))?; } } WebsocketClientInboundEvent::Error(error) => { - if let Some(on_error) = callbacks.on_error.clone() { - on_error.call::<_, ()>((id.to_string(), error))?; + if let Some(ref on_error) = callbacks.on_error { + on_error.call::<()>((id.to_string(), error))?; } } } - Ok(()) + Ok::<(), nvim_oxi::Error>(()) }); Ok::<_, nvim_oxi::Error>(()) })?; let connect_addr_clone = connect_addr.clone(); - let extra_headers_clone = extra_headers.clone(); + let extra_headers_clone = extra_headers; let inbound_event_publisher_clone = inbound_event_publisher.clone(); let lua_handle_clone = lua_handle.clone(); - // REFACTOR: convert type to a MapErr>>? So that we don't need to duplicate the error handling logic - let handle: JoinHandle<()> = ASYNC_RUNTIME.spawn(async move { + let _handle = ASYNC_RUNTIME.spawn(async move { if let Err(err) = start_client( &connect_addr_clone, &extra_headers_clone, @@ -243,16 +230,13 @@ impl WebsocketClient { WEBSOCKET_CLIENT_REGISTRY.lock().remove(&id); }); - // Store the handle in the WebsocketClient struct Ok(Self { id, connect_addr, - extra_headers, close_connection_event_publisher, outbound_message_publisher, inbound_event_publisher, lua_handle, - task_handle: handle, // Add this field to the struct }) } @@ -267,10 +251,10 @@ impl WebsocketClient { fn disconnect(&mut self) { self.close_connection_event_publisher - .send(WebsocketClientCloseConnectionEvent::Graceful) + .send(WebsocketClientCloseConnectionEvent) .unwrap_or_else(move |err| { self.send_event(WebsocketClientInboundEvent::Error( - WebsocketClientError::SendMessageError(err.to_string()), + WebsocketClientError::SendMessage(err.to_string()), )); }); } @@ -280,24 +264,21 @@ impl WebsocketClient { .send(data) .unwrap_or_else(move |err| { self.send_event(WebsocketClientInboundEvent::Error( - WebsocketClientError::SendMessageError(err.to_string()), + WebsocketClientError::SendMessage(err.to_string()), )); }); } } #[derive(Clone, Debug)] -pub enum WebsocketClientCloseConnectionEvent { - Graceful, - Forceful, -} +pub struct WebsocketClientCloseConnectionEvent; #[derive(Clone)] struct WebsocketClientCallbacks { - on_message: Option>>, - on_disconnect: Option>>, - on_connect: Option>>, - on_error: Option>>, + on_message: Option, + on_disconnect: Option, + on_connect: Option, + on_error: Option, } impl WebsocketClientCallbacks { @@ -305,24 +286,16 @@ impl WebsocketClientCallbacks { let lua = lua(); let callbacks = lua .globals() - .get::<_, LuaTable>("_WEBSOCKET_NVIM")? - .get::<_, LuaTable>("clients")? - .get::<_, LuaTable>("callbacks")? - .get::<_, LuaTable>(client_id.to_string())?; + .get::("_WEBSOCKET_NVIM")? + .get::("clients")? + .get::("callbacks")? + .get::(client_id.to_string())?; Ok(Self { - on_message: callbacks - .get::<_, Option>("on_message")? - .map(Arc::new), - on_disconnect: callbacks - .get::<_, Option>("on_disconnect")? - .map(Arc::new), - on_connect: callbacks - .get::<_, Option>("on_connect")? - .map(Arc::new), - on_error: callbacks - .get::<_, Option>("on_error")? - .map(Arc::new), + on_message: callbacks.get::>("on_message")?, + on_disconnect: callbacks.get::>("on_disconnect")?, + on_connect: callbacks.get::>("on_connect")?, + on_error: callbacks.get::>("on_error")?, }) } } diff --git a/rust/websocket-ffi/src/client/registry.rs b/rust/websocket-ffi/src/client/registry.rs index d613cb9..f8f30fc 100644 --- a/rust/websocket-ffi/src/client/registry.rs +++ b/rust/websocket-ffi/src/client/registry.rs @@ -29,10 +29,6 @@ impl WebsocketClientRegistry { self.clients.insert(id, client); } - pub(super) fn get(&self, id: &Uuid) -> Option<&WebsocketClient> { - self.clients.get(id) - } - pub(super) fn get_mut(&mut self, id: &Uuid) -> Option<&mut WebsocketClient> { self.clients.get_mut(id) } diff --git a/rust/websocket-ffi/src/lib.rs b/rust/websocket-ffi/src/lib.rs index d6c1c51..8f42218 100644 --- a/rust/websocket-ffi/src/lib.rs +++ b/rust/websocket-ffi/src/lib.rs @@ -15,7 +15,7 @@ lazy_static! { pub static ref ASYNC_RUNTIME: Runtime = Runtime::new().expect("Failed to create async runtime"); } -#[nvim_oxi::module] +#[nvim_oxi::plugin] fn websocket_ffi() -> nvim_oxi::Result { let file_appender = FileAppender::builder() // Pattern: https://docs.rs/log4rs/*/log4rs/encode/pattern/index.html diff --git a/rust/websocket-ffi/src/server/client.rs b/rust/websocket-ffi/src/server/client.rs index ef32218..c8d3d85 100644 --- a/rust/websocket-ffi/src/server/client.rs +++ b/rust/websocket-ffi/src/server/client.rs @@ -1,21 +1,18 @@ -use std::collections::HashMap; -use std::net::SocketAddr; -use std::sync::Arc; - -use futures_util::{SinkExt, StreamExt}; -use nvim_oxi::libuv::AsyncHandle; -use parking_lot::Mutex; -use tokio::net::TcpStream; -use tokio::sync::mpsc::{self, UnboundedSender}; -use uuid::Uuid; - -use log::{self, error, info}; -use tokio_tungstenite::tungstenite::{self}; - use super::{ OutboundMessageReplayBuffer, WebsocketServerCloseConnectionEvent, WebsocketServerError, WebsocketServerInboundEvent, }; +use futures_util::{SinkExt, StreamExt}; +use log::{self, error, info}; +use nvim_oxi::libuv::AsyncHandle; +use parking_lot::Mutex; +use std::{collections::HashMap, net::SocketAddr, sync::Arc}; +use tokio::{ + net::TcpStream, + sync::mpsc::{self, UnboundedSender}, +}; +use tokio_tungstenite::tungstenite::{self}; +use uuid::Uuid; pub struct WebsocketServerClient { pub id: Uuid, @@ -105,15 +102,15 @@ impl WebsocketServerClient { match message { tungstenite::Message::Text(data) => { info!("Server-client {} received message: {}", id, data); - send_event(WebsocketServerInboundEvent::NewMessage(id, data)); + send_event(WebsocketServerInboundEvent::NewMessage(id, data.to_string())); } tungstenite::Message::Binary(_data) => { info!("Server-client {} received binary data", id); - send_event(WebsocketServerInboundEvent::Error(WebsocketServerError::ReceiveMessageError(id, "Binary data handling is not supported".to_string()))); + send_event(WebsocketServerInboundEvent::Error(WebsocketServerError::ReceiveMessage(id, "Binary data handling is not supported".to_string()))); } tungstenite::Message::Frame(_frame) => { info!("Server-client {} received raw frame data", id); - send_event(WebsocketServerInboundEvent::Error(WebsocketServerError::ReceiveMessageError(id, "Raw frame data handling is not supported".to_string()))); + send_event(WebsocketServerInboundEvent::Error(WebsocketServerError::ReceiveMessage(id, "Raw frame data handling is not supported".to_string()))); } // Ping, pong, close are handled by tokio-tungstenite _ => {} @@ -121,7 +118,7 @@ impl WebsocketServerClient { }, Err(err) => { error!("Server-client {} received error: {}", id, err); - send_event(WebsocketServerInboundEvent::Error(WebsocketServerError::ReceiveMessageError(id, err.to_string()))); + send_event(WebsocketServerInboundEvent::Error(WebsocketServerError::ReceiveMessage(id, err.to_string()))); } } } @@ -131,24 +128,16 @@ impl WebsocketServerClient { } } maybe_close_connection_event = close_connection_event_subscriber.recv() => { - if let Some(close_connection_event) = maybe_close_connection_event { - match close_connection_event { - WebsocketServerCloseConnectionEvent::Graceful => { - info!("Server-client {} received termination signal", id); - ws_sender.send(tungstenite::Message::Close(None)).await.unwrap(); - break; - } - WebsocketServerCloseConnectionEvent::Forceful => { - info!("Server-client {} received forceful termination signal", id); - break; - } - } + if maybe_close_connection_event.is_some() { + info!("Server-client {} received termination signal", id); + ws_sender.send(tungstenite::Message::Close(None)).await.unwrap(); + break; } } maybe_message = outbound_message_subscriber.recv() => { if let Some(message) = maybe_message { info!("Server-client {} sending message: {}", id, message); - ws_sender.send(tungstenite::Message::Text(message)).await.unwrap(); + ws_sender.send(tungstenite::Message::Text(message.into())).await.unwrap(); } } } @@ -169,10 +158,10 @@ impl WebsocketServerClient { pub(super) fn terminate(&mut self) { self.close_connection_event_publisher - .send(WebsocketServerCloseConnectionEvent::Graceful) + .send(WebsocketServerCloseConnectionEvent) .unwrap_or_else(move |err| { self.send_event(WebsocketServerInboundEvent::Error( - WebsocketServerError::ClientTerminationError(self.id, err.to_string()), + WebsocketServerError::ClientTermination(self.id, err.to_string()), )); }); } @@ -182,7 +171,7 @@ impl WebsocketServerClient { .send(data) .unwrap_or_else(move |err| { self.send_event(WebsocketServerInboundEvent::Error( - WebsocketServerError::SendMessageError(self.id, err.to_string()), + WebsocketServerError::SendMessage(self.id, err.to_string()), )); }); } diff --git a/rust/websocket-ffi/src/server/ffi.rs b/rust/websocket-ffi/src/server/ffi.rs index d1b04af..59d8487 100644 --- a/rust/websocket-ffi/src/server/ffi.rs +++ b/rust/websocket-ffi/src/server/ffi.rs @@ -9,27 +9,36 @@ pub fn websocket_server_ffi() -> Dictionary { Dictionary::from_iter([ ( "start", - Object::from(Function::from_fn(create_and_start_server)), + Object::from(Function::<_, ()>::from_fn(create_and_start_server)), + ), + ( + "terminate", + Object::from(Function::<_, ()>::from_fn(terminate)), ), - ("terminate", Object::from(Function::from_fn(terminate))), ( "send_data_to_client", - Object::from(Function::from_fn(send_data_to_client)), + Object::from(Function::<_, ()>::from_fn(send_data_to_client)), ), ( "check_replay_messages", - Object::from(Function::from_fn(check_replay_messages)), + Object::from(Function::<_, Vec>::from_fn(check_replay_messages)), ), ( "broadcast_data", - Object::from(Function::from_fn(broadcast_data)), + Object::from(Function::<_, ()>::from_fn(broadcast_data)), ), ( "terminate_client", - Object::from(Function::from_fn(terminate_client)), + Object::from(Function::<_, ()>::from_fn(terminate_client)), + ), + ( + "get_servers", + Object::from(Function::<_, Dictionary>::from_fn(get_servers)), + ), + ( + "get_clients", + Object::from(Function::<_, Dictionary>::from_fn(get_clients)), ), - ("get_servers", Object::from(Function::from_fn(get_servers))), - ("get_clients", Object::from(Function::from_fn(get_clients))), ]) } diff --git a/rust/websocket-ffi/src/server/inbound_event.rs b/rust/websocket-ffi/src/server/inbound_event.rs index 1c952e1..e6b1220 100644 --- a/rust/websocket-ffi/src/server/inbound_event.rs +++ b/rust/websocket-ffi/src/server/inbound_event.rs @@ -1,16 +1,17 @@ -use mlua::prelude::{IntoLua, Lua, LuaResult, LuaValue}; -use nvim_oxi::Object; -use nvim_oxi::conversion::ToObject; +use nvim_oxi::{ + Object, + conversion::ToObject, + mlua::{IntoLua, Lua, Result as LuaResult, Value as LuaValue}, +}; use uuid::Uuid; #[derive(Clone)] pub enum WebsocketServerError { - ClientConnectionError(String), - ClientTerminationError(Uuid, String), - ServerTerminationError(String), - ReceiveMessageError(Uuid, String), - SendMessageError(Uuid, String), - BroadcastMessageError(String), + ClientTermination(Uuid, String), + ServerTermination(String), + ReceiveMessage(Uuid, String), + SendMessage(Uuid, String), + BroadcastMessage(String), } #[derive(Clone)] @@ -25,59 +26,48 @@ pub enum WebsocketServerInboundEvent { impl ToObject for WebsocketServerError { fn to_object(self) -> Result { match self { - WebsocketServerError::ClientConnectionError(message) => Ok(Object::from(message)), - WebsocketServerError::ClientTerminationError(_client_id, message) => { + WebsocketServerError::ClientTermination(_client_id, message) => { Ok(Object::from(message)) } - WebsocketServerError::ReceiveMessageError(_client_id, message) => { - Ok(Object::from(message)) - } - WebsocketServerError::SendMessageError(_client_id, message) => { - Ok(Object::from(message)) - } - WebsocketServerError::BroadcastMessageError(message) => Ok(Object::from(message)), - WebsocketServerError::ServerTerminationError(message) => Ok(Object::from(message)), + WebsocketServerError::ReceiveMessage(_client_id, message) => Ok(Object::from(message)), + WebsocketServerError::SendMessage(_client_id, message) => Ok(Object::from(message)), + WebsocketServerError::BroadcastMessage(message) => Ok(Object::from(message)), + WebsocketServerError::ServerTermination(message) => Ok(Object::from(message)), } } } -impl<'lua> IntoLua<'lua> for WebsocketServerError { - fn into_lua(self, lua: &'lua Lua) -> LuaResult> { +impl IntoLua for WebsocketServerError { + fn into_lua(self, lua: &Lua) -> LuaResult { let vec = match self { - WebsocketServerError::ClientConnectionError(message) => { - vec![ - ("type", "client_connection_error"), - ("message", message.leak()), - ] - } - WebsocketServerError::ClientTerminationError(client_id, message) => { + WebsocketServerError::ClientTermination(client_id, message) => { vec![ - ("type", "client_temrination_error"), + ("type", "client_termination_error"), ("client_id", client_id.to_string().leak()), ("message", message.leak()), ] } - WebsocketServerError::ReceiveMessageError(client_id, message) => { + WebsocketServerError::ReceiveMessage(client_id, message) => { vec![ ("type", "receive_message_error"), ("client_id", client_id.to_string().leak()), ("message", message.leak()), ] } - WebsocketServerError::SendMessageError(client_id, message) => { + WebsocketServerError::SendMessage(client_id, message) => { vec![ ("type", "send_message_error"), ("client_id", client_id.to_string().leak()), ("message", message.leak()), ] } - WebsocketServerError::BroadcastMessageError(message) => { + WebsocketServerError::BroadcastMessage(message) => { vec![ ("type", "broadcast_message_error"), ("message", message.leak()), ] } - WebsocketServerError::ServerTerminationError(message) => { + WebsocketServerError::ServerTermination(message) => { vec![ ("type", "server_termination_error"), ("message", message.leak()), diff --git a/rust/websocket-ffi/src/server/mod.rs b/rust/websocket-ffi/src/server/mod.rs index f3f4a44..4086e91 100644 --- a/rust/websocket-ffi/src/server/mod.rs +++ b/rust/websocket-ffi/src/server/mod.rs @@ -1,17 +1,20 @@ -use std::collections::HashMap; -use std::error::Error; -use std::sync::Arc; - -use mlua::prelude::{LuaFunction, LuaTable}; -use nvim_oxi::libuv::AsyncHandle; -use nvim_oxi::{mlua::lua, schedule}; +use log::info; +use nvim_oxi::{ + libuv::AsyncHandle, + mlua::{ + lua, + prelude::{LuaFunction, LuaTable}, + }, + schedule, +}; use parking_lot::Mutex; -use tokio::net::TcpListener; -use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender}; +use std::{collections::HashMap, error::Error, sync::Arc}; +use tokio::{ + net::TcpListener, + sync::mpsc::{self, UnboundedReceiver, UnboundedSender}, +}; use uuid::Uuid; -use log::info; - mod client; mod ffi; mod inbound_event; @@ -59,20 +62,13 @@ async fn start_server( tokio::spawn(WebsocketServerClient::run(stream, addr, inbound_event_publisher.clone(), lua_handle.clone(), extra_response_headers.clone(), message_replay_buffer.clone(), clients.clone())); } maybe_close_connection_event = close_connection_event_subscriber.recv() => { - if let Some(close_connection_event) = maybe_close_connection_event { - match close_connection_event { - WebsocketServerCloseConnectionEvent::Graceful => { - info!("Server received termination signal. Propagating to server clients"); - for client in clients.lock().values() { - let mut client = client.lock(); - client.terminate(); - } - break; - } - WebsocketServerCloseConnectionEvent::Forceful => { - break; - } + if maybe_close_connection_event.is_some() { + info!("Server received termination signal. Propagating to server clients"); + for client in clients.lock().values() { + let mut client = client.lock(); + client.terminate(); } + break; } } maybe_message = outbound_broadcast_message_receiver.recv() => { @@ -117,17 +113,17 @@ impl WebsocketServer { match event { WebsocketServerInboundEvent::ClientConnected(client_id) => { if let Some(on_connect) = callbacks_clone.on_client_connect { - on_connect.call::<_, ()>((id.to_string(), client_id.to_string()))?; + on_connect.call::<()>((id.to_string(), client_id.to_string()))?; } } WebsocketServerInboundEvent::ClientDisconnected(client_id) => { if let Some(on_disconnect) = callbacks_clone.on_client_disconnect { - on_disconnect.call::<_, ()>((id.to_string(), client_id.to_string()))?; + on_disconnect.call::<()>((id.to_string(), client_id.to_string()))?; } } WebsocketServerInboundEvent::NewMessage(client_id, message) => { if let Some(on_message) = callbacks_clone.on_message { - on_message.call::<_, ()>(( + on_message.call::<()>(( id.to_string(), client_id.to_string(), message, @@ -136,11 +132,11 @@ impl WebsocketServer { } WebsocketServerInboundEvent::Error(error) => { if let Some(on_error) = callbacks_clone.on_error { - on_error.call::<_, ()>((id.to_string(), error))?; + on_error.call::<()>((id.to_string(), error))?; } } } - Ok(()) + Ok::<(), nvim_oxi::Error>(()) }); Ok::<_, nvim_oxi::Error>(()) })?; @@ -191,10 +187,10 @@ impl WebsocketServer { fn terminate(&self) { self.close_connection_event_publisher - .send(WebsocketServerCloseConnectionEvent::Graceful) + .send(WebsocketServerCloseConnectionEvent) .unwrap_or_else(move |err| { self.send_event(WebsocketServerInboundEvent::Error( - WebsocketServerError::ServerTerminationError(err.to_string()), + WebsocketServerError::ServerTermination(err.to_string()), )); }); } @@ -221,42 +217,38 @@ impl WebsocketServer { .send(data) .unwrap_or_else(|err| { self.send_event(WebsocketServerInboundEvent::Error( - WebsocketServerError::BroadcastMessageError(err.to_string()), + WebsocketServerError::BroadcastMessage(err.to_string()), )); }); } } #[derive(Clone)] -struct WebsocketServerCallbacks<'a> { - on_message: Option>, - on_client_disconnect: Option>, - on_client_connect: Option>, - on_error: Option>, +struct WebsocketServerCallbacks { + on_message: Option, + on_client_disconnect: Option, + on_client_connect: Option, + on_error: Option, } -impl<'a> WebsocketServerCallbacks<'a> { +impl WebsocketServerCallbacks { fn new(server_id: Uuid) -> Result> { let lua = lua(); let callbacks = lua .globals() - .get::<_, LuaTable>("_WEBSOCKET_NVIM")? - .get::<_, LuaTable>("servers")? - .get::<_, LuaTable>("callbacks")? - .get::<_, LuaTable>(server_id.to_string())?; + .get::("_WEBSOCKET_NVIM")? + .get::("servers")? + .get::("callbacks")? + .get::(server_id.to_string())?; Ok(Self { - on_message: callbacks.get::<_, Option>("on_message")?, - on_client_disconnect: callbacks - .get::<_, Option>("on_client_disconnect")?, - on_client_connect: callbacks.get::<_, Option>("on_client_connect")?, - on_error: callbacks.get::<_, Option>("on_error")?, + on_message: callbacks.get::>("on_message")?, + on_client_disconnect: callbacks.get::>("on_client_disconnect")?, + on_client_connect: callbacks.get::>("on_client_connect")?, + on_error: callbacks.get::>("on_error")?, }) } } #[derive(Clone, Debug)] -pub enum WebsocketServerCloseConnectionEvent { - Graceful, - Forceful, -} +pub struct WebsocketServerCloseConnectionEvent;