ib_tws_core 0.2.0

Core utilities for interacting with Interactive Broker's TWS API
Documentation
use std::{error, fmt, io, io::Cursor};

use bytes::{Buf, BytesMut};

use super::constants::MAX_MSG_LENGTH;

pub const FRAME_HEAD_LEN: usize = 4;

#[derive(Debug, Clone, Copy)]
pub enum FrameState {
    Head,
    Data(usize),
}

pub fn decode_head(src: &mut BytesMut) -> io::Result<Option<usize>> {
    if src.len() < FRAME_HEAD_LEN {
        return Ok(None);
    }

    let n = Cursor::new(&*src).get_u32() as usize;

    if n > MAX_MSG_LENGTH {
        return Err(io::Error::new(
            io::ErrorKind::InvalidData,
            FrameTooBigError { current_size: n },
        ));
    }

    let _ = src.split_to(FRAME_HEAD_LEN);

    src.reserve(n);

    Ok(Some(n))
}

pub fn decode_data(n: usize, src: &mut BytesMut) -> io::Result<Option<BytesMut>> {
    if src.len() < n {
        return Ok(None);
    }

    Ok(Some(src.split_to(n)))
}

#[derive(Debug, Clone)]
pub struct FrameTooBigError {
    pub current_size: usize,
}

impl fmt::Display for FrameTooBigError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "frame size:{} large than max:{}",
            self.current_size, MAX_MSG_LENGTH
        )
    }
}

impl error::Error for FrameTooBigError {
    fn description(&self) -> &str {
        "frame size too large than max size"
    }

    fn cause(&self) -> Option<&dyn error::Error> {
        None
    }
}