Added the RecordIterator struct

This commit is contained in:
Nicola Belluti 2024-05-05 22:16:48 +02:00
parent e2d1f141d6
commit f0ac5fe766
4 changed files with 72 additions and 1 deletions

View File

@ -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;

View File

@ -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> {
RecordIterator::from(self)
}
}

View File

@ -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))]

64
src/record_iterator.rs Normal file
View File

@ -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<u8>,
sequence_number: u16,
record_count: u16,
total_records: u16,
}
impl<'a> RecordIterator<'a> {
pub fn from(r701: &'a mut R701) -> Result<Self> {
// 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::Item> {
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()
}
}