bmp_client/
client.rs

1use crate::error::*;
2
3use bmp_protocol::{
4    types::BmpMessage,
5    BmpDecoder
6};
7
8use tokio::{
9    net::TcpStream,
10    stream::StreamExt,
11};
12use tokio_util::codec::FramedRead;
13
14use std::time::{Duration, Instant};
15
16/// ## BmpClient
17///
18/// Holds the `TcpStream` and Decoder state
19///
20/// ```
21/// let client = BmpClient::new(tcp_stream)?;
22/// let decoded_message = client.recv()?;
23/// ```
24#[derive(Debug)]
25pub struct BmpClient {
26    connected: Instant,
27    inner: FramedRead<TcpStream, BmpDecoder>,
28    messages: usize,
29}
30
31impl BmpClient {
32    /// Instantiate a new client
33    pub fn new(stream: TcpStream) -> Self {
34        let inner = FramedRead::new(stream, BmpDecoder::new());
35
36        Self {
37            connected: Instant::now(),
38            inner,
39            messages: 0,
40        }
41    }
42
43    /// Returns a Future that will resolve to the next message
44    ///
45    /// Returns an error if the client disconnects or if there is an error decoding the message
46    pub async fn recv(&mut self) -> Option<Result<BmpMessage, Error>> {
47        self.inner.next().await
48            .and_then(|m| { self.messages += 1; Some(m) })
49            .map(|thing| thing.map_err(|e| e.into()))
50    }
51
52    /// Return a Duration representing how long this client has been connected
53    pub fn connected(&self) -> Duration {
54        self.connected.elapsed()
55    }
56
57    /// Return the number of messages received from this client during the active session
58    pub fn messages(&self) -> usize {
59        self.messages
60    }
61}