io::copy
This commit is contained in:
parent
09c9c458a0
commit
d3c4e41a12
32
Cargo.lock
generated
32
Cargo.lock
generated
@ -617,26 +617,6 @@ version = "2.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae"
|
checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pin-project"
|
|
||||||
version = "1.1.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3"
|
|
||||||
dependencies = [
|
|
||||||
"pin-project-internal",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pin-project-internal"
|
|
||||||
version = "1.1.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project-lite"
|
name = "pin-project-lite"
|
||||||
version = "0.2.13"
|
version = "0.2.13"
|
||||||
@ -705,8 +685,6 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"futures",
|
"futures",
|
||||||
"miette",
|
"miette",
|
||||||
"pin-project",
|
|
||||||
"ruchei",
|
|
||||||
"smol",
|
"smol",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -719,16 +697,6 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ruchei"
|
|
||||||
version = "0.0.72"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e71761a29b7300c117636cb3566b11ee8d99559346d923767aae245766178539"
|
|
||||||
dependencies = [
|
|
||||||
"futures-util",
|
|
||||||
"pin-project",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-demangle"
|
name = "rustc-demangle"
|
||||||
version = "0.1.23"
|
version = "0.1.23"
|
||||||
|
@ -6,6 +6,4 @@ edition = "2021"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
futures = "0.3.30"
|
futures = "0.3.30"
|
||||||
miette = { version = "5", features = ["fancy"] }
|
miette = { version = "5", features = ["fancy"] }
|
||||||
pin-project = "1"
|
|
||||||
ruchei = "0.0.72"
|
|
||||||
smol = "1.3.0"
|
smol = "1.3.0"
|
||||||
|
81
src/main.rs
81
src/main.rs
@ -1,84 +1,9 @@
|
|||||||
use std::{
|
use futures::{AsyncReadExt, StreamExt};
|
||||||
pin::Pin,
|
|
||||||
task::{Context, Poll},
|
|
||||||
};
|
|
||||||
|
|
||||||
use futures::{ready, AsyncRead, AsyncWrite, Sink, Stream, StreamExt};
|
|
||||||
use miette::IntoDiagnostic;
|
use miette::IntoDiagnostic;
|
||||||
use ruchei::echo::bufferless::EchoBufferless;
|
|
||||||
|
|
||||||
async fn handle(stream: smol::io::Result<smol::net::TcpStream>) -> smol::io::Result<()> {
|
async fn handle(stream: smol::io::Result<smol::net::TcpStream>) -> smol::io::Result<()> {
|
||||||
Forward {
|
let (reader, mut writer) = stream?.split();
|
||||||
stream: stream?,
|
futures::io::copy(reader, &mut writer).await.map(|_| {})
|
||||||
write_buf: None,
|
|
||||||
}
|
|
||||||
.fuse()
|
|
||||||
.echo_bufferless()
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
|
|
||||||
struct WriteBuf {
|
|
||||||
msg: Vec<u8>,
|
|
||||||
start: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[pin_project::pin_project]
|
|
||||||
struct Forward {
|
|
||||||
#[pin]
|
|
||||||
stream: smol::net::TcpStream,
|
|
||||||
write_buf: Option<WriteBuf>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Stream for Forward {
|
|
||||||
type Item = smol::io::Result<Vec<u8>>;
|
|
||||||
|
|
||||||
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
|
|
||||||
let mut this = self.as_mut().project();
|
|
||||||
let mut buf = [0; 65536];
|
|
||||||
let read = ready!(this.stream.as_mut().poll_read(cx, &mut buf))?;
|
|
||||||
if read == 0 {
|
|
||||||
ready!(self.poll_close(cx))?;
|
|
||||||
Poll::Ready(None)
|
|
||||||
} else {
|
|
||||||
Poll::Ready(Some(Ok(buf[..read].into())))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Sink<Vec<u8>> for Forward {
|
|
||||||
type Error = smol::io::Error;
|
|
||||||
|
|
||||||
fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
|
||||||
let mut this = self.project();
|
|
||||||
while let Some(write_buf) = this.write_buf {
|
|
||||||
let bytes = ready!(this
|
|
||||||
.stream
|
|
||||||
.as_mut()
|
|
||||||
.poll_write(cx, &write_buf.msg[write_buf.start..]))?;
|
|
||||||
write_buf.start += bytes;
|
|
||||||
if write_buf.start == write_buf.msg.len() || bytes == 0 {
|
|
||||||
*this.write_buf = None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Poll::Ready(Ok(()))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn start_send(self: Pin<&mut Self>, msg: Vec<u8>) -> Result<(), Self::Error> {
|
|
||||||
if !msg.is_empty() {
|
|
||||||
*self.project().write_buf = Some(WriteBuf { msg, start: 0 });
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
|
||||||
ready!(self.as_mut().poll_ready(cx))?;
|
|
||||||
self.project().stream.poll_flush(cx)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
|
||||||
ready!(self.as_mut().poll_flush(cx))?;
|
|
||||||
self.project().stream.poll_close(cx)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> miette::Result<()> {
|
fn main() -> miette::Result<()> {
|
||||||
|
Loading…
Reference in New Issue
Block a user