candid_client 0.3.2

A library to handle client connections to a CANdid server
Documentation
use crate::Frame;

use std::io::prelude::*;
use std::io::{BufReader, BufWriter};
use std::net::{TcpStream, ToSocketAddrs};

use byteorder::{NetworkEndian, ReadBytesExt, WriteBytesExt};

/// A connection to a CANdid server. Simply contains a `TcpStream` wrapped by a
/// `BufReader`. Handles the communication with a server by reading one can
/// frame at a time from a TCP stream.
pub struct CandidConnection {
    read_stream: BufReader<TcpStream>,
    write_stream: BufWriter<TcpStream>,
}

impl CandidConnection {
    /// Creates a new CandidConnection with a server designated at `addr`
    pub fn new<A: ToSocketAddrs>(addr: A) -> Result<CandidConnection, std::io::Error> {
        let stream = TcpStream::connect(addr)?;

        Ok(CandidConnection {
            read_stream: BufReader::new(stream.try_clone().unwrap()),
            write_stream: BufWriter::new(stream.try_clone().unwrap()),
        })
    }

    /// Reads a single CAN frame sent by the server.
    pub fn read_frame(&mut self) -> Result<Frame, std::io::Error> {
        let id = self.read_stream.read_u32::<NetworkEndian>()?;

        let mut data = [0 as u8; 8];
        self.read_stream.read_exact(&mut data)?;

        Ok(Frame::new(id, data))
    }

    /// Sends a frame to the server
    pub fn write_frame(&mut self, frame: Frame) -> Result<(), std::io::Error> {
        self.write_stream.write_u32::<NetworkEndian>(frame.id)?;
        self.write_stream.write(&frame.data)?;
        self.write_stream.flush().unwrap();
        Ok(())
    }

    /// Unwraps the internal `BufReader` and returns the raw `TcpStream`.
    ///
    /// Note that any leftover data in the buffer will be lost.
    pub fn into_raw_stream(self) -> TcpStream {
        self.read_stream.into_inner()
    }

    /// Unwraps this `CandidConnection` and returns the underlying `BufReader`.
    pub fn into_buffer(self) -> BufReader<TcpStream> {
        self.read_stream
    }
}