mirror of
https://github.com/tokio-rs/tokio.git
synced 2025-09-25 12:00:35 +00:00

Strategy was to - copy the old codec code that was temporarily being stashed in `tokio-io` - modify all the type signatures to use Pin, as literal a translation as possible - fix up the tests likewise This is intended just to get things compiling and passing tests. Beyond that there is surely lots of refactoring that can be done to make things more idiomatic. The docs are unchanged. Closes #1189
105 lines
2.5 KiB
Rust
105 lines
2.5 KiB
Rust
#![deny(warnings, rust_2018_idioms)]
|
|
|
|
use std::io::{self, Read};
|
|
use std::pin::Pin;
|
|
use std::task::{Context, Poll};
|
|
|
|
use tokio_codec::{Decoder, Encoder, Framed, FramedParts};
|
|
use tokio_current_thread::block_on_all;
|
|
use tokio_io::AsyncRead;
|
|
|
|
use bytes::{Buf, BufMut, BytesMut, IntoBuf};
|
|
use futures::prelude::{FutureExt, StreamExt};
|
|
|
|
const INITIAL_CAPACITY: usize = 8 * 1024;
|
|
|
|
/// Encode and decode u32 values.
|
|
struct U32Codec;
|
|
|
|
impl Decoder for U32Codec {
|
|
type Item = u32;
|
|
type Error = io::Error;
|
|
|
|
fn decode(&mut self, buf: &mut BytesMut) -> io::Result<Option<u32>> {
|
|
if buf.len() < 4 {
|
|
return Ok(None);
|
|
}
|
|
|
|
let n = buf.split_to(4).into_buf().get_u32_be();
|
|
Ok(Some(n))
|
|
}
|
|
}
|
|
|
|
impl Encoder for U32Codec {
|
|
type Item = u32;
|
|
type Error = io::Error;
|
|
|
|
fn encode(&mut self, item: u32, dst: &mut BytesMut) -> io::Result<()> {
|
|
// Reserve space
|
|
dst.reserve(4);
|
|
dst.put_u32_be(item);
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
/// This value should never be used
|
|
struct DontReadIntoThis;
|
|
|
|
impl Read for DontReadIntoThis {
|
|
fn read(&mut self, _: &mut [u8]) -> io::Result<usize> {
|
|
Err(io::Error::new(
|
|
io::ErrorKind::Other,
|
|
"Read into something you weren't supposed to.",
|
|
))
|
|
}
|
|
}
|
|
|
|
impl AsyncRead for DontReadIntoThis {
|
|
fn poll_read(
|
|
self: Pin<&mut Self>,
|
|
_cx: &mut Context<'_>,
|
|
_buf: &mut [u8],
|
|
) -> Poll<io::Result<usize>> {
|
|
unreachable!()
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn can_read_from_existing_buf() {
|
|
let mut parts = FramedParts::new(DontReadIntoThis, U32Codec);
|
|
parts.read_buf = vec![0, 0, 0, 42].into();
|
|
|
|
let framed = Framed::from_parts(parts);
|
|
|
|
let num = block_on_all(
|
|
framed
|
|
.into_future()
|
|
.map(|(first_num, _)| first_num.unwrap()),
|
|
)
|
|
.unwrap();
|
|
|
|
assert_eq!(num, 42);
|
|
}
|
|
|
|
#[test]
|
|
fn external_buf_grows_to_init() {
|
|
let mut parts = FramedParts::new(DontReadIntoThis, U32Codec);
|
|
parts.read_buf = vec![0, 0, 0, 42].into();
|
|
|
|
let framed = Framed::from_parts(parts);
|
|
let FramedParts { read_buf, .. } = framed.into_parts();
|
|
|
|
assert_eq!(read_buf.capacity(), INITIAL_CAPACITY);
|
|
}
|
|
|
|
#[test]
|
|
fn external_buf_does_not_shrink() {
|
|
let mut parts = FramedParts::new(DontReadIntoThis, U32Codec);
|
|
parts.read_buf = vec![0; INITIAL_CAPACITY * 2].into();
|
|
|
|
let framed = Framed::from_parts(parts);
|
|
let FramedParts { read_buf, .. } = framed.into_parts();
|
|
|
|
assert_eq!(read_buf.capacity(), INITIAL_CAPACITY * 2);
|
|
}
|