Skip to main content

Crate ntex_codec

Crate ntex_codec 

Source
Expand description

Traits for encoding and decoding frames.

A codec turns a byte stream into frames and back. Decoder splits incoming bytes into frames, Encoder serializes outgoing frames. The ntex-io crate drives them: Io::recv() and IoRef::decode() run the decoder on the read buffer, Io::send() and IoRef::encode() run the encoder on the write buffer, and the ntex-dispatcher crate uses both to connect a stream to a service.

Both traits take &self, since a codec is shared between the reading and writing sides. A codec that keeps state between calls, such as a parser position or negotiated settings, has to use interior mutability, e.g. Cell or RefCell.

§Example

A codec for newline-terminated lines:

use std::io;

use ntex_bytes::{BytePages, Bytes, BytesMut};
use ntex_codec::{Decoder, Encoder};

struct LineCodec;

impl Decoder for LineCodec {
    type Item = Bytes;
    type Error = io::Error;

    fn decode(&self, src: &mut BytesMut) -> Result<Option<Bytes>, io::Error> {
        match src.iter().position(|b| *b == b'\n') {
            // consume the line and its terminator
            Some(n) => Ok(Some(src.split_to(n + 1).slice(..n))),
            // incomplete line, wait for more input
            None => Ok(None),
        }
    }

    fn decode_eof(&self, src: &mut BytesMut) -> Result<Option<Bytes>, io::Error> {
        match self.decode(src)? {
            Some(line) => Ok(Some(line)),
            // the last line has no terminator
            None if !src.is_empty() => Ok(Some(src.split_to(src.len()))),
            None => Ok(None),
        }
    }
}

impl Encoder for LineCodec {
    type Item = Bytes;
    type Error = io::Error;

    fn encode(&self, item: Bytes, dst: &mut BytePages) -> Result<(), io::Error> {
        if item.contains(&b'\n') {
            return Err(io::Error::new(io::ErrorKind::InvalidInput, "newline in line"));
        }
        dst.append(item);
        dst.extend_from_slice(b"\n");
        Ok(())
    }
}

let mut src = BytesMut::from(&b"one\ntwo"[..]);
assert_eq!(LineCodec.decode(&mut src).unwrap().unwrap(), "one");
assert!(LineCodec.decode(&mut src).unwrap().is_none());
assert_eq!(LineCodec.decode_eof(&mut src).unwrap().unwrap(), "two");
assert!(LineCodec.decode_eof(&mut src).unwrap().is_none());

Structs§

BytesCodec
Passes bytes through unchanged.

Traits§

Decoder
Splits a byte stream into frames.
Encoder
Serializes frames into bytes.