use std::iter::{Enumerate, Peekable};
use crate::{Grib2SubmessageIndex, ParseError, SectionInfo};
pub struct Submessage(
pub SectionInfo,
pub SectionInfo,
pub Option<SectionInfo>,
pub SectionInfo,
pub SectionInfo,
pub SectionInfo,
pub SectionInfo,
pub SectionInfo,
pub SectionInfo,
);
pub struct Grib2SubmessageStream<I>
where
I: Iterator,
{
iter: Grib2SubmessageValidator<I>,
sect0: SectionInfo,
sect1: SectionInfo,
sect2: Option<SectionInfo>,
sect3: SectionInfo,
}
impl<I> Grib2SubmessageStream<I>
where
I: Iterator,
{
pub fn new(iter: I) -> Self {
Self {
iter: Grib2SubmessageValidator::new(iter),
sect0: Default::default(),
sect1: Default::default(),
sect2: Default::default(),
sect3: Default::default(),
}
}
fn clear_message_cache(&mut self) {
self.sect0 = Default::default();
self.sect1 = Default::default();
self.sect2 = Default::default();
self.sect3 = Default::default();
}
}
impl<I> Iterator for Grib2SubmessageStream<I>
where
I: Iterator<Item = Result<SectionInfo, ParseError>>,
{
type Item = Result<(usize, usize, Submessage), ParseError>;
fn next(&mut self) -> Option<Self::Item> {
let mut sect4 = Default::default();
let mut sect5 = Default::default();
let mut sect6 = Default::default();
let mut sect7 = Default::default();
loop {
match self.iter.next()? {
Err(e) => return Some(Err(e)),
Ok((pos, message_count, submessage_count, s)) => match s.num {
0 => {
self.sect0 = s;
}
1 => {
self.sect1 = s;
}
2 => {
self.sect2 = Some(s);
}
3 => {
self.sect3 = s;
}
4 => {
sect4 = s;
}
5 => {
sect5 = s;
}
6 => {
sect6 = s;
}
7 => {
sect7 = s;
}
8 => {
let ret = Some(Ok((
message_count,
submessage_count,
Submessage(
self.sect0.clone(),
self.sect1.clone(),
self.sect2.clone(),
self.sect3.clone(),
sect4,
sect5,
sect6,
sect7,
s,
),
)));
if pos != 0 {
self.clear_message_cache();
}
return ret;
}
_ => unreachable!(),
},
}
}
}
}
pub(crate) struct Grib2SubmessageIndexStream<'cacher, I>
where
I: Iterator,
{
iter: Grib2SubmessageValidator<I>,
sect_cacher: Option<&'cacher mut Vec<SectionInfo>>,
sect0: usize,
sect1: usize,
sect2: Option<usize>,
sect3: usize,
}
impl<'cacher, I> Grib2SubmessageIndexStream<'cacher, I>
where
I: Iterator,
{
pub(crate) fn new(iter: I) -> Self {
Self {
iter: Grib2SubmessageValidator::new(iter),
sect_cacher: None,
sect0: Default::default(),
sect1: Default::default(),
sect2: Default::default(),
sect3: Default::default(),
}
}
pub(crate) fn with_cacher(mut self, cacher: &'cacher mut Vec<SectionInfo>) -> Self {
self.sect_cacher = Some(cacher);
self
}
fn cache_sect(&mut self, sect: SectionInfo) {
if let Some(cacher) = self.sect_cacher.as_mut() {
cacher.push(sect);
}
}
fn clear_message_cache(&mut self) {
self.sect0 = Default::default();
self.sect1 = Default::default();
self.sect2 = Default::default();
self.sect3 = Default::default();
}
}
impl<I> Iterator for Grib2SubmessageIndexStream<'_, I>
where
I: Iterator<Item = Result<SectionInfo, ParseError>>,
{
type Item = Result<Grib2SubmessageIndex, ParseError>;
fn next(&mut self) -> Option<Self::Item> {
let mut sect4 = Default::default();
let mut sect5 = Default::default();
let mut sect6 = Default::default();
let mut sect7 = Default::default();
loop {
match self.iter.next()? {
Err(e) => return Some(Err(e)),
Ok((pos, message_count, submessage_count, s)) => {
let num = s.num;
match num {
0 => {
self.cache_sect(s);
self.sect0 = pos;
}
1 => {
self.cache_sect(s);
self.sect1 = pos;
}
2 => {
self.cache_sect(s);
self.sect2 = Some(pos);
}
3 => {
self.cache_sect(s);
self.sect3 = pos;
}
4 => {
self.cache_sect(s);
sect4 = pos;
}
5 => {
self.cache_sect(s);
sect5 = pos;
}
6 => {
self.cache_sect(s);
sect6 = pos;
}
7 => {
self.cache_sect(s);
sect7 = pos;
}
8 => {
let ret = Some(Ok(Grib2SubmessageIndex::new(
(message_count, submessage_count),
(
self.sect0, self.sect1, self.sect2, self.sect3, sect4, sect5,
sect6, sect7, pos,
),
)));
if pos != 0 {
self.cache_sect(s);
self.clear_message_cache();
}
return ret;
}
_ => unreachable!(),
}
}
}
}
}
}
struct Grib2SubmessageValidator<I>
where
I: Iterator,
{
iter: Peekable<Enumerate<I>>,
pos: usize,
message_count: usize,
submessage_count: usize,
state: Grib2SubmessageValidatorState,
has_sect3: bool,
}
impl<I> Grib2SubmessageValidator<I>
where
I: Iterator,
{
pub fn new(iter: I) -> Self {
Grib2SubmessageValidator {
iter: iter.enumerate().peekable(),
pos: 0,
message_count: 0,
submessage_count: 0,
state: Grib2SubmessageValidatorState::StartOfMessage,
has_sect3: false,
}
}
#[inline]
fn reinitialize_message(&mut self) {
self.submessage_count = 0;
self.state = Grib2SubmessageValidatorState::StartOfMessage;
self.has_sect3 = false;
}
fn new_unexpected_end_of_data_err(
&mut self,
) -> Option<Result<(usize, usize, usize, SectionInfo), ParseError>> {
self.state = Grib2SubmessageValidatorState::EndOfStream;
Some(Err(ParseError::UnexpectedEndOfData(self.pos)))
}
fn new_invalid_section_order_err(
&mut self,
) -> Option<Result<(usize, usize, usize, SectionInfo), ParseError>> {
self.state = Grib2SubmessageValidatorState::EndOfStream;
Some(Err(ParseError::InvalidSectionOrder(self.pos)))
}
fn new_no_grid_definition_err(
&mut self,
) -> Option<Result<(usize, usize, usize, SectionInfo), ParseError>> {
self.state = Grib2SubmessageValidatorState::EndOfStream;
Some(Err(ParseError::NoGridDefinition(self.pos)))
}
fn wrap_parse_err(
&mut self,
e: ParseError,
) -> Option<Result<(usize, usize, usize, SectionInfo), ParseError>> {
self.state = Grib2SubmessageValidatorState::EndOfStream;
Some(Err(e))
}
}
impl<I> Grib2SubmessageValidator<I>
where
I: Iterator<Item = Result<SectionInfo, ParseError>>,
{
#[inline]
fn ensure_next_is_sect0(
&mut self,
) -> Option<Result<(usize, usize, usize, SectionInfo), ParseError>> {
match self.iter.next()? {
(pos, Ok(s)) => {
self.pos = pos;
if s.num == 0 {
self.state = Grib2SubmessageValidatorState::EndOfSect(0);
Some(Ok((self.pos, self.message_count, self.submessage_count, s)))
} else {
self.new_invalid_section_order_err()
}
}
(_, Err(e)) => self.wrap_parse_err(e),
}
}
#[inline]
fn ensure_next_is_sect_2_or_3_or_4(
&mut self,
) -> Option<Result<(usize, usize, usize, SectionInfo), ParseError>> {
match self.iter.next() {
Some((pos, Ok(s))) => {
self.pos = pos;
match s.num {
2 => {
self.state = Grib2SubmessageValidatorState::EndOfSect(2);
Some(Ok((self.pos, self.message_count, self.submessage_count, s)))
}
3 => {
self.state = Grib2SubmessageValidatorState::EndOfSect(3);
self.has_sect3 = true;
Some(Ok((self.pos, self.message_count, self.submessage_count, s)))
}
4 => {
if self.has_sect3 {
self.state = Grib2SubmessageValidatorState::EndOfSect(4);
Some(Ok((self.pos, self.message_count, self.submessage_count, s)))
} else {
self.new_no_grid_definition_err()
}
}
_ => self.new_invalid_section_order_err(),
}
}
Some((_, Err(e))) => self.wrap_parse_err(e),
None => self.new_unexpected_end_of_data_err(),
}
}
#[inline]
fn ensure_next_is_sect8(
&mut self,
) -> Option<Result<(usize, usize, usize, SectionInfo), ParseError>> {
match self.iter.peek() {
Some((_, Err(_))) => {
if let Some((_, Err(e))) = self.iter.next() {
self.wrap_parse_err(e)
} else {
unreachable!()
}
}
Some((_, Ok(SectionInfo { num: 8, .. }))) => {
let sect = if let Some((pos, Ok(s))) = self.iter.next() {
self.pos = pos;
s
} else {
unreachable!()
};
let ret = Some(Ok((
self.pos,
self.message_count,
self.submessage_count,
sect,
)));
self.message_count += 1;
self.reinitialize_message();
ret
}
Some((_, Ok(_))) => {
let ret = Some(Ok((
0,
self.message_count,
self.submessage_count,
SectionInfo::new_8(0),
)));
self.submessage_count += 1;
self.state = Grib2SubmessageValidatorState::StartOfSubmessage;
ret
}
None => self.new_unexpected_end_of_data_err(),
}
}
fn ensure_next_is_sect_num(
&mut self,
num: u8,
) -> Option<Result<(usize, usize, usize, SectionInfo), ParseError>> {
match self.iter.next() {
Some((pos, Ok(s))) => {
self.state = Grib2SubmessageValidatorState::EndOfSect(num);
self.pos = pos;
if s.num == num {
Some(Ok((self.pos, self.message_count, self.submessage_count, s)))
} else {
self.new_invalid_section_order_err()
}
}
Some((_, Err(e))) => self.wrap_parse_err(e),
None => self.new_unexpected_end_of_data_err(),
}
}
}
impl<I> Iterator for Grib2SubmessageValidator<I>
where
I: Iterator<Item = Result<SectionInfo, ParseError>>,
{
type Item = Result<(usize, usize, usize, SectionInfo), ParseError>;
fn next(&mut self) -> Option<Self::Item> {
match self.state {
Grib2SubmessageValidatorState::EndOfStream => None,
Grib2SubmessageValidatorState::StartOfMessage => self.ensure_next_is_sect0(),
Grib2SubmessageValidatorState::EndOfSect(0) => self.ensure_next_is_sect_num(1),
Grib2SubmessageValidatorState::EndOfSect(1) => self.ensure_next_is_sect_2_or_3_or_4(),
Grib2SubmessageValidatorState::StartOfSubmessage => {
self.ensure_next_is_sect_2_or_3_or_4()
}
Grib2SubmessageValidatorState::EndOfSect(2) => {
self.has_sect3 = true;
self.ensure_next_is_sect_num(3)
}
Grib2SubmessageValidatorState::EndOfSect(3) => self.ensure_next_is_sect_num(4),
Grib2SubmessageValidatorState::EndOfSect(4) => self.ensure_next_is_sect_num(5),
Grib2SubmessageValidatorState::EndOfSect(5) => self.ensure_next_is_sect_num(6),
Grib2SubmessageValidatorState::EndOfSect(6) => self.ensure_next_is_sect_num(7),
Grib2SubmessageValidatorState::EndOfSect(7) => self.ensure_next_is_sect8(),
Grib2SubmessageValidatorState::EndOfSect(_) => unreachable!(),
}
}
}
enum Grib2SubmessageValidatorState {
StartOfMessage,
StartOfSubmessage,
EndOfSect(u8),
EndOfStream,
}
#[cfg(test)]
mod tests {
use super::*;
fn new_sect_vec_with_dummy_offset(vec: Vec<u8>) -> Vec<Result<SectionInfo, ParseError>> {
vec.iter()
.enumerate()
.map(|(index, num)| {
Ok(SectionInfo {
num: *num,
offset: index,
..Default::default()
})
})
.collect::<Vec<_>>()
}
type SubmessageDigest = (
usize,
usize,
usize,
usize,
Option<usize>,
usize,
usize,
usize,
usize,
usize,
usize,
);
fn digest_submessage_iter_item(item: (usize, usize, Submessage)) -> SubmessageDigest {
let (i1, i2, submessage) = item;
(
i1,
i2,
submessage.0.offset,
submessage.1.offset,
submessage.2.map(|r| r.offset),
submessage.3.offset,
submessage.4.offset,
submessage.5.offset,
submessage.6.offset,
submessage.7.offset,
submessage.8.offset,
)
}
fn digest_submessage_index_iter_item(item: Grib2SubmessageIndex) -> SubmessageDigest {
let (message_index, submessage_index) = item.message_index();
(
message_index,
submessage_index,
item.0,
item.1,
item.2,
item.3,
item.4,
item.5,
item.6,
item.7,
item.8,
)
}
#[test]
fn submessage_stream_from_1_message() {
let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 2, 3, 4, 5, 6, 7, 8]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![Ok((0, 0, 0, 1, Some(2), 3, 4, 5, 6, 7, 8))],
);
}
#[test]
fn submessage_stream_from_multiple_messages() {
let sects = new_sect_vec_with_dummy_offset(vec![
0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8,
]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![
Ok((0, 0, 0, 1, Some(2), 3, 4, 5, 6, 7, 8)),
Ok((1, 0, 9, 10, Some(11), 12, 13, 14, 15, 16, 17))
],
);
}
#[test]
fn submessage_stream_empty() {
let sects = new_sect_vec_with_dummy_offset(vec![]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
Vec::new(),
);
}
#[test]
fn submessage_stream_from_multiple_messages_without_sect2() {
let sects =
new_sect_vec_with_dummy_offset(vec![0, 1, 3, 4, 5, 6, 7, 8, 0, 1, 3, 4, 5, 6, 7, 8]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![
Ok((0, 0, 0, 1, None, 2, 3, 4, 5, 6, 7)),
Ok((1, 0, 8, 9, None, 10, 11, 12, 13, 14, 15))
],
);
}
#[test]
fn submessage_stream_from_1_message_with_multiple_submessages_from_sect2() {
let sects =
new_sect_vec_with_dummy_offset(vec![0, 1, 2, 3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 7, 8]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![
Ok((0, 0, 0, 1, Some(2), 3, 4, 5, 6, 7, 0)),
Ok((0, 1, 0, 1, Some(8), 9, 10, 11, 12, 13, 14))
],
);
}
#[test]
fn submessage_stream_from_1_message_with_multiple_submessages_from_sect2_with_sect2_toggled() {
let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 7, 8]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![
Ok((0, 0, 0, 1, None, 2, 3, 4, 5, 6, 0)),
Ok((0, 1, 0, 1, Some(7), 8, 9, 10, 11, 12, 13))
],
);
}
#[test]
fn submessage_stream_from_1_message_with_multiple_submessages_from_sect3() {
let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 2, 3, 4, 5, 6, 7, 3, 4, 5, 6, 7, 8]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![
Ok((0, 0, 0, 1, Some(2), 3, 4, 5, 6, 7, 0)),
Ok((0, 1, 0, 1, Some(2), 8, 9, 10, 11, 12, 13))
],
);
}
#[test]
fn submessage_stream_from_1_message_with_multiple_submessages_from_sect3_without_sect2() {
let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 3, 4, 5, 6, 7, 3, 4, 5, 6, 7, 8]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![
Ok((0, 0, 0, 1, None, 2, 3, 4, 5, 6, 0)),
Ok((0, 1, 0, 1, None, 7, 8, 9, 10, 11, 12))
],
);
}
#[test]
fn submessage_stream_from_1_message_with_multiple_submessages_from_sect4() {
let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7, 8]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![
Ok((0, 0, 0, 1, Some(2), 3, 4, 5, 6, 7, 0)),
Ok((0, 1, 0, 1, Some(2), 3, 8, 9, 10, 11, 12))
],
);
}
#[test]
fn submessage_stream_from_1_message_with_multiple_submessages_from_sect4_without_sect2() {
let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 3, 4, 5, 6, 7, 4, 5, 6, 7, 8]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![
Ok((0, 0, 0, 1, None, 2, 3, 4, 5, 6, 0)),
Ok((0, 1, 0, 1, None, 2, 7, 8, 9, 10, 11))
],
);
}
#[test]
fn submessage_stream_from_multiple_messages_and_submessages_with_sect2_toggled() {
let sects = new_sect_vec_with_dummy_offset(vec![
0, 1, 2, 3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 7, 8, 0, 1, 3, 4, 5, 6, 7, 8,
]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![
Ok((0, 0, 0, 1, Some(2), 3, 4, 5, 6, 7, 0)),
Ok((0, 1, 0, 1, Some(8), 9, 10, 11, 12, 13, 14)),
Ok((1, 0, 15, 16, None, 17, 18, 19, 20, 21, 22))
],
);
}
#[test]
fn submessage_stream_ending_with_sect0() {
let sects = new_sect_vec_with_dummy_offset(vec![0]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![Err(ParseError::UnexpectedEndOfData(0)),],
);
}
#[test]
fn submessage_stream_ending_with_sect1() {
let sects = new_sect_vec_with_dummy_offset(vec![0, 1]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![Err(ParseError::UnexpectedEndOfData(1)),],
);
}
#[test]
fn submessage_stream_ending_with_sect2() {
let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 2]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![Err(ParseError::UnexpectedEndOfData(2)),],
);
}
#[test]
fn submessage_stream_ending_with_sect3() {
let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 2, 3]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![Err(ParseError::UnexpectedEndOfData(3)),],
);
}
#[test]
fn submessage_stream_ending_with_sect3_without_sect2() {
let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 3]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![Err(ParseError::UnexpectedEndOfData(2)),],
);
}
#[test]
fn submessage_stream_ending_with_sect4() {
let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 2, 3, 4]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![Err(ParseError::UnexpectedEndOfData(4)),],
);
}
#[test]
fn submessage_stream_ending_with_sect4_without_sect2() {
let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 3, 4]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![Err(ParseError::UnexpectedEndOfData(3)),],
);
}
#[test]
fn submessage_stream_ending_with_sect7() {
let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 2, 3, 4, 5, 6, 7]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![Err(ParseError::UnexpectedEndOfData(7)),],
);
}
#[test]
fn submessage_stream_from_submessage_without_sect3() {
let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 4, 5, 6, 7, 8]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![Err(ParseError::NoGridDefinition(2)),],
);
}
#[test]
fn submessage_stream_wrongly_ordered_from_the_beginning() {
let sects = new_sect_vec_with_dummy_offset(vec![1, 0, 2, 3, 4, 5, 6, 7, 8]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![Err(ParseError::InvalidSectionOrder(0)),],
);
}
#[test]
fn submessage_stream_wrongly_ordered_after_sect0() {
let sects = new_sect_vec_with_dummy_offset(vec![0, 2, 1, 3, 4, 5, 6, 7, 8]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![Err(ParseError::InvalidSectionOrder(1)),],
);
}
#[test]
fn submessage_stream_wrongly_ordered_after_sect1() {
let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 5, 2, 3, 4, 6, 7, 8]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![Err(ParseError::InvalidSectionOrder(2)),],
);
}
#[test]
fn submessage_stream_wrongly_ordered_after_sect2() {
let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 2, 4, 3, 5, 6, 7, 8]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![Err(ParseError::InvalidSectionOrder(3)),],
);
}
#[test]
fn submessage_stream_wrongly_ordered_after_sect3() {
let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 2, 3, 5, 4, 6, 7, 8]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![Err(ParseError::InvalidSectionOrder(4)),],
);
}
#[test]
fn submessage_stream_wrongly_ordered_after_sect3_without_sect2() {
let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 3, 5, 4, 6, 7, 8]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![Err(ParseError::InvalidSectionOrder(3)),],
);
}
#[test]
fn submessage_stream_wrongly_ordered_after_sect4() {
let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 2, 3, 4, 6, 5, 7, 8]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![Err(ParseError::InvalidSectionOrder(5)),],
);
}
#[test]
fn submessage_stream_wrongly_ordered_after_sect4_without_sect2() {
let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 3, 4, 6, 5, 7, 8]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![Err(ParseError::InvalidSectionOrder(4)),],
);
}
#[test]
fn submessage_stream_wrongly_ordered_after_sect5() {
let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 2, 3, 4, 5, 7, 6, 8]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![Err(ParseError::InvalidSectionOrder(6)),],
);
}
#[test]
fn submessage_stream_wrongly_ordered_after_sect6() {
let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 2, 3, 4, 5, 6, 8, 7]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![Err(ParseError::InvalidSectionOrder(7)),],
);
}
#[test]
fn submessage_stream_with_2nd_submessage_wrongly_ordered_from_the_beginning() {
let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 2, 3, 4, 5, 6, 7, 0, 8]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![
Ok((0, 0, 0, 1, Some(2), 3, 4, 5, 6, 7, 0)),
Err(ParseError::InvalidSectionOrder(8)),
],
);
}
#[test]
fn submessage_stream_with_2nd_submessage_wrongly_ordered_after_sect2() {
let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 2, 3, 4, 5, 6, 7, 2, 8]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![
Ok((0, 0, 0, 1, Some(2), 3, 4, 5, 6, 7, 0)),
Err(ParseError::InvalidSectionOrder(9)),
],
);
}
#[test]
fn submessage_stream_with_2nd_submessage_wrongly_ordered_after_sect4_without_sect2_and_sect3() {
let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 2, 3, 4, 5, 6, 7, 4, 8]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![
Ok((0, 0, 0, 1, Some(2), 3, 4, 5, 6, 7, 0)),
Err(ParseError::InvalidSectionOrder(9)),
],
);
}
fn new_sect_vec_with_dummy_offset_and_errors(
vec: Vec<Result<u8, ParseError>>,
) -> Vec<Result<SectionInfo, ParseError>> {
vec.iter()
.enumerate()
.map(|(index, result)| {
result.clone().map(|num| SectionInfo {
num,
offset: index,
..Default::default()
})
})
.collect::<Vec<_>>()
}
#[test]
fn submessage_stream_with_sect_stream_error_at_sect0_in_1st_submessage() {
let sects = new_sect_vec_with_dummy_offset_and_errors(vec![Err(ParseError::ReadError(
"failed to fill whole buffer".to_owned(),
))]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![Err(ParseError::ReadError(
"failed to fill whole buffer".to_owned()
)),],
);
}
#[test]
fn submessage_stream_with_sect_stream_error_at_sect1_in_1st_submessage() {
let sects = new_sect_vec_with_dummy_offset_and_errors(vec![
Ok(0),
Err(ParseError::ReadError(
"failed to fill whole buffer".to_owned(),
)),
]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![Err(ParseError::ReadError(
"failed to fill whole buffer".to_owned()
)),],
);
}
#[test]
fn submessage_stream_with_sect_stream_error_at_sect2_in_1st_submessage() {
let sects = new_sect_vec_with_dummy_offset_and_errors(vec![
Ok(0),
Ok(1),
Err(ParseError::ReadError(
"failed to fill whole buffer".to_owned(),
)),
]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![Err(ParseError::ReadError(
"failed to fill whole buffer".to_owned()
)),],
);
}
#[test]
fn submessage_stream_with_sect_stream_error_at_sect3_in_1st_submessage() {
let sects = new_sect_vec_with_dummy_offset_and_errors(vec![
Ok(0),
Ok(1),
Ok(2),
Err(ParseError::ReadError(
"failed to fill whole buffer".to_owned(),
)),
]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![Err(ParseError::ReadError(
"failed to fill whole buffer".to_owned()
)),],
);
}
#[test]
fn submessage_stream_with_sect_stream_error_at_sect4_in_1st_submessage() {
let sects = new_sect_vec_with_dummy_offset_and_errors(vec![
Ok(0),
Ok(1),
Ok(2),
Ok(3),
Err(ParseError::ReadError(
"failed to fill whole buffer".to_owned(),
)),
]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![Err(ParseError::ReadError(
"failed to fill whole buffer".to_owned()
)),],
);
}
#[test]
fn submessage_stream_with_sect_stream_error_at_sect5_in_1st_submessage() {
let sects = new_sect_vec_with_dummy_offset_and_errors(vec![
Ok(0),
Ok(1),
Ok(2),
Ok(3),
Ok(4),
Err(ParseError::ReadError(
"failed to fill whole buffer".to_owned(),
)),
]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![Err(ParseError::ReadError(
"failed to fill whole buffer".to_owned()
)),],
);
}
#[test]
fn submessage_stream_with_sect_stream_error_at_sect6_in_1st_submessage() {
let sects = new_sect_vec_with_dummy_offset_and_errors(vec![
Ok(0),
Ok(1),
Ok(2),
Ok(3),
Ok(4),
Ok(5),
Err(ParseError::ReadError(
"failed to fill whole buffer".to_owned(),
)),
]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![Err(ParseError::ReadError(
"failed to fill whole buffer".to_owned()
)),],
);
}
#[test]
fn submessage_stream_with_sect_stream_error_at_sect7_in_1st_submessage() {
let sects = new_sect_vec_with_dummy_offset_and_errors(vec![
Ok(0),
Ok(1),
Ok(2),
Ok(3),
Ok(4),
Ok(5),
Ok(6),
Err(ParseError::ReadError(
"failed to fill whole buffer".to_owned(),
)),
]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![Err(ParseError::ReadError(
"failed to fill whole buffer".to_owned()
)),],
);
}
#[test]
fn submessage_stream_with_sect_stream_error_at_sect8_in_1st_submessage() {
let sects = new_sect_vec_with_dummy_offset_and_errors(vec![
Ok(0),
Ok(1),
Ok(2),
Ok(3),
Ok(4),
Ok(5),
Ok(6),
Ok(7),
Err(ParseError::ReadError(
"failed to fill whole buffer".to_owned(),
)),
]);
assert_eq!(
Grib2SubmessageStream::new(sects.into_iter())
.map(|result| result.map(digest_submessage_iter_item))
.collect::<Vec<_>>(),
vec![Err(ParseError::ReadError(
"failed to fill whole buffer".to_owned()
)),],
);
}
#[test]
fn submessage_index_stream_from_multiple_messages_and_submessages_with_sect2_toggled() {
let sect_nums = vec![
0, 1, 2, 3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 7, 8, 0, 1, 3, 4, 5, 6, 7, 8,
];
let sects = new_sect_vec_with_dummy_offset(sect_nums.clone());
let mut cacher = Vec::new();
let stream = Grib2SubmessageIndexStream::new(sects.into_iter()).with_cacher(&mut cacher);
assert_eq!(
stream
.map(|result| result.map(digest_submessage_index_iter_item))
.collect::<Vec<_>>(),
vec![
Ok((0, 0, 0, 1, Some(2), 3, 4, 5, 6, 7, 0)),
Ok((0, 1, 0, 1, Some(8), 9, 10, 11, 12, 13, 14)),
Ok((1, 0, 15, 16, None, 17, 18, 19, 20, 21, 22))
],
);
assert_eq!(cacher.iter().map(|s| s.num).collect::<Vec<_>>(), sect_nums,);
}
}