From f0ac5fe7660883cb92c192b175666b4fa03c6281 Mon Sep 17 00:00:00 2001 From: Nicola Belluti Date: Sun, 5 May 2024 22:16:48 +0200 Subject: [PATCH] Added the RecordIterator struct --- src/lib.rs | 2 ++ src/r701.rs | 5 ++++ src/record.rs | 2 +- src/record_iterator.rs | 64 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 src/record_iterator.rs diff --git a/src/lib.rs b/src/lib.rs index f50a48f..f4568f7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,6 @@ mod r701; mod record; +mod record_iterator; pub use r701::R701; pub use record::{Clock, Record}; +pub use record_iterator::RecordIterator; diff --git a/src/r701.rs b/src/r701.rs index 4d2cad0..1700dff 100644 --- a/src/r701.rs +++ b/src/r701.rs @@ -1,3 +1,4 @@ +use crate::RecordIterator; use std::io::{BufRead, BufReader, Error, ErrorKind::InvalidData, Result, Write}; use std::net::{TcpStream, ToSocketAddrs}; @@ -142,4 +143,8 @@ impl R701 { // Return only the payload bits as a vector Ok(response[12..response.len() - 2].to_vec()) } + + pub fn iter(&mut self) -> Result { + RecordIterator::from(self) + } } diff --git a/src/record.rs b/src/record.rs index 79ae136..84cac40 100644 --- a/src/record.rs +++ b/src/record.rs @@ -1,6 +1,6 @@ +use chrono::{DateTime, Local, TimeZone}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; -use chrono::{DateTime, Local, TimeZone}; #[derive(Debug, Clone, Copy, Default, Eq, PartialEq, Ord, PartialOrd, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] diff --git a/src/record_iterator.rs b/src/record_iterator.rs new file mode 100644 index 0000000..d9d5efa --- /dev/null +++ b/src/record_iterator.rs @@ -0,0 +1,64 @@ +use crate::{Record, R701}; +use std::io::Result; + +#[derive(Debug)] +pub struct RecordIterator<'a> { + r701: &'a mut R701, + input_buffer: Vec, + sequence_number: u16, + record_count: u16, + total_records: u16, +} + +impl<'a> RecordIterator<'a> { + pub fn from(r701: &'a mut R701) -> Result { + // Ping the endpoint + r701.ping()?; + + // Get the total number of records + let total_records = r701.get_total_record_count()?; + + // Return a new Iterator + Ok(Self { + r701, + input_buffer: Vec::new(), + record_count: 0, + sequence_number: 0, + total_records, + }) + } +} + +impl<'a> Iterator for RecordIterator<'a> { + type Item = Record; + + fn next(&mut self) -> Option { + self.record_count += 1; + + // If we exceeded the total number of records, return None + if self.record_count > self.total_records { + return None; + } + + // If the buffer is empty, make another request to the endpoint asking + // for more data + if self.input_buffer.len() < 12 { + let bytes = &mut self + .r701 + .get_record_bytes(self.total_records, self.sequence_number) + .ok()?; + + self.input_buffer.append(bytes); + self.sequence_number += 1; + } + + // If the record bytes are set to `ff ff ff ff ff ff ff ff ff ff ff ff`, + // return None + if self.input_buffer[..12] == [0xff_u8; 12] { + return None; + } + + // Return a new Record + self.input_buffer.drain(..12).as_slice().try_into().ok() + } +}