mirror of
https://github.com/Astatin3/unshell.git
synced 2026-06-08 22:38:01 -06:00
Add packet.
This commit is contained in:
Generated
+3
-670
@@ -22,12 +22,6 @@ dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "allocator-api2"
|
||||
version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
||||
|
||||
[[package]]
|
||||
name = "android_system_properties"
|
||||
version = "0.1.5"
|
||||
@@ -124,15 +118,6 @@ version = "1.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
|
||||
|
||||
[[package]]
|
||||
name = "castaway"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a"
|
||||
dependencies = [
|
||||
"rustversion",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cbc"
|
||||
version = "0.2.0"
|
||||
@@ -204,35 +189,12 @@ dependencies = [
|
||||
"inout",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "compact_str"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb1325a1cece981e8a296ab8f0f9b63ae357bd0784a9faaf548cc7b480707a"
|
||||
dependencies = [
|
||||
"castaway",
|
||||
"cfg-if",
|
||||
"itoa",
|
||||
"rustversion",
|
||||
"ryu",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "const-oid"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c"
|
||||
|
||||
[[package]]
|
||||
name = "convert_case"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.7"
|
||||
@@ -254,48 +216,6 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
||||
|
||||
[[package]]
|
||||
name = "crossterm"
|
||||
version = "0.29.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b"
|
||||
dependencies = [
|
||||
"bitflags 2.11.1",
|
||||
"crossterm_winapi",
|
||||
"derive_more",
|
||||
"document-features",
|
||||
"mio",
|
||||
"parking_lot",
|
||||
"rustix",
|
||||
"signal-hook",
|
||||
"signal-hook-mio",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossterm_winapi"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.2.1"
|
||||
@@ -305,71 +225,6 @@ dependencies = [
|
||||
"hybrid-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.23.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"darling_macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_core"
|
||||
version = "0.23.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0"
|
||||
dependencies = [
|
||||
"ident_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_macro"
|
||||
version = "0.23.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"quote",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deranged"
|
||||
version = "0.5.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c"
|
||||
dependencies = [
|
||||
"powerfmt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_more"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134"
|
||||
dependencies = [
|
||||
"derive_more-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_more-impl"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb"
|
||||
dependencies = [
|
||||
"convert_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustc_version",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.11.2"
|
||||
@@ -381,54 +236,12 @@ dependencies = [
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "document-features"
|
||||
version = "0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61"
|
||||
dependencies = [
|
||||
"litrs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "downcast-rs"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2"
|
||||
|
||||
[[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"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "filedescriptor"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e40758ed24c9b2eeb76c35fb0aebc66c626084edd827e07e1552279814c6682d"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"thiserror 1.0.69",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "find-msvc-tools"
|
||||
version = "0.1.8"
|
||||
@@ -441,12 +254,6 @@ version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||
|
||||
[[package]]
|
||||
name = "foldhash"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.4.2"
|
||||
@@ -467,7 +274,7 @@ version = "0.15.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
|
||||
dependencies = [
|
||||
"foldhash 0.1.5",
|
||||
"foldhash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -475,11 +282,6 @@ name = "hashbrown"
|
||||
version = "0.16.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
|
||||
dependencies = [
|
||||
"allocator-api2",
|
||||
"equivalent",
|
||||
"foldhash 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
@@ -544,12 +346,6 @@ version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
|
||||
|
||||
[[package]]
|
||||
name = "ident_case"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.13.0"
|
||||
@@ -562,15 +358,6 @@ dependencies = [
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indoc"
|
||||
version = "2.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706"
|
||||
dependencies = [
|
||||
"rustversion",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inout"
|
||||
version = "0.2.2"
|
||||
@@ -581,28 +368,6 @@ dependencies = [
|
||||
"hybrid-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instability"
|
||||
version = "0.3.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5eb2d60ef19920a3a9193c3e371f726ec1dafc045dac788d0fb3704272458971"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"indoc",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.18"
|
||||
@@ -619,23 +384,6 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kasuari"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bde5057d6143cc94e861d90f591b9303d6716c6b9602309150bd068853c10899"
|
||||
dependencies = [
|
||||
"hashbrown 0.16.1",
|
||||
"portable-atomic",
|
||||
"thiserror 2.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
|
||||
[[package]]
|
||||
name = "leb128fmt"
|
||||
version = "0.1.0"
|
||||
@@ -648,27 +396,6 @@ version = "0.2.185"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f"
|
||||
|
||||
[[package]]
|
||||
name = "line-clipping"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f50e8f47623268b5407192d26876c4d7f89d686ca130fdc53bced4814cd29f8"
|
||||
dependencies = [
|
||||
"bitflags 2.11.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
|
||||
|
||||
[[package]]
|
||||
name = "litrs"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.14"
|
||||
@@ -684,33 +411,12 @@ version = "0.4.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
|
||||
|
||||
[[package]]
|
||||
name = "lru"
|
||||
version = "0.16.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f66e8d5d03f609abc3a39e6f08e4164ebf1447a732906d39eb9b99b7919ef39"
|
||||
dependencies = [
|
||||
"hashbrown 0.16.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"wasi",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "munge"
|
||||
version = "0.4.7"
|
||||
@@ -731,24 +437,6 @@ dependencies = [
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.28.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4"
|
||||
dependencies = [
|
||||
"bitflags 2.11.1",
|
||||
"cfg-if",
|
||||
"cfg_aliases 0.1.1",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-conv"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967"
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
@@ -758,15 +446,6 @@ dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_threads"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.3"
|
||||
@@ -796,39 +475,6 @@ dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "portable-atomic"
|
||||
version = "1.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
|
||||
|
||||
[[package]]
|
||||
name = "portable-pty"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4a596a2b3d2752d94f51fac2d4a96737b8705dddd311a32b9af47211f08671e"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags 1.3.2",
|
||||
"downcast-rs",
|
||||
"filedescriptor",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"log",
|
||||
"nix",
|
||||
"serial2",
|
||||
"shared_library",
|
||||
"shell-words",
|
||||
"winapi",
|
||||
"winreg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "powerfmt"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||
|
||||
[[package]]
|
||||
name = "prettyplease"
|
||||
version = "0.2.37"
|
||||
@@ -909,69 +555,6 @@ version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69"
|
||||
|
||||
[[package]]
|
||||
name = "ratatui"
|
||||
version = "0.30.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d1ce67fb8ba4446454d1c8dbaeda0557ff5e94d39d5e5ed7f10a65eb4c8266bc"
|
||||
dependencies = [
|
||||
"instability",
|
||||
"ratatui-core",
|
||||
"ratatui-crossterm",
|
||||
"ratatui-widgets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ratatui-core"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ef8dea09a92caaf73bff7adb70b76162e5937524058a7e5bff37869cbbec293"
|
||||
dependencies = [
|
||||
"bitflags 2.11.1",
|
||||
"compact_str",
|
||||
"hashbrown 0.16.1",
|
||||
"indoc",
|
||||
"itertools",
|
||||
"kasuari",
|
||||
"lru",
|
||||
"strum",
|
||||
"thiserror 2.0.18",
|
||||
"unicode-segmentation",
|
||||
"unicode-truncate",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ratatui-crossterm"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "577c9b9f652b4c121fb25c6a391dd06406d3b092ba68827e6d2f09550edc54b3"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossterm",
|
||||
"instability",
|
||||
"ratatui-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ratatui-widgets"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7dbfa023cd4e604c2553483820c5fe8aa9d71a42eea5aa77c6e7f35756612db"
|
||||
dependencies = [
|
||||
"bitflags 2.11.1",
|
||||
"hashbrown 0.16.1",
|
||||
"indoc",
|
||||
"instability",
|
||||
"itertools",
|
||||
"line-clipping",
|
||||
"ratatui-core",
|
||||
"strum",
|
||||
"time",
|
||||
"unicode-segmentation",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.18"
|
||||
@@ -1049,40 +632,12 @@ dependencies = [
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "1.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190"
|
||||
dependencies = [
|
||||
"bitflags 2.11.1",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
@@ -1137,17 +692,6 @@ dependencies = [
|
||||
"zmij",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serial2"
|
||||
version = "0.2.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcdbc46aa3882ec3d48ec2b5abcb4f0d863a13d7599265f3faa6d851f23c12f3"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.11.0"
|
||||
@@ -1159,59 +703,12 @@ dependencies = [
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shared_library"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a9e7e0f2bfae24d8a5b5a66c5b257a83c7412304311512a0c054cd5e619da11"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shell-words"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc6fe69c597f9c37bfeeeeeb33da3530379845f10be461a66d16d03eca2ded77"
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"signal-hook-registry",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-mio"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b75a19a7a740b25bc7944bdee6172368f988763b744e3d4dfe753f6b4ece40cc"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"mio",
|
||||
"signal-hook",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b"
|
||||
dependencies = [
|
||||
"errno",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simdutf8"
|
||||
version = "0.1.5"
|
||||
@@ -1224,12 +721,6 @@ version = "1.15.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "static_init"
|
||||
version = "1.0.4"
|
||||
@@ -1258,33 +749,6 @@ dependencies = [
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.27.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf"
|
||||
dependencies = [
|
||||
"strum_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strum_macros"
|
||||
version = "0.27.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
@@ -1307,33 +771,13 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
||||
dependencies = [
|
||||
"thiserror-impl 1.0.69",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "2.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
|
||||
dependencies = [
|
||||
"thiserror-impl 2.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.117",
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1347,27 +791,6 @@ dependencies = [
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.47"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c"
|
||||
dependencies = [
|
||||
"deranged",
|
||||
"libc",
|
||||
"num-conv",
|
||||
"num_threads",
|
||||
"powerfmt",
|
||||
"serde_core",
|
||||
"time-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time-core"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca"
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.11.0"
|
||||
@@ -1383,17 +806,6 @@ version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "treetest"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"crossterm",
|
||||
"ratatui",
|
||||
"thiserror 2.0.18",
|
||||
"unshell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.20.0"
|
||||
@@ -1406,29 +818,6 @@ version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-truncate"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "16b380a1238663e5f8a691f9039c73e1cdae598a30e9855f541d29b08b53e9a5"
|
||||
dependencies = [
|
||||
"itertools",
|
||||
"unicode-segmentation",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.6"
|
||||
@@ -1440,34 +829,10 @@ name = "unshell"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"crossbeam-channel",
|
||||
"rkyv",
|
||||
"static_init",
|
||||
"thiserror 2.0.18",
|
||||
"unshell-leaves",
|
||||
"unshell-macros",
|
||||
"thiserror",
|
||||
"unshell-protocol",
|
||||
"unshell-runtime",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unshell-leaves"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"portable-pty",
|
||||
"rkyv",
|
||||
"unshell-macros",
|
||||
"unshell-protocol",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unshell-macros"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1475,14 +840,6 @@ name = "unshell-protocol"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"rkyv",
|
||||
"unshell-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unshell-runtime"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"unshell-protocol",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1511,12 +868,6 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.1+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
|
||||
|
||||
[[package]]
|
||||
name = "wasip2"
|
||||
version = "1.0.3+wasi-0.2.9"
|
||||
@@ -1695,24 +1046,6 @@ dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.61.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen"
|
||||
version = "0.51.0"
|
||||
|
||||
+13
-67
@@ -4,11 +4,11 @@ cargo-features = ["trim-paths", "panic-immediate-abort"]
|
||||
members = [
|
||||
"ush-obfuscate",
|
||||
"base62",
|
||||
"unshell-macros",
|
||||
# "unshell-macros",
|
||||
"unshell-protocol",
|
||||
"unshell-runtime",
|
||||
"unshell-leaves",
|
||||
"treetest",
|
||||
# "unshell-runtime",
|
||||
# "unshell-leaves",
|
||||
# "treetest",
|
||||
]
|
||||
resolver = "2"
|
||||
|
||||
@@ -32,9 +32,9 @@ portable-pty = "0.9.0"
|
||||
crossbeam-channel = "0.5.15"
|
||||
unshell = { path = "." }
|
||||
unshell-protocol = { path = "./unshell-protocol" }
|
||||
unshell-runtime = { path = "./unshell-runtime" }
|
||||
unshell-leaves = { path = "./unshell-leaves" }
|
||||
unshell-macros = { path = "./unshell-macros" }
|
||||
# unshell-runtime = { path = "./unshell-runtime" }
|
||||
# unshell-leaves = { path = "./unshell-leaves" }
|
||||
# unshell-macros = { path = "./unshell-macros" }
|
||||
|
||||
# ush-obfuscate = { path = "./ush-obfuscate" }
|
||||
# base62 = { path = "./base62" }
|
||||
@@ -51,8 +51,8 @@ log = []
|
||||
log_debug = ["log", "dep:chrono"]
|
||||
|
||||
# Leaf features
|
||||
leaf_endpoint = ["unshell-leaves/leaf_endpoint"]
|
||||
leaf_tui = ["unshell-leaves/leaf_tui"]
|
||||
# leaf_endpoint = ["unshell-leaves/leaf_endpoint"]
|
||||
# leaf_tui = ["unshell-leaves/leaf_tui"]
|
||||
|
||||
# obfuscate_aes = ["ush-obfuscate/obfuscate_aes"]
|
||||
# obfuscate_ref = ["ush-obfuscate/obfuscate_ref"]
|
||||
@@ -63,64 +63,10 @@ thiserror = { workspace = true, optional = true }
|
||||
chrono = { workspace = true, optional = true }
|
||||
# ush-obfuscate = { workspace = true }
|
||||
static_init = { workspace = true }
|
||||
unshell-macros = { workspace = true }
|
||||
# unshell-macros = { workspace = true }
|
||||
unshell-protocol = { workspace = true }
|
||||
unshell-runtime = { workspace = true }
|
||||
unshell-leaves = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
crossbeam-channel = { workspace = true }
|
||||
|
||||
[[example]]
|
||||
name = "leaf_derive"
|
||||
path = "examples/protocol/leaf_derive.rs"
|
||||
|
||||
[[example]]
|
||||
name = "crossbeam_channel_leaf"
|
||||
path = "examples/protocol/crossbeam_channel_leaf.rs"
|
||||
|
||||
[[example]]
|
||||
name = "runtime_leaf_actions"
|
||||
path = "examples/protocol/runtime_leaf_actions.rs"
|
||||
|
||||
[[example]]
|
||||
name = "remote_shell_endpoint"
|
||||
path = "examples/protocol/remote_shell_endpoint.rs"
|
||||
required-features = ["leaf_endpoint"]
|
||||
|
||||
[[example]]
|
||||
name = "remote_shell_receive"
|
||||
path = "examples/protocol/remote_shell_receive.rs"
|
||||
required-features = ["leaf_endpoint"]
|
||||
|
||||
[[example]]
|
||||
name = "remote_shell_single_endpoint"
|
||||
path = "examples/protocol/remote_shell_single_endpoint.rs"
|
||||
required-features = ["leaf_endpoint"]
|
||||
|
||||
[[example]]
|
||||
name = "bench"
|
||||
path = "examples/protocol/bench/bench.rs"
|
||||
|
||||
[[example]]
|
||||
name = "op_encode_call"
|
||||
path = "examples/protocol/bench/op_encode_call.rs"
|
||||
|
||||
[[example]]
|
||||
name = "op_decode_call"
|
||||
path = "examples/protocol/bench/op_decode_call.rs"
|
||||
|
||||
[[example]]
|
||||
name = "op_forward_call_receive"
|
||||
path = "examples/protocol/bench/op_forward_call_receive.rs"
|
||||
|
||||
[[example]]
|
||||
name = "op_local_call_receive"
|
||||
path = "examples/protocol/bench/op_local_call_receive.rs"
|
||||
|
||||
[[example]]
|
||||
name = "op_hook_data_receive"
|
||||
path = "examples/protocol/bench/op_hook_data_receive.rs"
|
||||
# unshell-runtime = { workspace = true }
|
||||
# unshell-leaves = { workspace = true }
|
||||
|
||||
[profile.minimize]
|
||||
inherits = "release"
|
||||
@@ -143,4 +89,4 @@ unsafe_op_in_unsafe_fn = "warn"
|
||||
unused_import_braces = "warn"
|
||||
unused_lifetimes = "warn"
|
||||
trivial_casts = "allow"
|
||||
missing_docs = "warn"
|
||||
# missing_docs = "warn"
|
||||
|
||||
+18
-18
@@ -24,12 +24,12 @@ pub mod logger;
|
||||
pub use unshell_protocol as protocol;
|
||||
|
||||
/// Re-export the leaf library crate behind the historical `unshell::leaves` path
|
||||
pub use unshell_leaves as leaves;
|
||||
// pub use unshell_leaves as leaves;
|
||||
|
||||
/// Re-export the runtime crate behind the `unshell::runtime` path.
|
||||
pub use unshell_runtime as runtime;
|
||||
// pub use unshell_runtime as runtime;
|
||||
|
||||
pub use unshell_macros::{Procedure, leaf, procedures};
|
||||
// pub use unshell_macros::{Procedure, leaf, procedures};
|
||||
|
||||
/// Creates a root-assumed endpoint from one local identifier plus any number of leaf hosts.
|
||||
///
|
||||
@@ -40,21 +40,21 @@ pub use unshell_macros::{Procedure, leaf, procedures};
|
||||
/// Why it exists: the common bootstrap case should not require callers to manually construct an
|
||||
/// empty path, `Vec<ChildRoute>`, and a `Vec<LeafSpec>` when they already have leaf host values.
|
||||
///
|
||||
/// # Example
|
||||
/// ```rust
|
||||
/// use unshell::{create_endpoint, leaf};
|
||||
/// use unshell::protocol::tree::Endpoint;
|
||||
///
|
||||
/// #[derive(Default)]
|
||||
/// struct DemoLeaf;
|
||||
///
|
||||
/// #[leaf(id = "org.example.v1.demo", procedures = ["ping"], endpoint_struct = DemoLeaf)]
|
||||
/// struct Demo;
|
||||
///
|
||||
/// let endpoint = create_endpoint!("demo", DemoLeaf::default());
|
||||
/// assert!(endpoint.path().is_empty());
|
||||
/// assert_eq!(endpoint.local_id(), Some("demo"));
|
||||
/// ```
|
||||
// # Example
|
||||
// ```rust
|
||||
// use unshell::{create_endpoint, leaf};
|
||||
// use unshell::protocol::tree::Endpoint;
|
||||
|
||||
// #[derive(Default)]
|
||||
// struct DemoLeaf;
|
||||
|
||||
// #[leaf(id = "org.example.v1.demo", procedures = ["ping"], endpoint_struct = DemoLeaf)]
|
||||
// struct Demo;
|
||||
|
||||
// let endpoint = create_endpoint!("demo", DemoLeaf::default());
|
||||
// assert!(endpoint.path().is_empty());
|
||||
// assert_eq!(endpoint.local_id(), Some("demo"));
|
||||
// ```
|
||||
#[macro_export]
|
||||
macro_rules! create_endpoint {
|
||||
($id:expr $(, $leaf:expr )* $(,)?) => {{
|
||||
|
||||
@@ -9,7 +9,7 @@ doctest = false
|
||||
|
||||
[dependencies]
|
||||
rkyv = { workspace = true }
|
||||
unshell-macros = { path = "../unshell-macros" }
|
||||
# unshell-macros = { path = "../unshell-macros" }
|
||||
|
||||
[lints.rust]
|
||||
elided_lifetimes_in_paths = "warn"
|
||||
@@ -22,4 +22,4 @@ unsafe_op_in_unsafe_fn = "warn"
|
||||
unused_import_braces = "warn"
|
||||
unused_lifetimes = "warn"
|
||||
trivial_casts = "allow"
|
||||
missing_docs = "warn"
|
||||
# missing_docs = "warn"
|
||||
|
||||
@@ -1,20 +1,6 @@
|
||||
//! # UnShell Protocol
|
||||
//!
|
||||
//! The protocol crate owns the wire types, framing, validation helpers, and the
|
||||
//! small tree runtime used by endpoint implementations.
|
||||
|
||||
#![no_std]
|
||||
|
||||
pub extern crate alloc;
|
||||
#[allow(unused_extern_crates)]
|
||||
extern crate self as unshell;
|
||||
|
||||
/// Keep the historical nested path so existing imports and proc-macro output can
|
||||
/// continue to target `unshell::protocol::...` while the implementation lives in
|
||||
/// its own crate.
|
||||
pub mod protocol;
|
||||
|
||||
pub use protocol::*;
|
||||
|
||||
#[cfg(test)]
|
||||
pub use unshell_macros::{Procedure, leaf, procedures};
|
||||
pub mod packet;
|
||||
pub mod utils;
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
use alloc::string::String;
|
||||
use alloc::vec::Vec;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Packet {
|
||||
pub hook_id: u16,
|
||||
pub is_upwards_call: bool,
|
||||
pub end_hook: bool,
|
||||
pub path: String,
|
||||
// ── body (routers never read below this line) ──
|
||||
pub procedure_id: String,
|
||||
pub data: Vec<u8>,
|
||||
}
|
||||
|
||||
/// Returned by `deserialize_header` — only what a router needs.
|
||||
/// `body_remainder` is a raw slice into the original buffer so the
|
||||
/// entire body can be forwarded without touching it.
|
||||
#[derive(Debug)]
|
||||
pub struct HeaderRef<'buf> {
|
||||
pub hook_id: u16,
|
||||
pub is_upwards_call: bool,
|
||||
pub end_hook: bool,
|
||||
pub path: &'buf str,
|
||||
pub body_remainder: &'buf [u8],
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum SerializeError {
|
||||
PathTooLarge,
|
||||
ProcIdTooLarge,
|
||||
BodyTooLarge,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum DeserializeError {
|
||||
BufferTooShort,
|
||||
BodyLengthMismatch,
|
||||
PathTooLong,
|
||||
ProcIdTooLong,
|
||||
InvalidUtf8,
|
||||
}
|
||||
|
||||
impl Packet {
|
||||
pub fn serialize(&self) -> Result<Vec<u8>, SerializeError> {
|
||||
let path_bytes = self.path.as_bytes();
|
||||
let proc_id_bytes = self.procedure_id.as_bytes();
|
||||
|
||||
let path_len = u32::try_from(path_bytes.len()).map_err(|_| SerializeError::PathTooLarge)?;
|
||||
let proc_id_len =
|
||||
u32::try_from(proc_id_bytes.len()).map_err(|_| SerializeError::ProcIdTooLarge)?;
|
||||
|
||||
// body = proc_id_len field + proc_id bytes + data bytes
|
||||
let body_payload_len = 4usize
|
||||
.checked_add(proc_id_bytes.len())
|
||||
.and_then(|n| n.checked_add(self.data.len()))
|
||||
.ok_or(SerializeError::BodyTooLarge)?;
|
||||
let body_len = u32::try_from(body_payload_len).map_err(|_| SerializeError::BodyTooLarge)?;
|
||||
|
||||
let total = 8 + path_bytes.len() + 4 + body_payload_len;
|
||||
let mut buf = Vec::with_capacity(total);
|
||||
|
||||
// ── header ────────────────────────────────────────────────────────────
|
||||
let flags = (self.is_upwards_call as u8) | ((self.end_hook as u8) << 1);
|
||||
buf.extend_from_slice(&self.hook_id.to_le_bytes());
|
||||
buf.push(flags);
|
||||
buf.push(0u8); // padding
|
||||
buf.extend_from_slice(&path_len.to_le_bytes());
|
||||
buf.extend_from_slice(path_bytes);
|
||||
|
||||
// ── body ──────────────────────────────────────────────────────────────
|
||||
buf.extend_from_slice(&body_len.to_le_bytes());
|
||||
buf.extend_from_slice(&proc_id_len.to_le_bytes());
|
||||
buf.extend_from_slice(proc_id_bytes);
|
||||
buf.extend_from_slice(&self.data);
|
||||
|
||||
Ok(buf)
|
||||
}
|
||||
|
||||
/// Deserialize only the header — O(path_len), body bytes are never read.
|
||||
/// A router can inspect `HeaderRef` then forward the original buffer as-is.
|
||||
pub fn deserialize_header(buf: &[u8]) -> Result<HeaderRef<'_>, DeserializeError> {
|
||||
// fixed prefix: hook_id (2) + flags (1) + padding (1) + path_len (4)
|
||||
if buf.len() < 8 {
|
||||
return Err(DeserializeError::BufferTooShort);
|
||||
}
|
||||
|
||||
let hook_id = u16::from_le_bytes([buf[0], buf[1]]);
|
||||
let flags = buf[2];
|
||||
let is_upwards_call = flags & 0b0000_0001 != 0;
|
||||
let end_hook = flags & 0b0000_0010 != 0;
|
||||
let path_len = u32::from_le_bytes([buf[4], buf[5], buf[6], buf[7]]) as usize;
|
||||
|
||||
let path_start = 8usize;
|
||||
let path_end = path_start
|
||||
.checked_add(path_len)
|
||||
.ok_or(DeserializeError::PathTooLong)?;
|
||||
|
||||
if buf.len() < path_end {
|
||||
return Err(DeserializeError::BufferTooShort);
|
||||
}
|
||||
|
||||
let path = core::str::from_utf8(&buf[path_start..path_end])
|
||||
.map_err(|_| DeserializeError::InvalidUtf8)?;
|
||||
|
||||
Ok(HeaderRef {
|
||||
hook_id,
|
||||
is_upwards_call,
|
||||
end_hook,
|
||||
path,
|
||||
body_remainder: &buf[path_end..],
|
||||
})
|
||||
}
|
||||
|
||||
/// Full deserialization. Parses the header then the body.
|
||||
pub fn deserialize(buf: &[u8]) -> Result<Self, DeserializeError> {
|
||||
let header = Self::deserialize_header(buf)?;
|
||||
let body_buf = header.body_remainder;
|
||||
|
||||
// body_len prefix
|
||||
if body_buf.len() < 4 {
|
||||
return Err(DeserializeError::BufferTooShort);
|
||||
}
|
||||
let body_len =
|
||||
u32::from_le_bytes([body_buf[0], body_buf[1], body_buf[2], body_buf[3]]) as usize;
|
||||
|
||||
let body_end = 4usize
|
||||
.checked_add(body_len)
|
||||
.ok_or(DeserializeError::BodyLengthMismatch)?;
|
||||
if body_buf.len() < body_end {
|
||||
return Err(DeserializeError::BodyLengthMismatch);
|
||||
}
|
||||
|
||||
// proc_id_len + proc_id
|
||||
let inner = &body_buf[4..body_end];
|
||||
if inner.len() < 4 {
|
||||
return Err(DeserializeError::BufferTooShort);
|
||||
}
|
||||
let proc_id_len = u32::from_le_bytes([inner[0], inner[1], inner[2], inner[3]]) as usize;
|
||||
|
||||
let proc_id_start = 4usize;
|
||||
let proc_id_end = proc_id_start
|
||||
.checked_add(proc_id_len)
|
||||
.ok_or(DeserializeError::ProcIdTooLong)?;
|
||||
if inner.len() < proc_id_end {
|
||||
return Err(DeserializeError::BufferTooShort);
|
||||
}
|
||||
|
||||
let procedure_id = core::str::from_utf8(&inner[proc_id_start..proc_id_end])
|
||||
.map_err(|_| DeserializeError::InvalidUtf8)?;
|
||||
|
||||
let data = inner[proc_id_end..].to_vec();
|
||||
|
||||
Ok(Self {
|
||||
hook_id: header.hook_id,
|
||||
is_upwards_call: header.is_upwards_call,
|
||||
end_hook: header.end_hook,
|
||||
path: header.path.into(),
|
||||
procedure_id: procedure_id.into(),
|
||||
data,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,264 @@
|
||||
use super::*;
|
||||
use alloc::string::ToString;
|
||||
use alloc::vec;
|
||||
|
||||
// ── Helpers ───────────────────────────────────────────────────────────────
|
||||
|
||||
fn make_packet() -> Packet {
|
||||
Packet {
|
||||
hook_id: 42,
|
||||
is_upwards_call: true,
|
||||
end_hook: false,
|
||||
path: "my/service/path".to_string(),
|
||||
procedure_id: "my.service.Method".to_string(),
|
||||
data: vec![0xDE, 0xAD, 0xBE, 0xEF],
|
||||
}
|
||||
}
|
||||
|
||||
fn make_packet_flags(is_upwards_call: bool, end_hook: bool) -> Packet {
|
||||
Packet {
|
||||
is_upwards_call,
|
||||
end_hook,
|
||||
..make_packet()
|
||||
}
|
||||
}
|
||||
|
||||
// ── Round-trip ────────────────────────────────────────────────────────────
|
||||
|
||||
#[test]
|
||||
fn full_round_trip() {
|
||||
let packet = make_packet();
|
||||
let buf = packet.serialize().unwrap();
|
||||
let result = Packet::deserialize(&buf).unwrap();
|
||||
|
||||
assert_eq!(result.hook_id, packet.hook_id);
|
||||
assert_eq!(result.is_upwards_call, packet.is_upwards_call);
|
||||
assert_eq!(result.end_hook, packet.end_hook);
|
||||
assert_eq!(result.path, packet.path);
|
||||
assert_eq!(result.procedure_id, packet.procedure_id);
|
||||
assert_eq!(result.data, packet.data);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn header_round_trip() {
|
||||
let packet = make_packet();
|
||||
let buf = packet.serialize().unwrap();
|
||||
let header = Packet::deserialize_header(&buf).unwrap();
|
||||
|
||||
assert_eq!(header.hook_id, packet.hook_id);
|
||||
assert_eq!(header.is_upwards_call, packet.is_upwards_call);
|
||||
assert_eq!(header.end_hook, packet.end_hook);
|
||||
assert_eq!(header.path, packet.path);
|
||||
}
|
||||
|
||||
// ── Flags ─────────────────────────────────────────────────────────────────
|
||||
|
||||
#[test]
|
||||
fn flags_both_false() {
|
||||
let packet = make_packet_flags(false, false);
|
||||
let buf = packet.serialize().unwrap();
|
||||
let header = Packet::deserialize_header(&buf).unwrap();
|
||||
assert!(!header.is_upwards_call);
|
||||
assert!(!header.end_hook);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flags_both_true() {
|
||||
let packet = make_packet_flags(true, true);
|
||||
let buf = packet.serialize().unwrap();
|
||||
let header = Packet::deserialize_header(&buf).unwrap();
|
||||
assert!(header.is_upwards_call);
|
||||
assert!(header.end_hook);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flags_upwards_only() {
|
||||
let packet = make_packet_flags(true, false);
|
||||
let buf = packet.serialize().unwrap();
|
||||
let header = Packet::deserialize_header(&buf).unwrap();
|
||||
assert!(header.is_upwards_call);
|
||||
assert!(!header.end_hook);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flags_end_hook_only() {
|
||||
let packet = make_packet_flags(false, true);
|
||||
let buf = packet.serialize().unwrap();
|
||||
let header = Packet::deserialize_header(&buf).unwrap();
|
||||
assert!(!header.is_upwards_call);
|
||||
assert!(header.end_hook);
|
||||
}
|
||||
|
||||
// ── Empty fields ──────────────────────────────────────────────────────────
|
||||
|
||||
#[test]
|
||||
fn empty_path() {
|
||||
let packet = Packet {
|
||||
path: "".to_string(),
|
||||
..make_packet()
|
||||
};
|
||||
let buf = packet.serialize().unwrap();
|
||||
let header = Packet::deserialize_header(&buf).unwrap();
|
||||
assert_eq!(header.path, "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_procedure_id() {
|
||||
let packet = Packet {
|
||||
procedure_id: "".to_string(),
|
||||
..make_packet()
|
||||
};
|
||||
let buf = packet.serialize().unwrap();
|
||||
let result = Packet::deserialize(&buf).unwrap();
|
||||
assert_eq!(result.procedure_id, "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_data() {
|
||||
let packet = Packet {
|
||||
data: vec![],
|
||||
..make_packet()
|
||||
};
|
||||
let buf = packet.serialize().unwrap();
|
||||
let result = Packet::deserialize(&buf).unwrap();
|
||||
assert_eq!(result.data, &[] as &[u8]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn all_fields_empty() {
|
||||
let packet = Packet {
|
||||
hook_id: 0,
|
||||
is_upwards_call: false,
|
||||
end_hook: false,
|
||||
path: "".to_string(),
|
||||
procedure_id: "".to_string(),
|
||||
data: vec![],
|
||||
};
|
||||
let buf = packet.serialize().unwrap();
|
||||
let result = Packet::deserialize(&buf).unwrap();
|
||||
assert_eq!(result.hook_id, 0);
|
||||
assert_eq!(result.path, "");
|
||||
assert_eq!(result.procedure_id, "");
|
||||
assert_eq!(result.data, &[] as &[u8]);
|
||||
}
|
||||
|
||||
// ── Zero-copy: borrows point into the original buffer ─────────────────────
|
||||
|
||||
#[test]
|
||||
fn header_path_is_borrowed_from_buffer() {
|
||||
let buf = make_packet().serialize().unwrap();
|
||||
let header = Packet::deserialize_header(&buf).unwrap();
|
||||
|
||||
let path_ptr = header.path.as_ptr();
|
||||
let buf_range = buf.as_ptr_range();
|
||||
assert!(
|
||||
buf_range.contains(&path_ptr),
|
||||
"path must be a subslice of the input buffer, not a new allocation"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn body_remainder_is_borrowed_from_buffer() {
|
||||
let buf = make_packet().serialize().unwrap();
|
||||
let header = Packet::deserialize_header(&buf).unwrap();
|
||||
|
||||
let remainder_ptr = header.body_remainder.as_ptr();
|
||||
let buf_range = buf.as_ptr_range();
|
||||
assert!(
|
||||
buf_range.contains(&remainder_ptr),
|
||||
"body_remainder must point into the input buffer"
|
||||
);
|
||||
}
|
||||
|
||||
// ── Partial deserialization: body is untouched by header parse ────────────
|
||||
|
||||
#[test]
|
||||
fn deserialize_header_does_not_read_body() {
|
||||
let buf = make_packet().serialize().unwrap();
|
||||
let header = Packet::deserialize_header(&buf).unwrap();
|
||||
|
||||
// Re-parse body from the remainder to confirm it's intact.
|
||||
let body_buf = header.body_remainder;
|
||||
let body_len =
|
||||
u32::from_le_bytes([body_buf[0], body_buf[1], body_buf[2], body_buf[3]]) as usize;
|
||||
assert!(
|
||||
body_buf.len() >= 4 + body_len,
|
||||
"body_remainder must contain the full body"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_forward_buffer_after_header_parse() {
|
||||
// Simulates a router: parse the header, then forward the raw buffer
|
||||
// without touching the body.
|
||||
let original = make_packet().serialize().unwrap();
|
||||
let header = Packet::deserialize_header(&original).unwrap();
|
||||
|
||||
assert_eq!(header.path, "my/service/path");
|
||||
|
||||
// "Forward" by deserializing the full original buffer downstream.
|
||||
let forwarded = Packet::deserialize(&original).unwrap();
|
||||
assert_eq!(forwarded.procedure_id, "my.service.Method");
|
||||
assert_eq!(forwarded.data, &[0xDE, 0xAD, 0xBE, 0xEF]);
|
||||
}
|
||||
|
||||
// ── Truncation / corruption ───────────────────────────────────────────────
|
||||
|
||||
#[test]
|
||||
fn truncated_in_fixed_prefix() {
|
||||
let buf = make_packet().serialize().unwrap();
|
||||
// Cut inside the fixed 8-byte prefix.
|
||||
assert_eq!(
|
||||
Packet::deserialize_header(&buf[..4]).unwrap_err(),
|
||||
DeserializeError::BufferTooShort
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn truncated_in_path() {
|
||||
let buf = make_packet().serialize().unwrap();
|
||||
// Cut to just past the fixed prefix, mid-path.
|
||||
assert_eq!(
|
||||
Packet::deserialize_header(&buf[..9]).unwrap_err(),
|
||||
DeserializeError::BufferTooShort
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn truncated_in_body() {
|
||||
let buf = make_packet().serialize().unwrap();
|
||||
// Remove last byte — well into the body.
|
||||
assert!(Packet::deserialize(&buf[..buf.len() - 1]).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_buffer_rejected() {
|
||||
assert_eq!(
|
||||
Packet::deserialize_header(&[]).unwrap_err(),
|
||||
DeserializeError::BufferTooShort
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_utf8_in_path() {
|
||||
let mut buf = make_packet().serialize().unwrap();
|
||||
// Overwrite the first byte of the path (offset 8) with an invalid UTF-8 byte.
|
||||
buf[8] = 0xFF;
|
||||
assert_eq!(
|
||||
Packet::deserialize_header(&buf).unwrap_err(),
|
||||
DeserializeError::InvalidUtf8
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_utf8_in_procedure_id() {
|
||||
let mut buf = make_packet().serialize().unwrap();
|
||||
// Find where procedure_id starts: 8 + path_len + 4 (body_len) + 4 (proc_id_len)
|
||||
let path_len = u32::from_le_bytes([buf[4], buf[5], buf[6], buf[7]]) as usize;
|
||||
let proc_id_offset = 8 + path_len + 4 + 4;
|
||||
buf[proc_id_offset] = 0xFF;
|
||||
assert_eq!(
|
||||
Packet::deserialize(&buf).unwrap_err(),
|
||||
DeserializeError::InvalidUtf8
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
Reference in New Issue
Block a user