1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
use std::io::prelude::*;
use std::io::{BufReader, Lines};
use std::net::{TcpStream, ToSocketAddrs};

pub struct CandidConnection {
    stream: BufReader<TcpStream>,
}

/// 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.
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 {
            stream: BufReader::new(stream),
        })
    }

    /// Reads a single CAN frame sent by the server.
    pub fn read_frame(&mut self) -> Result<String, std::io::Error> {
        let mut buffer = String::new();
        self.stream.read_line(&mut buffer)?;
        Ok(buffer)
    }

    /// 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.stream.into_inner()
    }

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

    /// Returns an iterator over the raw lines form the underlying `TcpStream`.
    pub fn lines(self) -> Lines<BufReader<TcpStream>> {
        self.stream.lines()
    }
}