feat: Add hyperdeck command
This commit is contained in:
parent
ee375e34a8
commit
f9cac35a29
|
@ -23,10 +23,6 @@ name = "accesskit"
|
||||||
version = "0.12.3"
|
version = "0.12.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "74a4b14f3d99c1255dcba8f45621ab1a2e7540a0009652d33989005a4d0bfc6b"
|
checksum = "74a4b14f3d99c1255dcba8f45621ab1a2e7540a0009652d33989005a4d0bfc6b"
|
||||||
dependencies = [
|
|
||||||
"enumn",
|
|
||||||
"serde",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "accesskit_consumer"
|
name = "accesskit_consumer"
|
||||||
|
@ -117,7 +113,6 @@ dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"getrandom",
|
"getrandom",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"serde",
|
|
||||||
"version_check",
|
"version_check",
|
||||||
"zerocopy",
|
"zerocopy",
|
||||||
]
|
]
|
||||||
|
@ -131,6 +126,27 @@ dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "alloc-no-stdlib"
|
||||||
|
version = "2.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "alloc-stdlib"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece"
|
||||||
|
dependencies = [
|
||||||
|
"alloc-no-stdlib",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "allocator-api2"
|
||||||
|
version = "0.2.16"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "android-activity"
|
name = "android-activity"
|
||||||
version = "0.5.2"
|
version = "0.5.2"
|
||||||
|
@ -202,6 +218,22 @@ dependencies = [
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-compression"
|
||||||
|
version = "0.4.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c90a406b4495d129f00461241616194cb8a032c8d1c53c657f0961d5f8e0498"
|
||||||
|
dependencies = [
|
||||||
|
"brotli",
|
||||||
|
"flate2",
|
||||||
|
"futures-core",
|
||||||
|
"memchr",
|
||||||
|
"pin-project-lite",
|
||||||
|
"tokio",
|
||||||
|
"zstd",
|
||||||
|
"zstd-safe",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-executor"
|
name = "async-executor"
|
||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
|
@ -415,6 +447,71 @@ version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
|
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "axum"
|
||||||
|
version = "0.6.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf"
|
||||||
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
|
"axum-core",
|
||||||
|
"axum-macros",
|
||||||
|
"base64",
|
||||||
|
"bitflags 1.3.2",
|
||||||
|
"bytes",
|
||||||
|
"futures-util",
|
||||||
|
"http 0.2.12",
|
||||||
|
"http-body",
|
||||||
|
"hyper",
|
||||||
|
"itoa",
|
||||||
|
"matchit",
|
||||||
|
"memchr",
|
||||||
|
"mime",
|
||||||
|
"percent-encoding",
|
||||||
|
"pin-project-lite",
|
||||||
|
"rustversion",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"serde_path_to_error",
|
||||||
|
"serde_urlencoded",
|
||||||
|
"sha1",
|
||||||
|
"sync_wrapper",
|
||||||
|
"tokio",
|
||||||
|
"tokio-tungstenite 0.20.1",
|
||||||
|
"tower",
|
||||||
|
"tower-layer",
|
||||||
|
"tower-service",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "axum-core"
|
||||||
|
version = "0.3.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c"
|
||||||
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
|
"bytes",
|
||||||
|
"futures-util",
|
||||||
|
"http 0.2.12",
|
||||||
|
"http-body",
|
||||||
|
"mime",
|
||||||
|
"rustversion",
|
||||||
|
"tower-layer",
|
||||||
|
"tower-service",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "axum-macros"
|
||||||
|
version = "0.3.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cdca6a10ecad987bda04e95606ef85a5417dcaac1a78455242d72e031e2b6b62"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.60",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "backtrace"
|
name = "backtrace"
|
||||||
version = "0.3.71"
|
version = "0.3.71"
|
||||||
|
@ -447,9 +544,6 @@ name = "bitflags"
|
||||||
version = "2.5.0"
|
version = "2.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
|
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
|
||||||
dependencies = [
|
|
||||||
"serde",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "block"
|
name = "block"
|
||||||
|
@ -527,6 +621,27 @@ dependencies = [
|
||||||
"piper",
|
"piper",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "brotli"
|
||||||
|
version = "6.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b"
|
||||||
|
dependencies = [
|
||||||
|
"alloc-no-stdlib",
|
||||||
|
"alloc-stdlib",
|
||||||
|
"brotli-decompressor",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "brotli-decompressor"
|
||||||
|
version = "4.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e6221fe77a248b9117d431ad93761222e1cf8ff282d9d1d5d9f53d6299a1cf76"
|
||||||
|
dependencies = [
|
||||||
|
"alloc-no-stdlib",
|
||||||
|
"alloc-stdlib",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bumpalo"
|
name = "bumpalo"
|
||||||
version = "3.16.0"
|
version = "3.16.0"
|
||||||
|
@ -827,27 +942,6 @@ dependencies = [
|
||||||
"crypto-common",
|
"crypto-common",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "directories-next"
|
|
||||||
version = "2.0.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "339ee130d97a610ea5a5872d2bbb130fdf68884ff09d3028b81bec8a1ac23bbc"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"dirs-sys-next",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "dirs-sys-next"
|
|
||||||
version = "0.1.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"redox_users",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dispatch"
|
name = "dispatch"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
@ -885,7 +979,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "20930a432bbd57a6d55e07976089708d4893f3d556cf42a0d79e9e321fa73b10"
|
checksum = "20930a432bbd57a6d55e07976089708d4893f3d556cf42a0d79e9e321fa73b10"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"serde",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -896,7 +989,6 @@ checksum = "020e2ccef6bbcec71dbc542f7eed64a5846fc3076727f5746da8fd307c91bab2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"cocoa",
|
"cocoa",
|
||||||
"directories-next",
|
|
||||||
"document-features",
|
"document-features",
|
||||||
"egui",
|
"egui",
|
||||||
"egui-winit",
|
"egui-winit",
|
||||||
|
@ -912,8 +1004,6 @@ dependencies = [
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"raw-window-handle 0.5.2",
|
"raw-window-handle 0.5.2",
|
||||||
"raw-window-handle 0.6.1",
|
"raw-window-handle 0.6.1",
|
||||||
"ron",
|
|
||||||
"serde",
|
|
||||||
"static_assertions",
|
"static_assertions",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
|
@ -935,8 +1025,6 @@ dependencies = [
|
||||||
"epaint",
|
"epaint",
|
||||||
"log",
|
"log",
|
||||||
"nohash-hasher",
|
"nohash-hasher",
|
||||||
"ron",
|
|
||||||
"serde",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -950,7 +1038,6 @@ dependencies = [
|
||||||
"egui",
|
"egui",
|
||||||
"log",
|
"log",
|
||||||
"raw-window-handle 0.6.1",
|
"raw-window-handle 0.6.1",
|
||||||
"serde",
|
|
||||||
"smithay-clipboard",
|
"smithay-clipboard",
|
||||||
"web-time",
|
"web-time",
|
||||||
"webbrowser",
|
"webbrowser",
|
||||||
|
@ -979,7 +1066,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e4c3a552cfca14630702449d35f41c84a0d15963273771c6059175a803620f3f"
|
checksum = "e4c3a552cfca14630702449d35f41c84a0d15963273771c6059175a803620f3f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"serde",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1003,17 +1089,6 @@ dependencies = [
|
||||||
"syn 2.0.60",
|
"syn 2.0.60",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "enumn"
|
|
||||||
version = "0.1.13"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6fd000fd6988e73bbe993ea3db9b1aa64906ab88766d654973924340c8cddb42"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 2.0.60",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "env_logger"
|
name = "env_logger"
|
||||||
version = "0.10.2"
|
version = "0.10.2"
|
||||||
|
@ -1041,7 +1116,6 @@ dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"nohash-hasher",
|
"nohash-hasher",
|
||||||
"parking_lot 0.12.2",
|
"parking_lot 0.12.2",
|
||||||
"serde",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1125,6 +1199,21 @@ dependencies = [
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ewebsock"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6177769715c6ec5a324acee995183b22721ea23c58e49af14a828eadec85d120"
|
||||||
|
dependencies = [
|
||||||
|
"document-features",
|
||||||
|
"js-sys",
|
||||||
|
"log",
|
||||||
|
"tungstenite 0.21.0",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"wasm-bindgen-futures",
|
||||||
|
"web-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "eyre"
|
name = "eyre"
|
||||||
version = "0.6.12"
|
version = "0.6.12"
|
||||||
|
@ -1453,11 +1542,37 @@ dependencies = [
|
||||||
"gl_generator",
|
"gl_generator",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.12.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.14.5"
|
version = "0.14.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||||
|
dependencies = [
|
||||||
|
"ahash",
|
||||||
|
"allocator-api2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hdrhistogram"
|
||||||
|
version = "7.5.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "765c9198f173dd59ce26ff9f95ef0aafd0a0fe01fb9d72841bc5066a4c06511d"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
|
@ -1486,6 +1601,17 @@ version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2a80870ee775a6b862265eb04a8d61d1b1ef8e4c423154a52ba6a1e3ff24836c"
|
checksum = "2a80870ee775a6b862265eb04a8d61d1b1ef8e4c423154a52ba6a1e3ff24836c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "http"
|
||||||
|
version = "0.2.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"fnv",
|
||||||
|
"itoa",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "http"
|
name = "http"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
|
@ -1497,32 +1623,84 @@ dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "http-body"
|
||||||
|
version = "0.4.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"http 0.2.12",
|
||||||
|
"pin-project-lite",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "http-range-header"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "httparse"
|
name = "httparse"
|
||||||
version = "1.8.0"
|
version = "1.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
|
checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "httpdate"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "humantime"
|
name = "humantime"
|
||||||
version = "2.1.0"
|
version = "2.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hyper"
|
||||||
|
version = "0.14.28"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"futures-channel",
|
||||||
|
"futures-core",
|
||||||
|
"futures-util",
|
||||||
|
"http 0.2.12",
|
||||||
|
"http-body",
|
||||||
|
"httparse",
|
||||||
|
"httpdate",
|
||||||
|
"itoa",
|
||||||
|
"pin-project-lite",
|
||||||
|
"socket2 0.5.7",
|
||||||
|
"tokio",
|
||||||
|
"tower-service",
|
||||||
|
"tracing",
|
||||||
|
"want",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyperdeck-monitor"
|
name = "hyperdeck-monitor"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"axum",
|
||||||
"color-eyre",
|
"color-eyre",
|
||||||
|
"futures",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-tungstenite",
|
"tokio-stream",
|
||||||
|
"tokio-tungstenite 0.21.0",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
|
"tower",
|
||||||
|
"tower-http",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
"url",
|
"url",
|
||||||
|
"uuid",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1532,9 +1710,11 @@ dependencies = [
|
||||||
"eframe",
|
"eframe",
|
||||||
"egui",
|
"egui",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
|
"ewebsock",
|
||||||
"hrtime",
|
"hrtime",
|
||||||
"log",
|
"log",
|
||||||
"serde",
|
"serde",
|
||||||
|
"serde_json",
|
||||||
"wasm-bindgen-futures",
|
"wasm-bindgen-futures",
|
||||||
"wasm-timer",
|
"wasm-timer",
|
||||||
]
|
]
|
||||||
|
@ -1579,6 +1759,16 @@ version = "0.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
|
checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "1.9.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"hashbrown 0.12.3",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "2.2.6"
|
version = "2.2.6"
|
||||||
|
@ -1586,7 +1776,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
|
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"equivalent",
|
"equivalent",
|
||||||
"hashbrown",
|
"hashbrown 0.14.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1609,6 +1799,16 @@ dependencies = [
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "iri-string"
|
||||||
|
version = "0.7.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f5f6c2df22c009ac44f6f1499308e7a3ac7ba42cd2378475cc691510e1eef1b"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "is-terminal"
|
name = "is-terminal"
|
||||||
version = "0.4.12"
|
version = "0.4.12"
|
||||||
|
@ -1705,16 +1905,6 @@ dependencies = [
|
||||||
"redox_syscall 0.4.1",
|
"redox_syscall 0.4.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "libredox"
|
|
||||||
version = "0.1.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags 2.5.0",
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linux-raw-sys"
|
name = "linux-raw-sys"
|
||||||
version = "0.3.8"
|
version = "0.3.8"
|
||||||
|
@ -1767,6 +1957,12 @@ dependencies = [
|
||||||
"regex-automata 0.1.10",
|
"regex-automata 0.1.10",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "matchit"
|
||||||
|
version = "0.7.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.7.2"
|
version = "2.7.2"
|
||||||
|
@ -1800,6 +1996,22 @@ dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mime"
|
||||||
|
version = "0.3.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mime_guess"
|
||||||
|
version = "2.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef"
|
||||||
|
dependencies = [
|
||||||
|
"mime",
|
||||||
|
"unicase",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miniz_oxide"
|
name = "miniz_oxide"
|
||||||
version = "0.7.2"
|
version = "0.7.2"
|
||||||
|
@ -2047,7 +2259,7 @@ version = "0.3.47"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "52f0d54bde9774d3a51dcf281a5def240c71996bc6ca05d2c847ec8b2b216166"
|
checksum = "52f0d54bde9774d3a51dcf281a5def240c71996bc6ca05d2c847ec8b2b216166"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libredox 0.0.2",
|
"libredox",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2147,6 +2359,26 @@ version = "2.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
|
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pin-project"
|
||||||
|
version = "1.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3"
|
||||||
|
dependencies = [
|
||||||
|
"pin-project-internal",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pin-project-internal"
|
||||||
|
version = "1.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.60",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project-lite"
|
name = "pin-project-lite"
|
||||||
version = "0.2.14"
|
version = "0.2.14"
|
||||||
|
@ -2350,17 +2582,6 @@ dependencies = [
|
||||||
"bitflags 2.5.0",
|
"bitflags 2.5.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "redox_users"
|
|
||||||
version = "0.4.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891"
|
|
||||||
dependencies = [
|
|
||||||
"getrandom",
|
|
||||||
"libredox 0.1.3",
|
|
||||||
"thiserror",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.10.4"
|
version = "1.10.4"
|
||||||
|
@ -2405,18 +2626,6 @@ version = "0.8.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
|
checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ron"
|
|
||||||
version = "0.8.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94"
|
|
||||||
dependencies = [
|
|
||||||
"base64",
|
|
||||||
"bitflags 2.5.0",
|
|
||||||
"serde",
|
|
||||||
"serde_derive",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-demangle"
|
name = "rustc-demangle"
|
||||||
version = "0.1.23"
|
version = "0.1.23"
|
||||||
|
@ -2450,6 +2659,12 @@ dependencies = [
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustversion"
|
||||||
|
version = "1.0.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
version = "1.0.17"
|
version = "1.0.17"
|
||||||
|
@ -2499,15 +2714,25 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.116"
|
version = "1.0.117"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813"
|
checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_path_to_error"
|
||||||
|
version = "0.1.16"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_repr"
|
name = "serde_repr"
|
||||||
version = "0.1.19"
|
version = "0.1.19"
|
||||||
|
@ -2519,6 +2744,18 @@ dependencies = [
|
||||||
"syn 2.0.60",
|
"syn 2.0.60",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_urlencoded"
|
||||||
|
version = "0.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
|
||||||
|
dependencies = [
|
||||||
|
"form_urlencoded",
|
||||||
|
"itoa",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sha1"
|
name = "sha1"
|
||||||
version = "0.10.6"
|
version = "0.10.6"
|
||||||
|
@ -2671,6 +2908,12 @@ dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sync_wrapper"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tempfile"
|
name = "tempfile"
|
||||||
version = "3.10.1"
|
version = "3.10.1"
|
||||||
|
@ -2767,6 +3010,30 @@ dependencies = [
|
||||||
"syn 2.0.60",
|
"syn 2.0.60",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-stream"
|
||||||
|
version = "0.1.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"pin-project-lite",
|
||||||
|
"tokio",
|
||||||
|
"tokio-util",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-tungstenite"
|
||||||
|
version = "0.20.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c"
|
||||||
|
dependencies = [
|
||||||
|
"futures-util",
|
||||||
|
"log",
|
||||||
|
"tokio",
|
||||||
|
"tungstenite 0.20.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-tungstenite"
|
name = "tokio-tungstenite"
|
||||||
version = "0.21.0"
|
version = "0.21.0"
|
||||||
|
@ -2776,19 +3043,23 @@ dependencies = [
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"log",
|
"log",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tungstenite",
|
"tungstenite 0.21.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-util"
|
name = "tokio-util"
|
||||||
version = "0.7.10"
|
version = "0.7.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15"
|
checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
"futures-io",
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
|
"futures-util",
|
||||||
|
"hashbrown 0.14.5",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
"slab",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2804,7 +3075,7 @@ version = "0.19.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
|
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap 2.2.6",
|
||||||
"toml_datetime",
|
"toml_datetime",
|
||||||
"winnow",
|
"winnow",
|
||||||
]
|
]
|
||||||
|
@ -2815,17 +3086,81 @@ version = "0.21.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1"
|
checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap 2.2.6",
|
||||||
"toml_datetime",
|
"toml_datetime",
|
||||||
"winnow",
|
"winnow",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tower"
|
||||||
|
version = "0.4.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"futures-util",
|
||||||
|
"hdrhistogram",
|
||||||
|
"indexmap 1.9.3",
|
||||||
|
"pin-project",
|
||||||
|
"pin-project-lite",
|
||||||
|
"rand",
|
||||||
|
"slab",
|
||||||
|
"tokio",
|
||||||
|
"tokio-util",
|
||||||
|
"tower-layer",
|
||||||
|
"tower-service",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tower-http"
|
||||||
|
version = "0.4.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140"
|
||||||
|
dependencies = [
|
||||||
|
"async-compression",
|
||||||
|
"base64",
|
||||||
|
"bitflags 2.5.0",
|
||||||
|
"bytes",
|
||||||
|
"futures-core",
|
||||||
|
"futures-util",
|
||||||
|
"http 0.2.12",
|
||||||
|
"http-body",
|
||||||
|
"http-range-header",
|
||||||
|
"httpdate",
|
||||||
|
"iri-string",
|
||||||
|
"mime",
|
||||||
|
"mime_guess",
|
||||||
|
"percent-encoding",
|
||||||
|
"pin-project-lite",
|
||||||
|
"tokio",
|
||||||
|
"tokio-util",
|
||||||
|
"tower",
|
||||||
|
"tower-layer",
|
||||||
|
"tower-service",
|
||||||
|
"tracing",
|
||||||
|
"uuid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tower-layer"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tower-service"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing"
|
name = "tracing"
|
||||||
version = "0.1.40"
|
version = "0.1.40"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
|
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"log",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"tracing-attributes",
|
"tracing-attributes",
|
||||||
"tracing-core",
|
"tracing-core",
|
||||||
|
@ -2891,12 +3226,37 @@ dependencies = [
|
||||||
"tracing-log",
|
"tracing-log",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "try-lock"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ttf-parser"
|
name = "ttf-parser"
|
||||||
version = "0.20.0"
|
version = "0.20.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "17f77d76d837a7830fe1d4f12b7b4ba4192c1888001c7164257e4bc6d21d96b4"
|
checksum = "17f77d76d837a7830fe1d4f12b7b4ba4192c1888001c7164257e4bc6d21d96b4"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tungstenite"
|
||||||
|
version = "0.20.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
"bytes",
|
||||||
|
"data-encoding",
|
||||||
|
"http 0.2.12",
|
||||||
|
"httparse",
|
||||||
|
"log",
|
||||||
|
"rand",
|
||||||
|
"sha1",
|
||||||
|
"thiserror",
|
||||||
|
"url",
|
||||||
|
"utf-8",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tungstenite"
|
name = "tungstenite"
|
||||||
version = "0.21.0"
|
version = "0.21.0"
|
||||||
|
@ -2906,7 +3266,7 @@ dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"bytes",
|
"bytes",
|
||||||
"data-encoding",
|
"data-encoding",
|
||||||
"http",
|
"http 1.1.0",
|
||||||
"httparse",
|
"httparse",
|
||||||
"log",
|
"log",
|
||||||
"rand",
|
"rand",
|
||||||
|
@ -2933,6 +3293,15 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicase"
|
||||||
|
version = "2.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89"
|
||||||
|
dependencies = [
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-bidi"
|
name = "unicode-bidi"
|
||||||
version = "0.3.15"
|
version = "0.3.15"
|
||||||
|
@ -2977,6 +3346,16 @@ version = "0.7.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uuid"
|
||||||
|
version = "1.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "valuable"
|
name = "valuable"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -3005,6 +3384,15 @@ dependencies = [
|
||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "want"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
|
||||||
|
dependencies = [
|
||||||
|
"try-lock",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasi"
|
||||||
version = "0.11.0+wasi-snapshot-preview1"
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
|
@ -3723,6 +4111,34 @@ dependencies = [
|
||||||
"syn 2.0.60",
|
"syn 2.0.60",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zstd"
|
||||||
|
version = "0.13.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2d789b1514203a1120ad2429eae43a7bd32b90976a7bb8a05f7ec02fa88cc23a"
|
||||||
|
dependencies = [
|
||||||
|
"zstd-safe",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zstd-safe"
|
||||||
|
version = "7.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1cd99b45c6bc03a018c8b8a86025678c87e55526064e38f9df301989dce7ec0a"
|
||||||
|
dependencies = [
|
||||||
|
"zstd-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zstd-sys"
|
||||||
|
version = "2.0.10+zstd.1.5.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c253a4914af5bafc8fa8c86ee400827e83cf6ec01195ec1f1ed8441bf00d65aa"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"pkg-config",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zvariant"
|
name = "zvariant"
|
||||||
version = "3.15.2"
|
version = "3.15.2"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
"monitor",
|
"monitor",
|
||||||
"frontend"
|
"frontend",
|
||||||
]
|
]
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# Copied during build (🤮)
|
||||||
|
src/websocket.rs
|
||||||
|
|
||||||
# trunk output folder
|
# trunk output folder
|
||||||
dist
|
dist
|
||||||
|
|
||||||
|
|
|
@ -9,12 +9,13 @@ eframe = { version = "0.27.0", default-features = false, features = [
|
||||||
"accesskit", # Make egui comptaible with screen readers.
|
"accesskit", # Make egui comptaible with screen readers.
|
||||||
"default_fonts", # Embed the default egui fonts.
|
"default_fonts", # Embed the default egui fonts.
|
||||||
"glow", # Use the glow rendering backend. Alternative: "wgpu".
|
"glow", # Use the glow rendering backend. Alternative: "wgpu".
|
||||||
"persistence", # Enable restoring app state when restarting the app.
|
|
||||||
] }
|
] }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
hrtime = "0.2.0"
|
hrtime = "0.2.0"
|
||||||
wasm-timer = "0.2.5"
|
wasm-timer = "0.2.5"
|
||||||
|
ewebsock = "0.5.0"
|
||||||
|
serde_json = "1.0.117"
|
||||||
|
|
||||||
|
|
||||||
# native:
|
# native:
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
fn main() {
|
||||||
|
// Sorry, I know it's horrible but I don't have the spoons to make it right.
|
||||||
|
const API_DEFINITION_FILE: &str = "../monitor/src/api/message.rs";
|
||||||
|
println!("cargo:rerun-if-changed={API_DEFINITION_FILE}");
|
||||||
|
std::fs::copy(API_DEFINITION_FILE, "./src/websocket.rs")
|
||||||
|
.expect("Failed to copy API definition");
|
||||||
|
}
|
|
@ -1,35 +1,38 @@
|
||||||
use std::{
|
use std::{
|
||||||
|
collections::VecDeque,
|
||||||
fmt::Display,
|
fmt::Display,
|
||||||
|
mem,
|
||||||
net::{IpAddr, Ipv4Addr},
|
net::{IpAddr, Ipv4Addr},
|
||||||
};
|
};
|
||||||
|
|
||||||
use egui::{Color32, RichText, Sense, Stroke, Vec2};
|
use egui::{Button, Color32, RichText, Sense, Stroke, Vec2};
|
||||||
|
use ewebsock::{Options, WsReceiver, WsSender};
|
||||||
use wasm_timer::Instant;
|
use wasm_timer::Instant;
|
||||||
|
|
||||||
#[derive(serde::Deserialize, serde::Serialize)]
|
use crate::websocket::{AddHyperdeckRequest, ClientRequest};
|
||||||
#[serde(default)]
|
|
||||||
pub struct HyperdeckMonitorApp {
|
pub struct HyperdeckMonitorApp {
|
||||||
#[serde(skip)]
|
|
||||||
blink: bool,
|
blink: bool,
|
||||||
#[serde(skip)]
|
|
||||||
last_blink_change: Instant,
|
last_blink_change: Instant,
|
||||||
#[serde(skip)]
|
|
||||||
new_hyperdeck_ip: String,
|
new_hyperdeck_ip: String,
|
||||||
|
|
||||||
#[serde(skip)]
|
|
||||||
new_hyperdeck_name: String,
|
new_hyperdeck_name: String,
|
||||||
|
new_hyperdeck_port: String,
|
||||||
#[serde(skip)]
|
|
||||||
hyperdecks: Vec<Hyperdeck>,
|
hyperdecks: Vec<Hyperdeck>,
|
||||||
|
websocket_message_queue: VecDeque<ClientRequest>,
|
||||||
|
ws_sender: WsSender,
|
||||||
|
ws_receiver: WsReceiver,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for HyperdeckMonitorApp {
|
impl Default for HyperdeckMonitorApp {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
let (ws_sender, ws_receiver) =
|
||||||
|
ewebsock::connect("ws://127.0.0.1:9681/ws", Options::default()).unwrap();
|
||||||
Self {
|
Self {
|
||||||
blink: false,
|
blink: false,
|
||||||
last_blink_change: Instant::now(),
|
last_blink_change: Instant::now(),
|
||||||
new_hyperdeck_ip: "".to_owned(),
|
new_hyperdeck_ip: "".to_owned(),
|
||||||
new_hyperdeck_name: "".to_owned(),
|
new_hyperdeck_name: "".to_owned(),
|
||||||
|
new_hyperdeck_port: 9993.to_string(),
|
||||||
hyperdecks: vec![
|
hyperdecks: vec![
|
||||||
Hyperdeck {
|
Hyperdeck {
|
||||||
name: "Test Hyperdeck 1".to_string(),
|
name: "Test Hyperdeck 1".to_string(),
|
||||||
|
@ -52,27 +55,20 @@ impl Default for HyperdeckMonitorApp {
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
websocket_message_queue: VecDeque::new(),
|
||||||
|
ws_sender,
|
||||||
|
ws_receiver,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HyperdeckMonitorApp {
|
|
||||||
pub fn new(cc: &eframe::CreationContext<'_>) -> Self {
|
|
||||||
// Load previous app state (if any)
|
|
||||||
if let Some(storage) = cc.storage {
|
|
||||||
return eframe::get_value(storage, eframe::APP_KEY).unwrap_or_default();
|
|
||||||
}
|
|
||||||
|
|
||||||
Default::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl eframe::App for HyperdeckMonitorApp {
|
impl eframe::App for HyperdeckMonitorApp {
|
||||||
fn save(&mut self, storage: &mut dyn eframe::Storage) {
|
|
||||||
eframe::set_value(storage, eframe::APP_KEY, self);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
|
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
|
||||||
|
if let Some(message) = self.websocket_message_queue.pop_front() {
|
||||||
|
self.ws_sender.send(ewebsock::WsMessage::Text(
|
||||||
|
serde_json::to_string(&message).expect("Could not serialize message"),
|
||||||
|
));
|
||||||
|
}
|
||||||
egui::TopBottomPanel::top("top_panel").show(ctx, |ui| {
|
egui::TopBottomPanel::top("top_panel").show(ctx, |ui| {
|
||||||
egui::menu::bar(ui, |ui| {
|
egui::menu::bar(ui, |ui| {
|
||||||
egui::widgets::global_dark_light_mode_buttons(ui);
|
egui::widgets::global_dark_light_mode_buttons(ui);
|
||||||
|
@ -80,7 +76,13 @@ impl eframe::App for HyperdeckMonitorApp {
|
||||||
});
|
});
|
||||||
|
|
||||||
egui::CentralPanel::default().show(ctx, |ui| {
|
egui::CentralPanel::default().show(ctx, |ui| {
|
||||||
add_hyperdeck_panel(ui, &mut self.new_hyperdeck_ip, &mut self.new_hyperdeck_name);
|
add_hyperdeck_panel(
|
||||||
|
ui,
|
||||||
|
&mut self.new_hyperdeck_name,
|
||||||
|
&mut self.new_hyperdeck_ip,
|
||||||
|
&mut self.new_hyperdeck_port,
|
||||||
|
&mut self.websocket_message_queue,
|
||||||
|
);
|
||||||
ui.separator();
|
ui.separator();
|
||||||
|
|
||||||
ui.vertical(|ui| {
|
ui.vertical(|ui| {
|
||||||
|
@ -105,8 +107,10 @@ impl eframe::App for HyperdeckMonitorApp {
|
||||||
|
|
||||||
fn add_hyperdeck_panel(
|
fn add_hyperdeck_panel(
|
||||||
ui: &mut egui::Ui,
|
ui: &mut egui::Ui,
|
||||||
new_hyperdeck_ip: &mut String,
|
|
||||||
new_hyperdeck_name: &mut String,
|
new_hyperdeck_name: &mut String,
|
||||||
|
new_hyperdeck_ip: &mut String,
|
||||||
|
new_hyperdeck_port: &mut String,
|
||||||
|
message_queue: &mut VecDeque<ClientRequest>,
|
||||||
) {
|
) {
|
||||||
ui.heading("Add hyperdeck");
|
ui.heading("Add hyperdeck");
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
|
@ -114,8 +118,19 @@ fn add_hyperdeck_panel(
|
||||||
ui.text_edit_singleline(new_hyperdeck_name);
|
ui.text_edit_singleline(new_hyperdeck_name);
|
||||||
ui.label("IP");
|
ui.label("IP");
|
||||||
ui.text_edit_singleline(new_hyperdeck_ip);
|
ui.text_edit_singleline(new_hyperdeck_ip);
|
||||||
if ui.button("Add").clicked() {
|
ui.label("Port");
|
||||||
// Do Something
|
ui.text_edit_singleline(new_hyperdeck_port);
|
||||||
|
let button_enabled = new_hyperdeck_ip.parse::<IpAddr>().is_ok()
|
||||||
|
&& !new_hyperdeck_name.is_empty()
|
||||||
|
&& new_hyperdeck_port.parse::<u16>().is_ok();
|
||||||
|
if ui.add_enabled(button_enabled, Button::new("Add")).clicked() {
|
||||||
|
message_queue.push_back(ClientRequest::AddHyperdeck(AddHyperdeckRequest {
|
||||||
|
name: mem::take(new_hyperdeck_name),
|
||||||
|
ip: mem::take(new_hyperdeck_ip),
|
||||||
|
port: mem::replace(new_hyperdeck_port, "9993".to_string())
|
||||||
|
.parse::<u16>()
|
||||||
|
.unwrap(),
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
mod app;
|
mod app;
|
||||||
|
mod websocket;
|
||||||
|
|
||||||
pub use app::HyperdeckMonitorApp;
|
pub use app::HyperdeckMonitorApp;
|
||||||
|
|
|
@ -11,7 +11,7 @@ fn main() -> eframe::Result<()> {
|
||||||
eframe::run_native(
|
eframe::run_native(
|
||||||
"eframe template",
|
"eframe template",
|
||||||
native_options,
|
native_options,
|
||||||
Box::new(|cc| Box::new(hyperdeck_monitor_gui::HyperdeckMonitorApp::new(cc))),
|
Box::new(|_| Box::new(hyperdeck_monitor_gui::HyperdeckMonitorApp::default())),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ fn main() {
|
||||||
.start(
|
.start(
|
||||||
"the_canvas_id", // Where to draw to.
|
"the_canvas_id", // Where to draw to.
|
||||||
web_options,
|
web_options,
|
||||||
Box::new(|cc| Box::new(hyperdeck_monitor_gui::HyperdeckMonitorApp::new(cc))),
|
Box::new(|_| Box::new(hyperdeck_monitor_gui::HyperdeckMonitorApp::default())),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.expect("failed to start eframe");
|
.expect("failed to start eframe");
|
||||||
|
|
|
@ -6,13 +6,19 @@ edition = "2021"
|
||||||
default-run = "hyperdeck-monitor"
|
default-run = "hyperdeck-monitor"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
axum = { version = "0.6.10", features = ["macros", "ws"] }
|
||||||
color-eyre = "0.6.3"
|
color-eyre = "0.6.3"
|
||||||
|
futures = { version = "0.3.25" }
|
||||||
futures-util = "0.3.30"
|
futures-util = "0.3.30"
|
||||||
serde = { version = "1.0.199", features = ["derive"] }
|
serde = { version = "1.0.199", features = ["derive"] }
|
||||||
serde_json = "1.0.116"
|
serde_json = "1.0.116"
|
||||||
tokio = { version = "1.37.0", features = ["full"] }
|
tokio = { version = "1.37.0", features = ["full"] }
|
||||||
|
tokio-stream = { version = "0.1.12", features = ["sync"] }
|
||||||
tokio-tungstenite = "0.21.0"
|
tokio-tungstenite = "0.21.0"
|
||||||
tokio-util = "0.7.10"
|
tokio-util = { version = "0.7.11", features = ["full"] }
|
||||||
|
tower = { version = "0.4.13", features = ["full"] }
|
||||||
|
tower-http = { version = "0.4.0", features = ["full"] }
|
||||||
tracing = "0.1.40"
|
tracing = "0.1.40"
|
||||||
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
||||||
url = "2.5.0"
|
url = "2.5.0"
|
||||||
|
uuid = { version = "1.2.2", features = ["serde", "v4"] }
|
||||||
|
|
|
@ -1,10 +1,35 @@
|
||||||
|
import { Hyperdeck, Commands } from 'hyperdeck-connection';
|
||||||
import WebSocket from 'ws';
|
import WebSocket from 'ws';
|
||||||
|
|
||||||
|
interface WrappedHyperdeck {
|
||||||
|
ip: String,
|
||||||
|
port: number,
|
||||||
|
hyperdeck: Hyperdeck
|
||||||
|
}
|
||||||
|
|
||||||
|
const hyperdecks: Map<string, WrappedHyperdeck> = new Map()
|
||||||
|
|
||||||
|
enum WebSocketMessageType {
|
||||||
|
AddHyperdeck = "add_hyperdeck"
|
||||||
|
}
|
||||||
|
|
||||||
|
type WebSocketMessage = {
|
||||||
|
type: WebSocketMessageType.AddHyperdeck,
|
||||||
|
id: string,
|
||||||
|
ip: string,
|
||||||
|
port: number
|
||||||
|
}
|
||||||
|
|
||||||
const wss = new WebSocket.Server({ port: 7867 });
|
const wss = new WebSocket.Server({ port: 7867 });
|
||||||
|
|
||||||
wss.on('connection', function connection(ws) {
|
wss.on('connection', function connection(ws) {
|
||||||
ws.on('message', function message(data) {
|
ws.on('message', function message(data) {
|
||||||
console.log('received: %s', data);
|
try {
|
||||||
|
const message = JSON.parse(data.toString()) as Partial<WebSocketMessage>;
|
||||||
|
handle_message(message)
|
||||||
|
} catch (_err) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ws.send(JSON.stringify({
|
ws.send(JSON.stringify({
|
||||||
|
@ -12,3 +37,55 @@ wss.on('connection', function connection(ws) {
|
||||||
message: "Hello"
|
message: "Hello"
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function exhaustiveMatch(_never: never) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle_message(message: Partial<WebSocketMessage>) {
|
||||||
|
console.log(JSON.stringify(message));
|
||||||
|
if (message.type === undefined) return;
|
||||||
|
|
||||||
|
switch (message.type) {
|
||||||
|
case WebSocketMessageType.AddHyperdeck:
|
||||||
|
if (message.id === undefined) return;
|
||||||
|
if (message.ip === undefined) return;
|
||||||
|
if (message.port === undefined) return;
|
||||||
|
if (isNaN(message.port)) return;
|
||||||
|
if (message.port <= 0) return;
|
||||||
|
|
||||||
|
console.log("Adding hyperdeck");
|
||||||
|
|
||||||
|
const newHyperdeck = new Hyperdeck()
|
||||||
|
|
||||||
|
// hyperdecks.set(message.id, {
|
||||||
|
// ip: message.ip,
|
||||||
|
// port: message.port,
|
||||||
|
// hyperdeck: newHyperdeck
|
||||||
|
// });
|
||||||
|
|
||||||
|
newHyperdeck.on('connected', (info) => {
|
||||||
|
console.log(JSON.stringify(info))
|
||||||
|
|
||||||
|
newHyperdeck.sendCommand(new Commands.TransportInfoCommand()).then((transportInfo) => {
|
||||||
|
console.log(JSON.stringify(transportInfo))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
newHyperdeck.on('notify.slot', function (state) {
|
||||||
|
console.log(JSON.stringify(state)) // catch the slot state change.
|
||||||
|
})
|
||||||
|
newHyperdeck.on('notify.transport', function (state) {
|
||||||
|
console.log(JSON.stringify(state)) // catch the transport state change.
|
||||||
|
})
|
||||||
|
newHyperdeck.on('error', (err) => {
|
||||||
|
console.log('Hyperdeck error', JSON.stringify(err))
|
||||||
|
})
|
||||||
|
|
||||||
|
newHyperdeck.connect(message.ip, message.port)
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
exhaustiveMatch(message.type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,172 @@
|
||||||
|
use axum::extract::ws::Message;
|
||||||
|
use axum::extract::{State, WebSocketUpgrade};
|
||||||
|
use axum::response::Html;
|
||||||
|
use axum::{
|
||||||
|
body::Bytes,
|
||||||
|
extract::Path,
|
||||||
|
http::{header, HeaderValue, Method},
|
||||||
|
response::IntoResponse,
|
||||||
|
routing::get,
|
||||||
|
Router,
|
||||||
|
};
|
||||||
|
use message::{ClientRequest, HyperdeckMonitorState, ServerEvent};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
net::{Ipv4Addr, SocketAddr},
|
||||||
|
sync::Arc,
|
||||||
|
time::Duration,
|
||||||
|
};
|
||||||
|
use tokio::sync::{Mutex, RwLock};
|
||||||
|
use tower::ServiceBuilder;
|
||||||
|
use tower_http::timeout::TimeoutLayer;
|
||||||
|
use tower_http::ServiceBuilderExt;
|
||||||
|
use tower_http::{
|
||||||
|
cors::{Any, CorsLayer},
|
||||||
|
trace::{DefaultMakeSpan, DefaultOnResponse, TraceLayer},
|
||||||
|
LatencyUnit,
|
||||||
|
};
|
||||||
|
use tracing::info;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
pub mod message;
|
||||||
|
mod ws;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Client {
|
||||||
|
pub sender: Option<tokio::sync::broadcast::Sender<Message>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
type Clients = Arc<Mutex<HashMap<Uuid, Client>>>;
|
||||||
|
|
||||||
|
pub async fn initialize_api(
|
||||||
|
mut state_rx: tokio::sync::broadcast::Receiver<HyperdeckMonitorState>,
|
||||||
|
client_request_tx: tokio::sync::mpsc::UnboundedSender<ClientRequest>,
|
||||||
|
) {
|
||||||
|
info!("Initializing API");
|
||||||
|
|
||||||
|
let clients: Clients = Default::default();
|
||||||
|
|
||||||
|
let state = Arc::new(RwLock::new(state_rx.recv().await.unwrap()));
|
||||||
|
|
||||||
|
let state_clients = clients.clone();
|
||||||
|
let state_loop = state.clone();
|
||||||
|
tokio::spawn(async move {
|
||||||
|
loop {
|
||||||
|
if let Ok(hyperdeck_monitor_state) = state_rx.recv().await {
|
||||||
|
let mut state = state_loop.write().await;
|
||||||
|
*state = hyperdeck_monitor_state.clone();
|
||||||
|
|
||||||
|
let clients = state_clients.lock().await;
|
||||||
|
let state_json = serde_json::to_string(&ServerEvent::HyperdeckMonitorState(
|
||||||
|
hyperdeck_monitor_state.into(),
|
||||||
|
))
|
||||||
|
.unwrap();
|
||||||
|
for (_, client) in clients.iter() {
|
||||||
|
if let Some(sender) = &client.sender {
|
||||||
|
let message: Message = Message::Text(state_json.clone());
|
||||||
|
let _ = sender.send(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let app_state = AppState {
|
||||||
|
state,
|
||||||
|
client_request_tx,
|
||||||
|
clients,
|
||||||
|
port: 9681,
|
||||||
|
};
|
||||||
|
|
||||||
|
let addr = SocketAddr::from((Ipv4Addr::UNSPECIFIED, app_state.port));
|
||||||
|
info!("Listening on {}", addr);
|
||||||
|
// TODO: This could fail, need to figure out how to get a result from this
|
||||||
|
let _ = axum::Server::bind(&addr)
|
||||||
|
.serve(app(app_state).into_make_service())
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct AppState {
|
||||||
|
state: Arc<RwLock<HyperdeckMonitorState>>,
|
||||||
|
client_request_tx: tokio::sync::mpsc::UnboundedSender<ClientRequest>,
|
||||||
|
clients: Clients,
|
||||||
|
port: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn app(state: AppState) -> Router {
|
||||||
|
let sensitive_headers: Arc<[_]> = vec![header::AUTHORIZATION, header::COOKIE].into();
|
||||||
|
let middleware = ServiceBuilder::new()
|
||||||
|
// Mark the `Authorization` and `Cookie` headers as sensitive so it doesn't show in logs
|
||||||
|
.sensitive_request_headers(sensitive_headers.clone())
|
||||||
|
// Add high level tracing/logging to all requests
|
||||||
|
.layer(
|
||||||
|
TraceLayer::new_for_http()
|
||||||
|
.on_body_chunk(|chunk: &Bytes, latency: Duration, _: &tracing::Span| {
|
||||||
|
tracing::trace!(size_bytes = chunk.len(), latency = ?latency, "sending body chunk")
|
||||||
|
})
|
||||||
|
.make_span_with(DefaultMakeSpan::new().include_headers(true))
|
||||||
|
.on_response(DefaultOnResponse::new().include_headers(true).latency_unit(LatencyUnit::Micros)),
|
||||||
|
)
|
||||||
|
.sensitive_response_headers(sensitive_headers)
|
||||||
|
// Set a timeout
|
||||||
|
.layer(TimeoutLayer::new(Duration::from_secs(10)))
|
||||||
|
// Box the response body so it implements `Default` which is required by axum
|
||||||
|
.map_response_body(axum::body::boxed)
|
||||||
|
// Compress responses
|
||||||
|
.compression()
|
||||||
|
// Set a `Content-Type` if there isn't one already.
|
||||||
|
.insert_response_header_if_not_present(
|
||||||
|
header::CONTENT_TYPE,
|
||||||
|
HeaderValue::from_static("application/octet-stream"),
|
||||||
|
);
|
||||||
|
|
||||||
|
let cors = CorsLayer::new()
|
||||||
|
.allow_methods(vec![
|
||||||
|
Method::GET,
|
||||||
|
Method::POST,
|
||||||
|
Method::PUT,
|
||||||
|
Method::DELETE,
|
||||||
|
Method::OPTIONS,
|
||||||
|
])
|
||||||
|
.allow_headers(Any)
|
||||||
|
.allow_origin(Any)
|
||||||
|
.allow_credentials(false);
|
||||||
|
|
||||||
|
Router::new()
|
||||||
|
.route("/", get(get_index))
|
||||||
|
.route("/ws", get(upgrade_ws))
|
||||||
|
.layer(middleware)
|
||||||
|
.layer(cors)
|
||||||
|
.with_state(state)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct WebSocketUpgradeRequest {}
|
||||||
|
|
||||||
|
async fn get_index() -> Html<String> {
|
||||||
|
Html(format!("Hello!"))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[axum::debug_handler]
|
||||||
|
async fn upgrade_ws(state: State<AppState>, ws: WebSocketUpgrade) -> impl IntoResponse {
|
||||||
|
info!("New client websocket connection");
|
||||||
|
let client_id = uuid::Uuid::new_v4();
|
||||||
|
state
|
||||||
|
.clients
|
||||||
|
.lock()
|
||||||
|
.await
|
||||||
|
.insert(client_id.clone(), Client { sender: None });
|
||||||
|
let client = state.clients.lock().await.get(&client_id).cloned().unwrap();
|
||||||
|
ws.on_upgrade(move |socket| {
|
||||||
|
ws::client_connection(
|
||||||
|
state.client_request_tx.clone(),
|
||||||
|
socket,
|
||||||
|
client_id,
|
||||||
|
state.state.clone(),
|
||||||
|
state.clients.clone(),
|
||||||
|
client,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
|
#[serde(tag = "type")]
|
||||||
|
pub enum ClientRequest {
|
||||||
|
AddHyperdeck(AddHyperdeckRequest),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct AddHyperdeckRequest {
|
||||||
|
pub name: String,
|
||||||
|
pub ip: String,
|
||||||
|
pub port: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
|
#[serde(tag = "type")]
|
||||||
|
pub enum ServerEvent {
|
||||||
|
HyperdeckMonitorState(HyperdeckMonitorState),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||||
|
pub struct HyperdeckMonitorState {
|
||||||
|
pub hyperdecks: HashMap<String, HyperdeckState>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct HyperdeckState {
|
||||||
|
pub name: String,
|
||||||
|
pub ip: String,
|
||||||
|
pub port: u16,
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
use std::{future, sync::Arc};
|
||||||
|
|
||||||
|
use super::message::{ClientRequest, HyperdeckMonitorState};
|
||||||
|
use crate::api::ServerEvent;
|
||||||
|
use axum::extract::ws::{Message, WebSocket};
|
||||||
|
use futures::StreamExt;
|
||||||
|
use tokio::sync::RwLock;
|
||||||
|
use tokio_stream::wrappers::BroadcastStream;
|
||||||
|
use tracing::{debug, error, log::info};
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
use super::{Client, Clients};
|
||||||
|
|
||||||
|
pub async fn client_connection(
|
||||||
|
client_request_tx: tokio::sync::mpsc::UnboundedSender<ClientRequest>,
|
||||||
|
ws: WebSocket,
|
||||||
|
id: Uuid,
|
||||||
|
state: Arc<RwLock<HyperdeckMonitorState>>,
|
||||||
|
clients: Clients,
|
||||||
|
mut client: Client,
|
||||||
|
) {
|
||||||
|
let (client_ws_sender, mut client_ws_rcv) = ws.split();
|
||||||
|
let (client_sender, client_rcv) = tokio::sync::broadcast::channel::<Message>(10);
|
||||||
|
let client_rcv = BroadcastStream::new(client_rcv);
|
||||||
|
|
||||||
|
tokio::task::spawn(
|
||||||
|
client_rcv
|
||||||
|
.filter(|msg| future::ready(msg.is_ok()))
|
||||||
|
.map(|msg| Ok(msg.unwrap()))
|
||||||
|
.forward(client_ws_sender),
|
||||||
|
);
|
||||||
|
|
||||||
|
let current_state = state.read().await.clone();
|
||||||
|
let state_json =
|
||||||
|
serde_json::to_string(&ServerEvent::HyperdeckMonitorState(current_state.into())).unwrap();
|
||||||
|
client_sender.send(Message::Text(state_json.clone())).ok();
|
||||||
|
|
||||||
|
client.sender = Some(client_sender);
|
||||||
|
clients.lock().await.insert(id, client);
|
||||||
|
|
||||||
|
info!("{} connected", id);
|
||||||
|
|
||||||
|
while let Some(result) = client_ws_rcv.next().await {
|
||||||
|
let msg = match result {
|
||||||
|
Ok(msg) => msg,
|
||||||
|
Err(e) => {
|
||||||
|
error!("error resolving ws message for id: {}: {}", id.clone(), e);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
client_msg(client_request_tx.clone(), &id, msg).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
clients.lock().await.remove(&id);
|
||||||
|
info!("{} disconnected", id);
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn client_msg(
|
||||||
|
client_request_tx: tokio::sync::mpsc::UnboundedSender<ClientRequest>,
|
||||||
|
id: &Uuid,
|
||||||
|
msg: Message,
|
||||||
|
) {
|
||||||
|
debug!("received message from {}: {:?}", id, msg);
|
||||||
|
let message = match msg.into_text() {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(err) => {
|
||||||
|
error!("error: {:?}", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if message == "ping" || message == "ping\n" {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let client_request: super::message::ClientRequest = match serde_json::from_str(&message) {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(_) => {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let _ = client_request_tx.send(client_request);
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
use std::{net::IpAddr, time::Duration};
|
use std::{process::Stdio, time::Duration};
|
||||||
|
|
||||||
|
use api::message::{AddHyperdeckRequest, ClientRequest, HyperdeckMonitorState, HyperdeckState};
|
||||||
use color_eyre::Report;
|
use color_eyre::Report;
|
||||||
use futures_util::{
|
use futures_util::{
|
||||||
pin_mut, select,
|
pin_mut, select,
|
||||||
|
@ -9,9 +10,14 @@ use futures_util::{
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tokio::net::TcpStream;
|
use tokio::net::TcpStream;
|
||||||
use tokio_tungstenite::{tungstenite::Message, MaybeTlsStream, WebSocketStream};
|
use tokio_tungstenite::{tungstenite::Message, MaybeTlsStream, WebSocketStream};
|
||||||
use tokio_util::sync::CancellationToken;
|
use tokio_util::{
|
||||||
|
codec::{FramedRead, LinesCodec},
|
||||||
|
sync::CancellationToken,
|
||||||
|
};
|
||||||
use tracing_subscriber::EnvFilter;
|
use tracing_subscriber::EnvFilter;
|
||||||
|
|
||||||
|
mod api;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
setup_logging().expect("Failed to setup logging");
|
setup_logging().expect("Failed to setup logging");
|
||||||
|
@ -20,35 +26,169 @@ async fn main() {
|
||||||
let cancel = CancellationToken::new();
|
let cancel = CancellationToken::new();
|
||||||
let node_process = run_node_process(cancel.clone()).fuse();
|
let node_process = run_node_process(cancel.clone()).fuse();
|
||||||
|
|
||||||
let (ws_message_tx, ws_message_rx) = tokio::sync::mpsc::unbounded_channel();
|
let (node_ws_message_tx, node_ws_message_rx) = tokio::sync::mpsc::unbounded_channel();
|
||||||
let (commands_tx, commands_rx) = tokio::sync::mpsc::unbounded_channel();
|
let (node_commands_tx, node_commands_rx) = tokio::sync::mpsc::unbounded_channel();
|
||||||
let state = AppState::default();
|
let state = AppState::default();
|
||||||
let ws_process = talk_to_node_ws(state, ws_message_tx, commands_rx, cancel.clone()).fuse();
|
let node_ws_communication =
|
||||||
|
talk_to_node_ws(state, node_ws_message_tx, node_commands_rx, cancel.clone()).fuse();
|
||||||
|
|
||||||
|
let (state_tx, state_rx) = tokio::sync::broadcast::channel(1);
|
||||||
|
let (client_request_tx, client_request_rx) = tokio::sync::mpsc::unbounded_channel();
|
||||||
|
let api = api::initialize_api(state_rx, client_request_tx).fuse();
|
||||||
|
|
||||||
|
let hyperdeck_monitor = run(
|
||||||
|
node_commands_tx,
|
||||||
|
node_ws_message_rx,
|
||||||
|
state_tx,
|
||||||
|
client_request_rx,
|
||||||
|
cancel.clone(),
|
||||||
|
)
|
||||||
|
.fuse();
|
||||||
|
|
||||||
pin_mut!(node_process);
|
pin_mut!(node_process);
|
||||||
pin_mut!(ws_process);
|
pin_mut!(node_ws_communication);
|
||||||
|
pin_mut!(api);
|
||||||
|
pin_mut!(hyperdeck_monitor);
|
||||||
|
|
||||||
select! {
|
select! {
|
||||||
_ = node_process => {},
|
_ = node_process => {},
|
||||||
_ = ws_process => {},
|
_ = node_ws_communication => {},
|
||||||
|
_ = api => {},
|
||||||
|
_ = hyperdeck_monitor => {},
|
||||||
_ = cancel.cancelled().fuse() => {}
|
_ = cancel.cancelled().fuse() => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
cancel.cancel();
|
cancel.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn run(
|
||||||
|
mut node_commands_tx: tokio::sync::mpsc::UnboundedSender<NodeWsCommand>,
|
||||||
|
mut node_ws_message_rx: tokio::sync::mpsc::UnboundedReceiver<NodeWsMessageReceived>,
|
||||||
|
mut state_tx: tokio::sync::broadcast::Sender<HyperdeckMonitorState>,
|
||||||
|
mut client_request_rx: tokio::sync::mpsc::UnboundedReceiver<ClientRequest>,
|
||||||
|
cancel: CancellationToken,
|
||||||
|
) {
|
||||||
|
let mut state = HyperdeckMonitorState::default();
|
||||||
|
let _ = state_tx.send(state.clone());
|
||||||
|
|
||||||
|
let mut ping_interval = tokio::time::interval(Duration::from_millis(500));
|
||||||
|
ping_interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Delay);
|
||||||
|
|
||||||
|
while !cancel.is_cancelled() {
|
||||||
|
let state_modified = select! {
|
||||||
|
_ = ping_interval.tick().fuse() => {
|
||||||
|
// TODO: Ping node, check it's still alive
|
||||||
|
false
|
||||||
|
},
|
||||||
|
message_from_node = node_ws_message_rx.recv().fuse() => {
|
||||||
|
if let Some(msg) = message_from_node {
|
||||||
|
handle_message_from_node(msg, &mut node_commands_tx, &mut state).await
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
message_from_client = client_request_rx.recv().fuse() => {
|
||||||
|
if let Some(msg) = message_from_client {
|
||||||
|
handle_message_from_client(msg, &mut node_commands_tx, &mut state).await
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if state_modified {
|
||||||
|
let _ = state_tx.send(state.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn handle_message_from_node(
|
||||||
|
msg: NodeWsMessageReceived,
|
||||||
|
node_commands_tx: &mut tokio::sync::mpsc::UnboundedSender<NodeWsCommand>,
|
||||||
|
state: &mut HyperdeckMonitorState,
|
||||||
|
) -> bool {
|
||||||
|
match msg {
|
||||||
|
NodeWsMessageReceived::Log { message } => {
|
||||||
|
tracing::info!("[NODE] {message}");
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn handle_message_from_client(
|
||||||
|
msg: ClientRequest,
|
||||||
|
node_commands_tx: &mut tokio::sync::mpsc::UnboundedSender<NodeWsCommand>,
|
||||||
|
state: &mut HyperdeckMonitorState,
|
||||||
|
) -> bool {
|
||||||
|
match msg {
|
||||||
|
ClientRequest::AddHyperdeck(AddHyperdeckRequest { name, ip, port }) => {
|
||||||
|
tracing::info!("Adding hyperdeck");
|
||||||
|
let id = uuid::Uuid::new_v4();
|
||||||
|
state.hyperdecks.insert(
|
||||||
|
id.to_string(),
|
||||||
|
HyperdeckState {
|
||||||
|
name,
|
||||||
|
ip: ip.clone(),
|
||||||
|
port,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
let _ = node_commands_tx.send(NodeWsCommand::AddHyperdeck(AddHyperdeckCommand {
|
||||||
|
id: id.to_string(),
|
||||||
|
ip,
|
||||||
|
port,
|
||||||
|
}));
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn run_node_process(cancel: CancellationToken) {
|
async fn run_node_process(cancel: CancellationToken) {
|
||||||
while !cancel.is_cancelled() {
|
while !cancel.is_cancelled() {
|
||||||
let result = tokio::process::Command::new("node")
|
|
||||||
.arg("monitor/index.js")
|
|
||||||
.output()
|
|
||||||
.await;
|
|
||||||
if let Ok(output) = result {
|
|
||||||
if !output.status.success() {
|
|
||||||
let err = String::from_utf8(output.stderr).unwrap_or("Unknown".to_string());
|
|
||||||
tracing::error!("Node process exited with error: {}", err);
|
|
||||||
// Back-off in case we are immediately crashing in a loop.
|
// Back-off in case we are immediately crashing in a loop.
|
||||||
tokio::time::sleep(Duration::from_secs(1)).await;
|
tokio::time::sleep(Duration::from_secs(1)).await;
|
||||||
|
|
||||||
|
let result = tokio::process::Command::new("node")
|
||||||
|
.arg("monitor/index.js")
|
||||||
|
.stdin(Stdio::piped())
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.stderr(Stdio::piped())
|
||||||
|
.spawn();
|
||||||
|
match result {
|
||||||
|
Ok(mut child_process) => {
|
||||||
|
let Some(raw_stdout) = child_process.stdout.take() else {
|
||||||
|
let _ = child_process.kill().await;
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some(raw_stderr) = child_process.stderr.take() else {
|
||||||
|
let _ = child_process.kill().await;
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut stdout = FramedRead::new(raw_stdout, LinesCodec::new())
|
||||||
|
.map(|data| data.expect("Could not read stdout"));
|
||||||
|
let mut stderr = FramedRead::new(raw_stderr, LinesCodec::new())
|
||||||
|
.map(|data| data.expect("Could not read stderr"));
|
||||||
|
|
||||||
|
while !cancel.is_cancelled() {
|
||||||
|
select! {
|
||||||
|
line = stdout.next().fuse() => {
|
||||||
|
if let Some(line) = line {
|
||||||
|
tracing::info!("[NODE] {line}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
line = stderr.next().fuse() => {
|
||||||
|
if let Some(line) = line {
|
||||||
|
tracing::error!("[NODE] {line}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = child_process.kill().await;
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
tracing::error!("Error running Node child process: {err}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,9 +196,15 @@ async fn run_node_process(cancel: CancellationToken) {
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct AppState {}
|
struct AppState {}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(tag = "type")]
|
||||||
enum NodeWsCommand {
|
enum NodeWsCommand {
|
||||||
|
#[serde(rename = "ping")]
|
||||||
Ping,
|
Ping,
|
||||||
|
#[serde(rename = "add_hyperdeck")]
|
||||||
AddHyperdeck(AddHyperdeckCommand),
|
AddHyperdeck(AddHyperdeckCommand),
|
||||||
|
#[serde(rename = "remove_hyperdeck")]
|
||||||
RemoveHyperdeck(RemoveHyperdeckCommand),
|
RemoveHyperdeck(RemoveHyperdeckCommand),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,16 +215,18 @@ enum NodeWsMessageReceived {
|
||||||
Log { message: String },
|
Log { message: String },
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
struct AddHyperdeckCommand {
|
struct AddHyperdeckCommand {
|
||||||
ip: IpAddr,
|
id: String,
|
||||||
|
ip: String,
|
||||||
|
port: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
struct RemoveHyperdeckCommand {
|
struct RemoveHyperdeckCommand {
|
||||||
ip: IpAddr,
|
id: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn talk_to_node_ws(
|
async fn talk_to_node_ws(
|
||||||
|
@ -126,28 +274,13 @@ async fn handle_outbound_messages(
|
||||||
mut socket_tx: SplitSink<WebSocketStream<MaybeTlsStream<TcpStream>>, Message>,
|
mut socket_tx: SplitSink<WebSocketStream<MaybeTlsStream<TcpStream>>, Message>,
|
||||||
) {
|
) {
|
||||||
while let Some(command) = commands_rx.recv().await {
|
while let Some(command) = commands_rx.recv().await {
|
||||||
match command {
|
if let Err(err) = socket_tx
|
||||||
NodeWsCommand::Ping => {
|
|
||||||
let _ = socket_tx
|
|
||||||
.send(tokio_tungstenite::tungstenite::Message::Ping(vec![]))
|
|
||||||
.await;
|
|
||||||
}
|
|
||||||
NodeWsCommand::AddHyperdeck(command) => {
|
|
||||||
let _ = socket_tx
|
|
||||||
.send(tokio_tungstenite::tungstenite::Message::Text(
|
.send(tokio_tungstenite::tungstenite::Message::Text(
|
||||||
serde_json::to_string(&command)
|
serde_json::to_string(&command).expect("Could not serialize command"),
|
||||||
.expect("Could not serialize AddHyperdeck command"),
|
|
||||||
))
|
))
|
||||||
.await;
|
.await
|
||||||
}
|
{
|
||||||
NodeWsCommand::RemoveHyperdeck(command) => {
|
tracing::error!("Error sending command to Node proccess: {err}");
|
||||||
let _ = socket_tx
|
|
||||||
.send(tokio_tungstenite::tungstenite::Message::Text(
|
|
||||||
serde_json::to_string(&command)
|
|
||||||
.expect("Could not serialize RemoveHyperdeck command"),
|
|
||||||
))
|
|
||||||
.await;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,11 +294,7 @@ async fn handle_inbound_messages(
|
||||||
match message {
|
match message {
|
||||||
Ok(tokio_tungstenite::tungstenite::Message::Text(text)) => {
|
Ok(tokio_tungstenite::tungstenite::Message::Text(text)) => {
|
||||||
if let Ok(received) = serde_json::from_str::<NodeWsMessageReceived>(&text) {
|
if let Ok(received) = serde_json::from_str::<NodeWsMessageReceived>(&text) {
|
||||||
match received {
|
let _ = ws_message_tx.send(received);
|
||||||
NodeWsMessageReceived::Log { message } => {
|
|
||||||
tracing::info!("Message from Node process: {message}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(tokio_tungstenite::tungstenite::Message::Pong(_)) => {}
|
Ok(tokio_tungstenite::tungstenite::Message::Pong(_)) => {}
|
||||||
|
|
Loading…
Reference in New Issue