From 143f70b921c571f3dd2804a89637b244e38c759e Mon Sep 17 00:00:00 2001 From: mycognosist Date: Thu, 2 Dec 2021 15:12:52 +0200 Subject: [PATCH] initial commit --- .gitignore | 1 + Cargo.lock | 1025 ++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 18 + README.md | 16 + src/error.rs | 106 +++++ src/lib.rs | 106 +++++ src/lib.rs_lifetimes | 161 +++++++ src/main.rs | 9 + src/utils.rs | 80 ++++ 9 files changed, 1522 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 README.md create mode 100644 src/error.rs create mode 100644 src/lib.rs create mode 100644 src/lib.rs_lifetimes create mode 100644 src/main.rs create mode 100644 src/utils.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..323f046 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,1025 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + +[[package]] +name = "async-attributes" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "async-channel" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2114d64672151c0c5eaa5e131ec84a74f06e1e559830dabba01ca30605d66319" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + +[[package]] +name = "async-executor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "871f9bb5e0a22eeb7e8cf16641feb87c9dc67032ccf8ff49e772eb9941d3a965" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "once_cell", + "slab", +] + +[[package]] +name = "async-global-executor" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9586ec52317f36de58453159d48351bc244bc24ced3effc1fce22f3d48664af6" +dependencies = [ + "async-channel", + "async-executor", + "async-io", + "async-mutex", + "blocking", + "futures-lite", + "num_cpus", + "once_cell", +] + +[[package]] +name = "async-io" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a811e6a479f2439f0c04038796b5cfb3d2ad56c230e0f2d3f7b04d68cfee607b" +dependencies = [ + "concurrent-queue", + "futures-lite", + "libc", + "log", + "once_cell", + "parking", + "polling", + "slab", + "socket2", + "waker-fn", + "winapi 0.3.9", +] + +[[package]] +name = "async-lock" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6a8ea61bf9947a1007c5cada31e647dbc77b103c679858150003ba697ea798b" +dependencies = [ + "event-listener", +] + +[[package]] +name = "async-mutex" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479db852db25d9dbf6204e6cb6253698f175c15726470f78af0d918e99d6156e" +dependencies = [ + "event-listener", +] + +[[package]] +name = "async-process" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83137067e3a2a6a06d67168e49e68a0957d215410473a740cea95a2425c0b7c6" +dependencies = [ + "async-io", + "blocking", + "cfg-if 1.0.0", + "event-listener", + "futures-lite", + "libc", + "once_cell", + "signal-hook", + "winapi 0.3.9", +] + +[[package]] +name = "async-std" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8056f1455169ab86dd47b47391e4ab0cbd25410a70e9fe675544f49bafaf952" +dependencies = [ + "async-attributes", + "async-channel", + "async-global-executor", + "async-io", + "async-lock", + "async-process", + "crossbeam-utils", + "futures-channel", + "futures-core", + "futures-io", + "futures-lite", + "gloo-timers", + "kv-log-macro", + "log", + "memchr", + "num_cpus", + "once_cell", + "pin-project-lite", + "pin-utils", + "slab", + "wasm-bindgen-futures", +] + +[[package]] +name = "async-stream" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22068c0c19514942eefcfd4daf8976ef1aad84e61539f95cd200c35202f80af5" +dependencies = [ + "async-stream-impl", + "futures-core", +] + +[[package]] +name = "async-stream-impl" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25f9db3b38af870bf7e5cc649167533b493928e50744e2c30ae350230b414670" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "async-task" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91831deabf0d6d7ec49552e489aed63b7456a7a3c46cff62adad428110b0af0" + +[[package]] +name = "atomic-waker" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a" + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "base64" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" + +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "blocking" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046e47d4b2d391b1f6f8b407b1deb8dee56c1852ccd868becf2710f601b5f427" +dependencies = [ + "async-channel", + "async-task", + "atomic-waker", + "fastrand", + "futures-lite", + "once_cell", +] + +[[package]] +name = "bumpalo" +version = "3.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c" + +[[package]] +name = "c_linked_list" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4964518bd3b4a8190e832886cdc0da9794f12e8e6c1613a9e90ff331c4c8724b" + +[[package]] +name = "cache-padded" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba" + +[[package]] +name = "cc" +version = "1.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "concurrent-queue" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3" +dependencies = [ + "cache-padded", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" +dependencies = [ + "cfg-if 1.0.0", + "lazy_static", +] + +[[package]] +name = "ctor" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccc0a48a9b826acdf4028595adc9db92caea352f7af011a3034acd172a52a0aa" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "dirs" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" +dependencies = [ + "cfg-if 0.1.10", + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780" +dependencies = [ + "libc", + "redox_users", + "winapi 0.3.9", +] + +[[package]] +name = "event-listener" +version = "2.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7531096570974c3a9dcf9e4b8e1cede1ec26cf5046219fb3b9d897503b9be59" + +[[package]] +name = "fastrand" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b394ed3d285a429378d3b384b9eb1285267e7df4b166df24b7a6939a04dc392e" +dependencies = [ + "instant", +] + +[[package]] +name = "futures" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cd0210d8c325c245ff06fd95a3b13689a1a276ac8cfa8e8720cb840bfb84b9e" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fc8cd39e3dbf865f7340dce6a2d401d24fd37c6fe6c4f0ee0de8bfca2252d27" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "629316e42fe7c2a0b9a65b47d159ceaa5453ab14e8f0a3c5eedbb8cd55b4a445" + +[[package]] +name = "futures-executor" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b808bf53348a36cab739d7e04755909b9fcaaa69b7d7e588b37b6ec62704c97" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e481354db6b5c353246ccf6a728b0c5511d752c08da7260546fc0933869daa11" + +[[package]] +name = "futures-lite" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + +[[package]] +name = "futures-macro" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89f17b21645bc4ed773c69af9c9a0effd4a3f1a3876eadd453469f8854e7fdd" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "996c6442437b62d21a32cd9906f9c41e7dc1e19a9579843fad948696769305af" + +[[package]] +name = "futures-task" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dabf1872aaab32c886832f2276d2f5399887e2bd613698a02359e4ea83f8de12" + +[[package]] +name = "futures-util" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d22213122356472061ac0f1ab2cee28d2bac8491410fd68c2af53d1cedb83e" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "gcc" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" + +[[package]] +name = "get_if_addrs" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abddb55a898d32925f3148bd281174a68eeb68bbfd9a5938a57b18f506ee4ef7" +dependencies = [ + "c_linked_list", + "get_if_addrs-sys", + "libc", + "winapi 0.2.8", +] + +[[package]] +name = "get_if_addrs-sys" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d04f9fb746cf36b191c00f3ede8bde9c8e64f9f4b05ae2694a9ccf5e3f5ab48" +dependencies = [ + "gcc", + "libc", +] + +[[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi", +] + +[[package]] +name = "gloo-timers" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47204a46aaff920a1ea58b11d03dec6f704287d27561724a4631e450654a891f" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "golgi" +version = "0.1.0" +dependencies = [ + "async-std", + "base64 0.13.0", + "futures", + "hex", + "kuska-handshake", + "kuska-sodiumoxide", + "kuska-ssb", + "serde", + "serde_json", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "indexmap" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + +[[package]] +name = "js-sys" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "kuska-handshake" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33da4b69f23c2ece0b3e729d079cebdc2c0206e493e42f510f500ad81c631d5" +dependencies = [ + "futures", + "hex", + "kuska-sodiumoxide", + "log", + "thiserror", +] + +[[package]] +name = "kuska-sodiumoxide" +version = "0.2.5-0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae0f8eafdd240b722243787b51fdaf8df6693fb8621d0f7061cdba574214cf88" +dependencies = [ + "libc", + "libsodium-sys", + "serde", +] + +[[package]] +name = "kuska-ssb" +version = "0.2.0" +dependencies = [ + "async-std", + "async-stream", + "base64 0.11.0", + "dirs", + "futures", + "get_if_addrs", + "hex", + "kuska-handshake", + "kuska-sodiumoxide", + "log", + "once_cell", + "regex", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119" + +[[package]] +name = "libsodium-sys" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b779387cd56adfbc02ea4a668e704f729be8d6a6abd2c27ca5ee537849a92fd" +dependencies = [ + "cc", + "libc", + "pkg-config", + "walkdir", +] + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if 1.0.0", + "value-bag", +] + +[[package]] +name = "memchr" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "once_cell" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" + +[[package]] +name = "parking" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" + +[[package]] +name = "pin-project-lite" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12295df4f294471248581bc09bef3c38a5e46f1e36d6a37353621a0c6c357e1f" + +[[package]] +name = "polling" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "685404d509889fade3e86fe3a5803bca2ec09b0c0778d5ada6ec8bf7a8de5259" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "log", + "wepoll-ffi", + "winapi 0.3.9", +] + +[[package]] +name = "proc-macro2" +version = "1.0.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" +dependencies = [ + "getrandom", + "redox_syscall", +] + +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + +[[package]] +name = "ryu" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c9613b5a66ab9ba26415184cfc41156594925a9cf3a2057e57f31ff145f6568" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "serde" +version = "1.0.130" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.130" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0ffa0837f2dfa6fb90868c2b5468cad482e175f7dad97e7421951e663f2b527" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "signal-hook" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c98891d737e271a2954825ef19e46bd16bdb98e2746f2eec4f7a4ef7946efd1" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +dependencies = [ + "libc", +] + +[[package]] +name = "slab" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" + +[[package]] +name = "socket2" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dc90fe6c7be1a323296982db1836d1ea9e47b6839496dde9a541bc496df3516" +dependencies = [ + "libc", + "winapi 0.3.9", +] + +[[package]] +name = "syn" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "thiserror" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "value-bag" +version = "1.0.0-alpha.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79923f7731dc61ebfba3633098bf3ac533bbd35ccd8c57e7088d9a5eebe0263f" +dependencies = [ + "ctor", + "version_check", +] + +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + +[[package]] +name = "waker-fn" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" + +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi 0.3.9", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "wasm-bindgen" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e8d7523cb1f2a4c96c1317ca690031b714a51cc14e05f712446691f413f5d39" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc" + +[[package]] +name = "web-sys" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "wepoll-ffi" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb" +dependencies = [ + "cc", +] + +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi 0.3.9", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..18620f3 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "golgi" +version = "0.1.0" +authors = ["glyph "] +edition = "2021" + +[dependencies] +async-std = "1.10.0" +base64 = "0.13.0" +futures = "0.3.18" +hex = "0.4.3" +kuska-handshake = { version = "0.2.0", features = ["async_std"] } +kuska-sodiumoxide = "0.2.5-0" +# waiting for a pr merge upstream +kuska-ssb = { path = "../ssb" } +# try to replace with miniserde +serde = "1" +serde_json = "1" diff --git a/README.md b/README.md new file mode 100644 index 0000000..59eae25 --- /dev/null +++ b/README.md @@ -0,0 +1,16 @@ +# golgi + +_A Scuttlebutt client written in Rust_ + +An experimental client which uses the [kuska-ssb](https://github.com/Kuska-ssb) libraries and aims to provide a high-level API for interacting with an sbot instance. Development efforts are currently oriented towards [go-sbot](https://github.com/cryptoscope/ssb) interoperability. + +## Example Usage + +```rust +pub async fn run() -> Result<(), GolgiError> { + let mut sbot_client = Sbot::init(None, None).await?; + + let id = sbot_client.whoami().await?; + println!("{}", id); +} +``` diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..9ff3ef8 --- /dev/null +++ b/src/error.rs @@ -0,0 +1,106 @@ +/* +use async_std::{io::Read, net::TcpStream}; +use std::fmt::Debug; + +use kuska_handshake::async_std::BoxStream; +use kuska_sodiumoxide::crypto::sign::ed25519; +use kuska_ssb::api::{dto::WhoAmIOut, ApiCaller}; +use kuska_ssb::discovery; +use kuska_ssb::keystore; +use kuska_ssb::keystore::OwnedIdentity; +use kuska_ssb::rpc::{RecvMsg, RequestNo, RpcReader, RpcWriter}; + +type Result = std::result::Result>; + +pub fn whoami_res_parse(body: &[u8]) -> Result { + Ok(serde_json::from_slice(body)?) +} +*/ + +#[derive(Debug)] +pub enum GolgiError { + DecodeBase64(base64::DecodeError), + Io { + source: std::io::Error, + context: String, + }, + Handshake(kuska_handshake::async_std::Error), + KuskaApi(kuska_ssb::api::Error), + KuskaFeed(kuska_ssb::feed::Error), + KuskaRpc(kuska_ssb::rpc::Error), + // error message returned from the go-sbot + Sbot(String), + SerdeJson(serde_json::Error), + WhoAmI(String), +} + +impl std::error::Error for GolgiError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match *self { + GolgiError::DecodeBase64(ref err) => Some(err), + GolgiError::Io { ref source, .. } => Some(source), + GolgiError::Handshake(_) => None, + GolgiError::KuskaApi(ref err) => Some(err), + GolgiError::KuskaFeed(ref err) => Some(err), + GolgiError::KuskaRpc(ref err) => Some(err), + GolgiError::Sbot(_) => None, + GolgiError::SerdeJson(ref err) => Some(err), + GolgiError::WhoAmI(_) => None, + } + } +} + +impl std::fmt::Display for GolgiError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match *self { + // TODO: add context (what were we trying to decode?) + GolgiError::DecodeBase64(_) => write!(f, "Failed to decode base64"), + GolgiError::Io { ref context, .. } => write!(f, "IO error: {}", context), + GolgiError::Handshake(ref err) => write!(f, "{}", err), + GolgiError::KuskaApi(_) => write!(f, "SSB API failure"), + GolgiError::KuskaFeed(_) => write!(f, "SSB feed error"), + // TODO: improve this variant with a context message + // then have the core display msg be: "SSB RPC error: {}", context + GolgiError::KuskaRpc(_) => write!(f, "SSB RPC failure"), + GolgiError::Sbot(ref err) => write!(f, "Sbot returned an error response: {}", err), + GolgiError::SerdeJson(_) => write!(f, "Failed to serialize JSON slice"), + GolgiError::WhoAmI(ref err) => write!(f, "{}", err), + } + } +} + +impl From for GolgiError { + fn from(err: base64::DecodeError) -> Self { + GolgiError::DecodeBase64(err) + } +} + +impl From for GolgiError { + fn from(err: kuska_handshake::async_std::Error) -> Self { + GolgiError::Handshake(err) + } +} + +impl From for GolgiError { + fn from(err: kuska_ssb::api::Error) -> Self { + GolgiError::KuskaApi(err) + } +} + +impl From for GolgiError { + fn from(err: kuska_ssb::feed::Error) -> Self { + GolgiError::KuskaFeed(err) + } +} + +impl From for GolgiError { + fn from(err: kuska_ssb::rpc::Error) -> Self { + GolgiError::KuskaRpc(err) + } +} + +impl From for GolgiError { + fn from(err: serde_json::Error) -> Self { + GolgiError::SerdeJson(err) + } +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..f94841c --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,106 @@ +mod error; +mod utils; + +use async_std::net::TcpStream; +//use futures::io::{self, AsyncRead as Read, AsyncWrite as Write}; +use kuska_handshake::async_std::{BoxStream, BoxStreamRead, BoxStreamWrite}; +use kuska_handshake::HandshakeComplete; +use kuska_sodiumoxide::crypto::{auth, sign::ed25519}; +use kuska_ssb::api::{dto::CreateHistoryStreamIn, ApiCaller}; +use kuska_ssb::discovery; +use kuska_ssb::keystore; +use kuska_ssb::keystore::OwnedIdentity; +use kuska_ssb::rpc::{RpcReader, RpcWriter}; + +use crate::error::GolgiError; + +struct Sbot { + id: String, + public_key: ed25519::PublicKey, + private_key: ed25519::SecretKey, + address: String, + // aka caps key (scuttleverse identifier) + network_id: auth::Key, + client: ApiCaller, + rpc_reader: RpcReader, +} + +impl Sbot { + async fn init(ip_port: Option, net_id: Option) -> Result { + let address; + if ip_port.is_none() { + address = "127.0.0.1:8008".to_string(); + } else { + address = ip_port.unwrap(); + } + + let network_id; + if net_id.is_none() { + network_id = discovery::ssb_net_id(); + } else { + network_id = auth::Key::from_slice(&hex::decode(net_id.unwrap()).unwrap()).unwrap(); + } + + let OwnedIdentity { pk, sk, id } = keystore::from_gosbot_local() + .await + .expect("couldn't read local secret"); + + let socket = TcpStream::connect(&address) + .await + .map_err(|source| GolgiError::Io { + source, + context: "socket error; failed to initiate tcp stream connection".to_string(), + })?; + + let handshake = kuska_handshake::async_std::handshake_client( + &mut &socket, + network_id.clone(), + pk, + sk.clone(), + pk, + ) + .await + .map_err(GolgiError::Handshake)?; + + let (box_stream_read, box_stream_write) = + BoxStream::from_handshake(socket.clone(), socket, handshake, 0x8000).split_read_write(); + + let rpc_reader = RpcReader::new(box_stream_read); + let client = ApiCaller::new(RpcWriter::new(box_stream_write)); + + Ok(Self { + id, + public_key: pk, + private_key: sk, + address, + network_id, + client: client, + rpc_reader: rpc_reader, + }) + } + + async fn whoami(&mut self) -> Result { + let req_id = self.client.whoami_req_send().await?; + + utils::get_async(&mut self.rpc_reader, req_id, utils::whoami_res_parse) + .await + .map(|whoami| whoami.id) + } + + async fn create_history_stream(&mut self, id: String) -> Result<(), GolgiError> { + let args = CreateHistoryStreamIn::new(id); + let req_id = self.client.create_history_stream_req_send(&args).await?; + utils::print_source_until_eof(&mut self.rpc_reader, req_id, utils::feed_res_parse).await + } +} + +pub async fn run() -> Result<(), GolgiError> { + let mut sbot_client = Sbot::init(None, None).await?; + + let id = sbot_client.whoami().await?; + println!("{}", id); + + sbot_client.create_history_stream(id).await?; + + Ok(()) +} diff --git a/src/lib.rs_lifetimes b/src/lib.rs_lifetimes new file mode 100644 index 0000000..e2de20f --- /dev/null +++ b/src/lib.rs_lifetimes @@ -0,0 +1,161 @@ +mod error; +mod utils; + +use async_std::net::TcpStream; +//use futures::io::{self, AsyncRead as Read, AsyncWrite as Write}; +use kuska_handshake::async_std::{BoxStream, BoxStreamRead, BoxStreamWrite}; +use kuska_handshake::HandshakeComplete; +use kuska_sodiumoxide::crypto::{auth, sign::ed25519}; +use kuska_ssb::api::{dto::CreateHistoryStreamIn, ApiCaller}; +use kuska_ssb::discovery; +use kuska_ssb::keystore; +use kuska_ssb::keystore::OwnedIdentity; +use kuska_ssb::rpc::{RpcReader, RpcWriter}; + +use crate::error::GolgiError; + +//struct Sbot { +struct Sbot<'a> { + id: String, + public_key: ed25519::PublicKey, + private_key: ed25519::SecretKey, + address: String, + // aka caps key (scuttleverse identifier) + network_id: auth::Key, + //socket: TcpStream, + //client: ApiCaller, + client: ApiCaller, + //rpc_reader: RpcReader, + rpc_reader: RpcReader<&'a TcpStream>, +} + +//impl Sbot { +//impl Sbot<'static> { +impl Sbot<'_> { + async fn init( + ip_port: Option, + net_id: Option, + ) -> Result, GolgiError> { + let address; + if ip_port.is_none() { + // set default + address = "127.0.0.1:8008".to_string(); + } else { + address = ip_port.unwrap().to_string(); + } + + let network_id; + if net_id.is_none() { + network_id = discovery::ssb_net_id(); + } else { + network_id = auth::Key::from_slice(&hex::decode(net_id.unwrap()).unwrap()).unwrap(); + } + + let OwnedIdentity { pk, sk, id } = keystore::from_gosbot_local() + .await + .expect("couldn't read local secret"); + + let socket = TcpStream::connect(&address) + .await + .map_err(|source| GolgiError::Io { + source, + context: "socket error; failed to initiate tcp stream connection".to_string(), + })?; + + let handshake = kuska_handshake::async_std::handshake_client( + &mut &socket, + network_id.clone(), + pk, + sk.clone(), + pk, + ) + .await + .map_err(|err| GolgiError::Handshake(err))?; + + let (box_stream_read, box_stream_write) = + BoxStream::from_handshake(socket, socket, handshake, 0x8000).split_read_write(); + + let rpc_reader = RpcReader::new(box_stream_read); + let client = ApiCaller::new(RpcWriter::new(box_stream_write)); + + Ok(Self { + id, + public_key: pk, + private_key: sk, + address, + network_id, + client: client, + rpc_reader: rpc_reader, + }) + } +} + +pub async fn run() -> Result<(), GolgiError> { + let sbot_client = Sbot::init(None, None); + /* + // read go-sbot id details from `/.ssb-go/secret + let OwnedIdentity { pk, sk, id } = keystore::from_gosbot_local() + .await + .expect("read local secret"); + println!("connecting with identity {}", id); + + // set the public key, ip and port for the sbot instance + let sbot_public_key = "a0SsCiZkBu6qaQ6tWVvzQPDSzvO0JqMAqPXt0LBIl30=".to_string(); + let server_pk = + ed25519::PublicKey::from_slice(&base64::decode(&sbot_public_key)?).expect("bad public key"); + let server_ipport = "127.0.0.1:8008".to_string(); + + // connect to the local go-sbot instance + let mut socket = TcpStream::connect(server_ipport) + .await + .map_err(|source| GolgiError::Io { + source, + context: "socket error; failed to initiate tcp stream connection".to_string(), + })?; + + // initiate secret handshake + let handshake = kuska_handshake::async_std::handshake_client( + &mut socket, + discovery::ssb_net_id(), + pk, + sk.clone(), + server_pk, + ) + .await + .expect("handshake error"); + + println!("💃 handshake complete"); + + // call `whoami` + let (box_stream_read, box_stream_write) = + BoxStream::from_handshake(&socket, &socket, handshake, 0x8000).split_read_write(); + + let mut rpc_reader = RpcReader::new(box_stream_read); + let mut client = ApiCaller::new(RpcWriter::new(box_stream_write)); + + let req_id = client.whoami_req_send().await?; + let whoami = match utils::get_async(&mut rpc_reader, req_id, utils::whoami_res_parse).await { + Ok(res) => { + println!("😊 server says hello to {}", res.id); + id + } + Err(err) => { + if !err + .to_string() + .contains("method:whoami is not in list of allowed methods") + { + println!("Cannot ask for whoami {}", err); + } + id + } + }; + + // call `createhistorystream` + let args = CreateHistoryStreamIn::new(whoami.clone()); + // TODO: this should return an error if the args are wrong but it doesn't? + let req_id = client.create_history_stream_req_send(&args).await?; + utils::print_source_until_eof(&mut rpc_reader, req_id, utils::feed_res_parse).await?; + */ + + Ok(()) +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..ee17c18 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,9 @@ +use std::process; + +#[async_std::main] +async fn main() { + if let Err(e) = golgi::run().await { + eprintln!("Application error: {}", e); + process::exit(1); + } +} diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..3a71d51 --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,80 @@ +/* + +use kuska_handshake::async_std::BoxStream; +use kuska_sodiumoxide::crypto::sign::ed25519; +use kuska_ssb::discovery; +use kuska_ssb::keystore; +use kuska_ssb::keystore::OwnedIdentity; +*/ +use std::fmt::Debug; + +use async_std::io::Read; + +use kuska_ssb::api::dto::WhoAmIOut; +use kuska_ssb::feed::Feed; +use kuska_ssb::rpc::{RecvMsg, RequestNo, RpcReader}; + +use crate::error::GolgiError; + +pub fn feed_res_parse(body: &[u8]) -> Result { + Ok(Feed::from_slice(body)?) +} + +pub fn whoami_res_parse(body: &[u8]) -> Result { + Ok(serde_json::from_slice(body)?) +} + +pub async fn get_async<'a, R, T, F>( + rpc_reader: &mut RpcReader, + req_no: RequestNo, + f: F, +) -> Result +where + R: Read + Unpin, + F: Fn(&[u8]) -> Result, + T: Debug, +{ + loop { + let (id, msg) = rpc_reader.recv().await?; + if id == req_no { + match msg { + RecvMsg::RpcResponse(_type, body) => { + return f(&body).map_err(|err| err); + } + RecvMsg::ErrorResponse(message) => { + return Err(GolgiError::Sbot(message)); + } + _ => {} + } + } + } +} + +pub async fn print_source_until_eof<'a, R, T, F>( + rpc_reader: &mut RpcReader, + req_no: RequestNo, + f: F, +) -> Result<(), GolgiError> +where + R: Read + Unpin, + F: Fn(&[u8]) -> Result, + T: Debug + serde::Deserialize<'a>, +{ + loop { + let (id, msg) = rpc_reader.recv().await?; + if id == req_no { + match msg { + RecvMsg::RpcResponse(_type, body) => { + let display = f(&body)?; + println!("{:?}", display); + } + RecvMsg::ErrorResponse(message) => { + return Err(GolgiError::Sbot(message)); + } + RecvMsg::CancelStreamRespose() => break, + _ => {} + } + } + } + Ok(()) +}