2019-10-22 10:13:49 -07:00
|
|
|
use crate::codec::decoder::Decoder;
|
|
|
|
|
use crate::codec::encoder::Encoder;
|
|
|
|
|
|
2019-02-21 11:56:15 -08:00
|
|
|
use bytes::{BufMut, Bytes, BytesMut};
|
2018-06-04 22:36:06 -05:00
|
|
|
use std::io;
|
|
|
|
|
|
2020-02-01 23:04:58 +01:00
|
|
|
/// A simple [`Decoder`] and [`Encoder`] implementation that just ships bytes around.
|
|
|
|
|
///
|
|
|
|
|
/// [`Decoder`]: crate::codec::Decoder
|
|
|
|
|
/// [`Encoder`]: crate::codec::Encoder
|
|
|
|
|
///
|
|
|
|
|
/// # Example
|
|
|
|
|
///
|
|
|
|
|
/// Turn an [`AsyncRead`] into a stream of `Result<`[`BytesMut`]`, `[`Error`]`>`.
|
|
|
|
|
///
|
|
|
|
|
/// [`AsyncRead`]: tokio::io::AsyncRead
|
|
|
|
|
/// [`BytesMut`]: bytes::BytesMut
|
|
|
|
|
/// [`Error`]: std::io::Error
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// # mod hidden {
|
|
|
|
|
/// # #[allow(unused_imports)]
|
|
|
|
|
/// use tokio::fs::File;
|
|
|
|
|
/// # }
|
|
|
|
|
/// use tokio::io::AsyncRead;
|
|
|
|
|
/// use tokio_util::codec::{FramedRead, BytesCodec};
|
|
|
|
|
///
|
|
|
|
|
/// # enum File {}
|
|
|
|
|
/// # impl File {
|
|
|
|
|
/// # async fn open(_name: &str) -> Result<impl AsyncRead, std::io::Error> {
|
|
|
|
|
/// # use std::io::Cursor;
|
|
|
|
|
/// # Ok(Cursor::new(vec![0, 1, 2, 3, 4, 5]))
|
|
|
|
|
/// # }
|
|
|
|
|
/// # }
|
|
|
|
|
/// #
|
2020-10-12 13:44:54 -04:00
|
|
|
/// # #[tokio::main(flavor = "current_thread")]
|
2020-02-01 23:04:58 +01:00
|
|
|
/// # async fn main() -> Result<(), std::io::Error> {
|
|
|
|
|
/// let my_async_read = File::open("filename.txt").await?;
|
|
|
|
|
/// let my_stream_of_bytes = FramedRead::new(my_async_read, BytesCodec::new());
|
|
|
|
|
/// # Ok(())
|
|
|
|
|
/// # }
|
|
|
|
|
/// ```
|
|
|
|
|
///
|
2019-07-26 03:47:14 +09:00
|
|
|
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]
|
2020-12-23 22:48:33 +09:00
|
|
|
#[non_exhaustive]
|
|
|
|
|
pub struct BytesCodec;
|
2018-06-04 22:36:06 -05:00
|
|
|
|
|
|
|
|
impl BytesCodec {
|
|
|
|
|
/// Creates a new `BytesCodec` for shipping around raw bytes.
|
2019-02-21 11:56:15 -08:00
|
|
|
pub fn new() -> BytesCodec {
|
2020-12-23 22:48:33 +09:00
|
|
|
BytesCodec
|
2019-02-21 11:56:15 -08:00
|
|
|
}
|
2018-06-04 22:36:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Decoder for BytesCodec {
|
|
|
|
|
type Item = BytesMut;
|
|
|
|
|
type Error = io::Error;
|
|
|
|
|
|
|
|
|
|
fn decode(&mut self, buf: &mut BytesMut) -> Result<Option<BytesMut>, io::Error> {
|
2019-07-26 03:47:14 +09:00
|
|
|
if !buf.is_empty() {
|
2018-06-04 22:36:06 -05:00
|
|
|
let len = buf.len();
|
|
|
|
|
Ok(Some(buf.split_to(len)))
|
|
|
|
|
} else {
|
|
|
|
|
Ok(None)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-04 15:54:41 -05:00
|
|
|
impl Encoder<Bytes> for BytesCodec {
|
2018-06-04 22:36:06 -05:00
|
|
|
type Error = io::Error;
|
|
|
|
|
|
|
|
|
|
fn encode(&mut self, data: Bytes, buf: &mut BytesMut) -> Result<(), io::Error> {
|
|
|
|
|
buf.reserve(data.len());
|
|
|
|
|
buf.put(data);
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
}
|