From 70bf234947f65f4d7d0e0173a5a5ff967b5d9f10 Mon Sep 17 00:00:00 2001 From: Titouan Rigoudy Date: Mon, 4 Jan 2021 19:12:14 +0000 Subject: [PATCH] Introduce simple Connection to send and receive frames. --- Cargo.lock | 145 +++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/proto/codec.rs | 13 +++- src/proto/connection.rs | 83 ++++++++++++++++++++++ src/proto/mod.rs | 4 ++ src/proto/value_codec.rs | 2 +- 6 files changed, 244 insertions(+), 4 deletions(-) create mode 100644 src/proto/connection.rs diff --git a/Cargo.lock b/Cargo.lock index c36cf63..01767a3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -267,6 +267,14 @@ dependencies = [ "unicode-normalization 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "instant" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "iovec" version = "0.1.4" @@ -310,6 +318,14 @@ dependencies = [ "scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "lock_api" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "log" version = "0.3.9" @@ -344,6 +360,11 @@ dependencies = [ "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "memchr" +version = "2.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "memoffset" version = "0.5.4" @@ -386,6 +407,18 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "mio" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "miow 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "ntapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "mio-uds" version = "0.6.8" @@ -418,6 +451,15 @@ dependencies = [ "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "miow" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "socket2 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "net2" version = "0.2.34" @@ -437,6 +479,14 @@ dependencies = [ "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ntapi" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "num_cpus" version = "1.13.0" @@ -446,6 +496,11 @@ dependencies = [ "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "once_cell" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "parking_lot" version = "0.8.0" @@ -466,6 +521,16 @@ dependencies = [ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "parking_lot" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "instant 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "lock_api 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "parking_lot_core" version = "0.5.0" @@ -495,11 +560,29 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "parking_lot_core" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "instant 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "percent-encoding" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "pin-project-lite" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "proc-macro2" version = "1.0.18" @@ -719,6 +802,14 @@ dependencies = [ "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "signal-hook-registry" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "slab" version = "0.1.3" @@ -747,6 +838,16 @@ name = "smallvec" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "socket2" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "solstice" version = "0.1.0" @@ -766,6 +867,7 @@ dependencies = [ "slab 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", "threadpool 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", @@ -857,6 +959,25 @@ dependencies = [ "tokio-uds 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tokio" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)", + "once_cell 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project-lite 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "signal-hook-registry 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-macros 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tokio-codec" version = "0.1.2" @@ -923,6 +1044,16 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tokio-macros" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tokio-reactor" version = "0.1.12" @@ -1146,31 +1277,41 @@ dependencies = [ "checksum hermit-abi 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "91780f809e750b0a89f5544be56617ff6b1227ee485bcb06ebe10cdf89bd3b71" "checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" +"checksum instant 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec" "checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" "checksum libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)" = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49" "checksum lock_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed946d4529956a20f2d63ebe1b69996d5a2137c91913fe3ebbeff957f5bca7ff" "checksum lock_api 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" +"checksum lock_api 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd96ffd135b2fd7b973ac026d28085defbe8983df057ced3eb4f2130b0831312" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" "checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" "checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20" +"checksum memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" "checksum memoffset 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b4fc2c02a7e374099d4ee95a193111f72d2110197fe200272371758f6c3643d8" "checksum mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a637d1ca14eacae06296a008fa7ad955347e34efcb5891cfd8ba05491a37907e" "checksum mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)" = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430" +"checksum mio 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)" = "e50ae3f04d169fcc9bde0b547d1c205219b7157e07ded9c5aff03e0637cb3ed7" "checksum mio-uds 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" "checksum miow 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3e690c5df6b2f60acd45d56378981e827ff8295562fc8d34f573deb267a59cd1" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" +"checksum miow 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "5a33c1b55807fbed163481b5ba66db4b2fa6cde694a5027be10fb724206c5897" "checksum net2 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)" = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7" "checksum nix 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bfb3ddedaa14746434a02041940495bf11325c22f6d36125d3bdd56090d50a79" +"checksum ntapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7a31937dea023539c72ddae0e3571deadc1414b300483fa7aaec176168cfa9d2" "checksum num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +"checksum once_cell 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0" +"checksum parking_lot 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" "checksum parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa7767817701cce701d5585b9c4db3cdd02086398322c1d7e8bf5094a96a2ce7" "checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" "checksum parking_lot_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cb88cb1cb3790baa6776844f968fea3be44956cf184fa1be5a03341f5491278c" "checksum parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" +"checksum parking_lot_core 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ccb628cad4f84851442432c60ad8e1f607e29752d0bf072cbd0baf28aa34272" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" +"checksum pin-project-lite 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6b063f57ec186e6140e2b8b6921e5f1bd89c7356dda5b33acc5401203ca6131c" "checksum proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa" "checksum quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" "checksum rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" @@ -1197,11 +1338,13 @@ dependencies = [ "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum sha1 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a307a40d5834140e4213a6952483b84e9ad53bdcab918b7335a6e305e505a53c" +"checksum signal-hook-registry 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16f1d0fef1604ba8f7a073c7e701f213e056707210e9020af4528e0101ce11a6" "checksum slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d807fd58c4181bbabed77cb3b891ba9748241a552bcc5be698faaebefc54f46e" "checksum slab 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6dbdd334bd28d328dad1c41b0ea662517883d8880d8533895ef96c8003dec9c4" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" "checksum smallvec 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cb5678e1615754284ec264d9bb5b4c27d2018577fd90ac0ceb578591ed5ee4" +"checksum socket2 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e" "checksum syn 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)" = "b5304cfdf27365b7585c25d4af91b35016ed21ef88f17ced89c7093b43dba8b6" "checksum thiserror 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)" = "b13f926965ad00595dd129fa12823b04bbf866e9085ab0a5f2b05b850fbfc344" "checksum thiserror-impl 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)" = "893582086c2f98cde18f906265a65b5030a074b1046c674ae898be6519a7f479" @@ -1210,12 +1353,14 @@ dependencies = [ "checksum threadpool 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" "checksum time 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" "checksum tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6" +"checksum tokio 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d258221f566b6c803c7b4714abadc080172b272090cdc5e244a6d4dd13c3a6bd" "checksum tokio-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "25b2998660ba0e70d18684de5d06b70b70a3a747469af9dea7618cc59e75976b" "checksum tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "aeeffbbb94209023feaef3c196a41cbcdafa06b4a6f893f68779bb5e53796f71" "checksum tokio-current-thread 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b1de0e32a83f131e002238d7ccde18211c0a5397f60cbfffcb112868c2e0e20e" "checksum tokio-executor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "fb2d1b8f4548dbf5e1f7818512e9c406860678f29c300cdf0ebac72d1a3a1671" "checksum tokio-fs 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "297a1206e0ca6302a0eed35b700d292b275256f596e2f3fea7729d5e629b6ff4" "checksum tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674" +"checksum tokio-macros 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "42517d2975ca3114b22a16192634e8241dc5cc1f130be194645970cc1c371494" "checksum tokio-reactor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "09bc590ec4ba8ba87652da2068d150dcada2cfa2e07faae270a5e0409aa51351" "checksum tokio-sync 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "edfe50152bc8164fcc456dab7891fa9bf8beaf01c5ee7e1dd43a397c3cf87dee" "checksum tokio-tcp 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "98df18ed66e3b72e742f185882a9e201892407957e45fbff8da17ae7a7c51f72" diff --git a/Cargo.toml b/Cargo.toml index 9d851c7..b983b93 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ rustc-serialize = "^0.3.17" slab = "^0.2" thiserror = "^1.0" threadpool = "^1.0" +tokio = { version = "1", features = ["full"] } tokio-core = "^0.1" tokio-io = "^0.1" tokio-codec = "^0.1" diff --git a/src/proto/codec.rs b/src/proto/codec.rs index 075fa23..3a650ae 100644 --- a/src/proto/codec.rs +++ b/src/proto/codec.rs @@ -3,6 +3,7 @@ //! The goal of this codec is to transform byte streams into value streams. use std::convert::TryInto; +use std::io; use std::marker; use bytes::BytesMut; @@ -26,19 +27,25 @@ pub enum FrameEncodeError { ValueEncodeError(#[from] ValueEncodeError), } +impl From for io::Error { + fn from(error: FrameEncodeError) -> Self { + io::Error::new(io::ErrorKind::InvalidData, format!("{}", error)) + } +} + /// Encodes entire protocol frames containing values of type `T`. -pub struct FrameEncoder { +pub struct FrameEncoder { phantom: marker::PhantomData, } -impl FrameEncoder { +impl FrameEncoder { pub fn new() -> Self { Self { phantom: marker::PhantomData, } } - fn encode_to(&mut self, value: &T, buffer: &mut BytesMut) -> Result<(), FrameEncodeError> { + pub fn encode_to(&mut self, value: &T, buffer: &mut BytesMut) -> Result<(), FrameEncodeError> { let mut prefixer = Prefixer::new(buffer); ValueEncoder::new(prefixer.suffix_mut()).encode(value)?; diff --git a/src/proto/connection.rs b/src/proto/connection.rs new file mode 100644 index 0000000..2cba8dd --- /dev/null +++ b/src/proto/connection.rs @@ -0,0 +1,83 @@ +use std::io; +use std::marker::PhantomData; + +use bytes::BytesMut; +use tokio::io::{AsyncReadExt, AsyncWriteExt}; +use tokio::net::TcpStream; + +use crate::proto::{FrameDecoder, FrameEncoder, ValueDecode, ValueEncode}; + +#[derive(Debug)] +pub struct Connection { + stream: TcpStream, + + read_buffer: BytesMut, + + phantom_read: PhantomData, + phantom_write: PhantomData, +} + +impl Connection +where + ReadFrame: ValueDecode, + WriteFrame: ValueEncode + ?Sized, +{ + pub fn new(stream: TcpStream) -> Self { + Connection { + stream, + read_buffer: BytesMut::with_capacity(4096), + phantom_read: PhantomData, + phantom_write: PhantomData, + } + } + + pub async fn read(&mut self) -> io::Result { + let mut decoder = FrameDecoder::new(); + + loop { + if let Some(frame) = decoder.decode_from(&mut self.read_buffer)? { + return Ok(frame); + } + self.stream.read_buf(&mut self.read_buffer).await?; + } + } + + pub async fn write(&mut self, frame: &WriteFrame) -> io::Result<()> { + let mut bytes = BytesMut::new(); + FrameEncoder::new().encode_to(frame, &mut bytes)?; + self.stream.write_all(bytes.as_ref()).await + } +} + +#[cfg(test)] +mod tests { + use tokio::net::{TcpListener, TcpStream}; + + use super::Connection; + + #[tokio::test] + async fn ping_pong() { + let listener = TcpListener::bind("localhost:0").await.unwrap(); + let address = listener.local_addr().unwrap(); + + let server_task = tokio::spawn(async move { + let (stream, _peer_address) = listener.accept().await.unwrap(); + let mut connection = Connection::::new(stream); + + assert_eq!(connection.read().await.unwrap(), "ping"); + connection.write("pong").await.unwrap(); + assert_eq!(connection.read().await.unwrap(), "ping"); + connection.write("pong").await.unwrap(); + }); + + let stream = TcpStream::connect(address).await.unwrap(); + let mut connection = Connection::::new(stream); + + connection.write("ping").await.unwrap(); + assert_eq!(connection.read().await.unwrap(), "pong"); + connection.write("ping").await.unwrap(); + assert_eq!(connection.read().await.unwrap(), "pong"); + + server_task.await.unwrap(); + } +} diff --git a/src/proto/mod.rs b/src/proto/mod.rs index 3a90674..120a575 100644 --- a/src/proto/mod.rs +++ b/src/proto/mod.rs @@ -1,4 +1,5 @@ mod codec; +mod connection; mod constants; mod handler; mod packet; @@ -6,11 +7,14 @@ pub mod peer; mod prefix; pub mod server; mod stream; +#[cfg(test)] +mod testing; pub mod u32; mod user; mod value_codec; pub use self::codec::*; +pub use self::connection::Connection; pub use self::handler::*; pub use self::packet::*; pub use self::server::{ServerRequest, ServerResponse}; diff --git a/src/proto/value_codec.rs b/src/proto/value_codec.rs index da5591b..6c7dc90 100644 --- a/src/proto/value_codec.rs +++ b/src/proto/value_codec.rs @@ -388,7 +388,7 @@ impl<'a> ValueEncoder<'a> { /// ``` /// encoder.encode(&Foo::new(bar))?; /// ``` - pub fn encode(&mut self, val: &T) -> Result<(), ValueEncodeError> { + pub fn encode(&mut self, val: &T) -> Result<(), ValueEncodeError> { val.encode(self) } }