grib/
parser.rs

1use std::iter::{Enumerate, Peekable};
2
3use crate::{Grib2SubmessageIndex, ParseError, SectionInfo};
4
5pub struct Submessage(
6    pub SectionInfo,
7    pub SectionInfo,
8    pub Option<SectionInfo>,
9    pub SectionInfo,
10    pub SectionInfo,
11    pub SectionInfo,
12    pub SectionInfo,
13    pub SectionInfo,
14    pub SectionInfo,
15);
16
17///
18/// # Example
19/// In all but the last `Submessage` in a message, the `offset` of Section 8 is
20/// set to 0 since this parser only reads required submessages from the
21/// beginning of the file.
22///
23/// ```
24/// use grib::{
25///     Grib2SectionStream, Grib2SubmessageStream, Indicator, SectionBody, SectionInfo,
26///     SeekableGrib2Reader,
27/// };
28///
29/// fn main() -> Result<(), Box<dyn std::error::Error>> {
30///     let f = std::fs::File::open(
31///         "testdata/icon_global_icosahedral_single-level_2021112018_000_TOT_PREC.grib2",
32///     )?;
33///     let f = std::io::BufReader::new(f);
34///     let grib2_reader = SeekableGrib2Reader::new(f);
35///
36///     let sect_stream = Grib2SectionStream::new(grib2_reader);
37///     let mut parser = Grib2SubmessageStream::new(sect_stream);
38///
39///     let first = parser.next();
40///     assert!(first.is_some());
41///
42///     let first = first.unwrap();
43///     assert!(first.is_ok());
44///
45///     let first = first.unwrap();
46///     let (message_index, submessage_index, submessage) = first;
47///     assert_eq!(message_index, 0);
48///     assert_eq!(submessage_index, 0);
49///     assert_eq!(
50///         (
51///             submessage.0.offset,
52///             submessage.1.offset,
53///             submessage.2.map(|s| s.offset),
54///             submessage.3.offset,
55///             submessage.4.offset,
56///             submessage.5.offset,
57///             submessage.6.offset,
58///             submessage.7.offset,
59///             submessage.8.offset
60///         ),
61///         (0, 16, Some(37), 64, 99, 157, 178, 184, 189)
62///     );
63///
64///     let second = parser.next();
65///     assert!(second.is_none());
66///     Ok(())
67/// }
68/// ```
69pub struct Grib2SubmessageStream<I>
70where
71    I: Iterator,
72{
73    iter: Grib2SubmessageValidator<I>,
74    sect0: SectionInfo,
75    sect1: SectionInfo,
76    sect2: Option<SectionInfo>,
77    sect3: SectionInfo,
78}
79
80impl<I> Grib2SubmessageStream<I>
81where
82    I: Iterator,
83{
84    /// # Example
85    /// ```
86    /// use grib::{Grib2SectionStream, Grib2SubmessageStream, SeekableGrib2Reader};
87    ///
88    /// fn main() -> Result<(), Box<dyn std::error::Error>> {
89    ///     let f = std::fs::File::open(
90    ///         "testdata/icon_global_icosahedral_single-level_2021112018_000_TOT_PREC.grib2",
91    ///     )?;
92    ///     let mut f = std::io::BufReader::new(f);
93    ///     let grib2_reader = SeekableGrib2Reader::new(f);
94    ///     let sect_stream = Grib2SectionStream::new(grib2_reader);
95    ///     let _parser = Grib2SubmessageStream::new(sect_stream);
96    ///     Ok(())
97    /// }
98    /// ```
99    pub fn new(iter: I) -> Self {
100        Self {
101            iter: Grib2SubmessageValidator::new(iter),
102            sect0: Default::default(),
103            sect1: Default::default(),
104            sect2: Default::default(),
105            sect3: Default::default(),
106        }
107    }
108
109    fn clear_message_cache(&mut self) {
110        self.sect0 = Default::default();
111        self.sect1 = Default::default();
112        self.sect2 = Default::default();
113        self.sect3 = Default::default();
114    }
115}
116
117impl<I> Iterator for Grib2SubmessageStream<I>
118where
119    I: Iterator<Item = Result<SectionInfo, ParseError>>,
120{
121    type Item = Result<(usize, usize, Submessage), ParseError>;
122
123    fn next(&mut self) -> Option<Self::Item> {
124        let mut sect4 = Default::default();
125        let mut sect5 = Default::default();
126        let mut sect6 = Default::default();
127        let mut sect7 = Default::default();
128        loop {
129            match self.iter.next()? {
130                Err(e) => return Some(Err(e)),
131                Ok((pos, message_count, submessage_count, s)) => match s.num {
132                    0 => {
133                        self.sect0 = s;
134                    }
135                    1 => {
136                        self.sect1 = s;
137                    }
138                    2 => {
139                        self.sect2 = Some(s);
140                    }
141                    3 => {
142                        self.sect3 = s;
143                    }
144                    4 => {
145                        sect4 = s;
146                    }
147                    5 => {
148                        sect5 = s;
149                    }
150                    6 => {
151                        sect6 = s;
152                    }
153                    7 => {
154                        sect7 = s;
155                    }
156                    8 => {
157                        let ret = Some(Ok((
158                            message_count,
159                            submessage_count,
160                            Submessage(
161                                self.sect0.clone(),
162                                self.sect1.clone(),
163                                self.sect2.clone(),
164                                self.sect3.clone(),
165                                sect4,
166                                sect5,
167                                sect6,
168                                sect7,
169                                s,
170                            ),
171                        )));
172
173                        // if pos is 0, it is dummy
174                        if pos != 0 {
175                            self.clear_message_cache();
176                        }
177                        return ret;
178                    }
179                    _ => unreachable!(),
180                },
181            }
182        }
183    }
184}
185
186pub(crate) struct Grib2SubmessageIndexStream<'cacher, I>
187where
188    I: Iterator,
189{
190    iter: Grib2SubmessageValidator<I>,
191    sect_cacher: Option<&'cacher mut Vec<SectionInfo>>,
192    sect0: usize,
193    sect1: usize,
194    sect2: Option<usize>,
195    sect3: usize,
196}
197
198impl<'cacher, I> Grib2SubmessageIndexStream<'cacher, I>
199where
200    I: Iterator,
201{
202    pub(crate) fn new(iter: I) -> Self {
203        Self {
204            iter: Grib2SubmessageValidator::new(iter),
205            sect_cacher: None,
206            sect0: Default::default(),
207            sect1: Default::default(),
208            sect2: Default::default(),
209            sect3: Default::default(),
210        }
211    }
212
213    pub(crate) fn with_cacher(mut self, cacher: &'cacher mut Vec<SectionInfo>) -> Self {
214        self.sect_cacher = Some(cacher);
215        self
216    }
217
218    fn cache_sect(&mut self, sect: SectionInfo) {
219        if let Some(cacher) = self.sect_cacher.as_mut() {
220            cacher.push(sect);
221        }
222    }
223
224    fn clear_message_cache(&mut self) {
225        self.sect0 = Default::default();
226        self.sect1 = Default::default();
227        self.sect2 = Default::default();
228        self.sect3 = Default::default();
229    }
230}
231
232impl<I> Iterator for Grib2SubmessageIndexStream<'_, I>
233where
234    I: Iterator<Item = Result<SectionInfo, ParseError>>,
235{
236    type Item = Result<Grib2SubmessageIndex, ParseError>;
237
238    fn next(&mut self) -> Option<Self::Item> {
239        let mut sect4 = Default::default();
240        let mut sect5 = Default::default();
241        let mut sect6 = Default::default();
242        let mut sect7 = Default::default();
243        loop {
244            match self.iter.next()? {
245                Err(e) => return Some(Err(e)),
246                Ok((pos, message_count, submessage_count, s)) => {
247                    let num = s.num;
248                    match num {
249                        0 => {
250                            self.cache_sect(s);
251                            self.sect0 = pos;
252                        }
253                        1 => {
254                            self.cache_sect(s);
255                            self.sect1 = pos;
256                        }
257                        2 => {
258                            self.cache_sect(s);
259                            self.sect2 = Some(pos);
260                        }
261                        3 => {
262                            self.cache_sect(s);
263                            self.sect3 = pos;
264                        }
265                        4 => {
266                            self.cache_sect(s);
267                            sect4 = pos;
268                        }
269                        5 => {
270                            self.cache_sect(s);
271                            sect5 = pos;
272                        }
273                        6 => {
274                            self.cache_sect(s);
275                            sect6 = pos;
276                        }
277                        7 => {
278                            self.cache_sect(s);
279                            sect7 = pos;
280                        }
281                        8 => {
282                            let ret = Some(Ok(Grib2SubmessageIndex::new(
283                                (message_count, submessage_count),
284                                (
285                                    self.sect0, self.sect1, self.sect2, self.sect3, sect4, sect5,
286                                    sect6, sect7, pos,
287                                ),
288                            )));
289
290                            // if pos is 0, it is dummy
291                            if pos != 0 {
292                                self.cache_sect(s);
293                                self.clear_message_cache();
294                            }
295                            return ret;
296                        }
297                        _ => unreachable!(),
298                    }
299                }
300            }
301        }
302    }
303}
304
305struct Grib2SubmessageValidator<I>
306where
307    I: Iterator,
308{
309    iter: Peekable<Enumerate<I>>,
310    pos: usize,
311    message_count: usize,
312    submessage_count: usize,
313    state: Grib2SubmessageValidatorState,
314    has_sect3: bool,
315}
316
317impl<I> Grib2SubmessageValidator<I>
318where
319    I: Iterator,
320{
321    pub fn new(iter: I) -> Self {
322        Grib2SubmessageValidator {
323            iter: iter.enumerate().peekable(),
324            pos: 0,
325            message_count: 0,
326            submessage_count: 0,
327            state: Grib2SubmessageValidatorState::StartOfMessage,
328            has_sect3: false,
329        }
330    }
331
332    #[inline]
333    fn reinitialize_message(&mut self) {
334        self.submessage_count = 0;
335        self.state = Grib2SubmessageValidatorState::StartOfMessage;
336        self.has_sect3 = false;
337    }
338
339    fn new_unexpected_end_of_data_err(
340        &mut self,
341    ) -> Option<Result<(usize, usize, usize, SectionInfo), ParseError>> {
342        self.state = Grib2SubmessageValidatorState::EndOfStream;
343        Some(Err(ParseError::UnexpectedEndOfData(self.pos)))
344    }
345
346    fn new_invalid_section_order_err(
347        &mut self,
348    ) -> Option<Result<(usize, usize, usize, SectionInfo), ParseError>> {
349        self.state = Grib2SubmessageValidatorState::EndOfStream;
350        Some(Err(ParseError::InvalidSectionOrder(self.pos)))
351    }
352
353    fn new_no_grid_definition_err(
354        &mut self,
355    ) -> Option<Result<(usize, usize, usize, SectionInfo), ParseError>> {
356        self.state = Grib2SubmessageValidatorState::EndOfStream;
357        Some(Err(ParseError::NoGridDefinition(self.pos)))
358    }
359
360    fn wrap_parse_err(
361        &mut self,
362        e: ParseError,
363    ) -> Option<Result<(usize, usize, usize, SectionInfo), ParseError>> {
364        self.state = Grib2SubmessageValidatorState::EndOfStream;
365        Some(Err(e))
366    }
367}
368
369impl<I> Grib2SubmessageValidator<I>
370where
371    I: Iterator<Item = Result<SectionInfo, ParseError>>,
372{
373    #[inline]
374    fn ensure_next_is_sect0(
375        &mut self,
376    ) -> Option<Result<(usize, usize, usize, SectionInfo), ParseError>> {
377        match self.iter.next()? {
378            (pos, Ok(s)) => {
379                self.pos = pos;
380                if s.num == 0 {
381                    self.state = Grib2SubmessageValidatorState::EndOfSect(0);
382                    Some(Ok((self.pos, self.message_count, self.submessage_count, s)))
383                } else {
384                    self.new_invalid_section_order_err()
385                }
386            }
387            (_, Err(e)) => self.wrap_parse_err(e),
388        }
389    }
390
391    #[inline]
392    fn ensure_next_is_sect_2_or_3_or_4(
393        &mut self,
394    ) -> Option<Result<(usize, usize, usize, SectionInfo), ParseError>> {
395        match self.iter.next() {
396            Some((pos, Ok(s))) => {
397                self.pos = pos;
398                match s.num {
399                    2 => {
400                        self.state = Grib2SubmessageValidatorState::EndOfSect(2);
401                        Some(Ok((self.pos, self.message_count, self.submessage_count, s)))
402                    }
403                    3 => {
404                        self.state = Grib2SubmessageValidatorState::EndOfSect(3);
405                        self.has_sect3 = true;
406                        Some(Ok((self.pos, self.message_count, self.submessage_count, s)))
407                    }
408                    4 => {
409                        if self.has_sect3 {
410                            self.state = Grib2SubmessageValidatorState::EndOfSect(4);
411                            Some(Ok((self.pos, self.message_count, self.submessage_count, s)))
412                        } else {
413                            self.new_no_grid_definition_err()
414                        }
415                    }
416                    _ => self.new_invalid_section_order_err(),
417                }
418            }
419            Some((_, Err(e))) => self.wrap_parse_err(e),
420            None => self.new_unexpected_end_of_data_err(),
421        }
422    }
423
424    #[inline]
425    fn ensure_next_is_sect8(
426        &mut self,
427    ) -> Option<Result<(usize, usize, usize, SectionInfo), ParseError>> {
428        match self.iter.peek() {
429            Some((_, Err(_))) => {
430                if let Some((_, Err(e))) = self.iter.next() {
431                    self.wrap_parse_err(e)
432                } else {
433                    unreachable!()
434                }
435            }
436            Some((_, Ok(SectionInfo { num: 8, .. }))) => {
437                let sect = if let Some((pos, Ok(s))) = self.iter.next() {
438                    self.pos = pos;
439                    s
440                } else {
441                    unreachable!()
442                };
443                let ret = Some(Ok((
444                    self.pos,
445                    self.message_count,
446                    self.submessage_count,
447                    sect,
448                )));
449
450                self.message_count += 1;
451                self.reinitialize_message();
452                ret
453            }
454            Some((_, Ok(_))) => {
455                // return dummy Section 8
456                let ret = Some(Ok((
457                    0,
458                    self.message_count,
459                    self.submessage_count,
460                    SectionInfo::new_8(0),
461                )));
462                self.submessage_count += 1;
463                self.state = Grib2SubmessageValidatorState::StartOfSubmessage;
464                ret
465            }
466            None => self.new_unexpected_end_of_data_err(),
467        }
468    }
469
470    fn ensure_next_is_sect_num(
471        &mut self,
472        num: u8,
473    ) -> Option<Result<(usize, usize, usize, SectionInfo), ParseError>> {
474        match self.iter.next() {
475            Some((pos, Ok(s))) => {
476                self.state = Grib2SubmessageValidatorState::EndOfSect(num);
477                self.pos = pos;
478                if s.num == num {
479                    Some(Ok((self.pos, self.message_count, self.submessage_count, s)))
480                } else {
481                    self.new_invalid_section_order_err()
482                }
483            }
484            Some((_, Err(e))) => self.wrap_parse_err(e),
485            None => self.new_unexpected_end_of_data_err(),
486        }
487    }
488}
489
490impl<I> Iterator for Grib2SubmessageValidator<I>
491where
492    I: Iterator<Item = Result<SectionInfo, ParseError>>,
493{
494    type Item = Result<(usize, usize, usize, SectionInfo), ParseError>;
495
496    fn next(&mut self) -> Option<Self::Item> {
497        match self.state {
498            Grib2SubmessageValidatorState::EndOfStream => None,
499            Grib2SubmessageValidatorState::StartOfMessage => self.ensure_next_is_sect0(),
500            Grib2SubmessageValidatorState::EndOfSect(0) => self.ensure_next_is_sect_num(1),
501            Grib2SubmessageValidatorState::EndOfSect(1) => self.ensure_next_is_sect_2_or_3_or_4(),
502            Grib2SubmessageValidatorState::StartOfSubmessage => {
503                self.ensure_next_is_sect_2_or_3_or_4()
504            }
505            Grib2SubmessageValidatorState::EndOfSect(2) => {
506                self.has_sect3 = true;
507                self.ensure_next_is_sect_num(3)
508            }
509            Grib2SubmessageValidatorState::EndOfSect(3) => self.ensure_next_is_sect_num(4),
510            Grib2SubmessageValidatorState::EndOfSect(4) => self.ensure_next_is_sect_num(5),
511            Grib2SubmessageValidatorState::EndOfSect(5) => self.ensure_next_is_sect_num(6),
512            Grib2SubmessageValidatorState::EndOfSect(6) => self.ensure_next_is_sect_num(7),
513            Grib2SubmessageValidatorState::EndOfSect(7) => self.ensure_next_is_sect8(),
514            Grib2SubmessageValidatorState::EndOfSect(_) => unreachable!(),
515        }
516    }
517}
518
519enum Grib2SubmessageValidatorState {
520    StartOfMessage,
521    StartOfSubmessage,
522    EndOfSect(u8),
523    EndOfStream,
524}
525
526#[cfg(test)]
527mod tests {
528    use super::*;
529
530    fn new_sect_vec_with_dummy_offset(vec: Vec<u8>) -> Vec<Result<SectionInfo, ParseError>> {
531        vec.iter()
532            .enumerate()
533            .map(|(index, num)| {
534                Ok(SectionInfo {
535                    num: *num,
536                    offset: index,
537                    ..Default::default()
538                })
539            })
540            .collect::<Vec<_>>()
541    }
542
543    type SubmessageDigest = (
544        usize,
545        usize,
546        usize,
547        usize,
548        Option<usize>,
549        usize,
550        usize,
551        usize,
552        usize,
553        usize,
554        usize,
555    );
556
557    fn digest_submessage_iter_item(item: (usize, usize, Submessage)) -> SubmessageDigest {
558        let (i1, i2, submessage) = item;
559        (
560            i1,
561            i2,
562            submessage.0.offset,
563            submessage.1.offset,
564            submessage.2.map(|r| r.offset),
565            submessage.3.offset,
566            submessage.4.offset,
567            submessage.5.offset,
568            submessage.6.offset,
569            submessage.7.offset,
570            submessage.8.offset,
571        )
572    }
573
574    fn digest_submessage_index_iter_item(item: Grib2SubmessageIndex) -> SubmessageDigest {
575        let (message_index, submessage_index) = item.message_index();
576        (
577            message_index,
578            submessage_index,
579            item.0,
580            item.1,
581            item.2,
582            item.3,
583            item.4,
584            item.5,
585            item.6,
586            item.7,
587            item.8,
588        )
589    }
590
591    #[test]
592    fn submessage_stream_from_1_message() {
593        let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 2, 3, 4, 5, 6, 7, 8]);
594
595        assert_eq!(
596            Grib2SubmessageStream::new(sects.into_iter())
597                .map(|result| result.map(digest_submessage_iter_item))
598                .collect::<Vec<_>>(),
599            vec![Ok((0, 0, 0, 1, Some(2), 3, 4, 5, 6, 7, 8))],
600        );
601    }
602
603    #[test]
604    fn submessage_stream_from_multiple_messages() {
605        let sects = new_sect_vec_with_dummy_offset(vec![
606            0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8,
607        ]);
608
609        assert_eq!(
610            Grib2SubmessageStream::new(sects.into_iter())
611                .map(|result| result.map(digest_submessage_iter_item))
612                .collect::<Vec<_>>(),
613            vec![
614                Ok((0, 0, 0, 1, Some(2), 3, 4, 5, 6, 7, 8)),
615                Ok((1, 0, 9, 10, Some(11), 12, 13, 14, 15, 16, 17))
616            ],
617        );
618    }
619
620    #[test]
621    fn submessage_stream_empty() {
622        let sects = new_sect_vec_with_dummy_offset(vec![]);
623
624        assert_eq!(
625            Grib2SubmessageStream::new(sects.into_iter())
626                .map(|result| result.map(digest_submessage_iter_item))
627                .collect::<Vec<_>>(),
628            Vec::new(),
629        );
630    }
631
632    #[test]
633    fn submessage_stream_from_multiple_messages_without_sect2() {
634        let sects =
635            new_sect_vec_with_dummy_offset(vec![0, 1, 3, 4, 5, 6, 7, 8, 0, 1, 3, 4, 5, 6, 7, 8]);
636
637        assert_eq!(
638            Grib2SubmessageStream::new(sects.into_iter())
639                .map(|result| result.map(digest_submessage_iter_item))
640                .collect::<Vec<_>>(),
641            vec![
642                Ok((0, 0, 0, 1, None, 2, 3, 4, 5, 6, 7)),
643                Ok((1, 0, 8, 9, None, 10, 11, 12, 13, 14, 15))
644            ],
645        );
646    }
647
648    #[test]
649    fn submessage_stream_from_1_message_with_multiple_submessages_from_sect2() {
650        let sects =
651            new_sect_vec_with_dummy_offset(vec![0, 1, 2, 3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 7, 8]);
652
653        assert_eq!(
654            Grib2SubmessageStream::new(sects.into_iter())
655                .map(|result| result.map(digest_submessage_iter_item))
656                .collect::<Vec<_>>(),
657            vec![
658                Ok((0, 0, 0, 1, Some(2), 3, 4, 5, 6, 7, 0)),
659                Ok((0, 1, 0, 1, Some(8), 9, 10, 11, 12, 13, 14))
660            ],
661        );
662    }
663
664    #[test]
665    fn submessage_stream_from_1_message_with_multiple_submessages_from_sect2_with_sect2_toggled() {
666        let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 7, 8]);
667
668        assert_eq!(
669            Grib2SubmessageStream::new(sects.into_iter())
670                .map(|result| result.map(digest_submessage_iter_item))
671                .collect::<Vec<_>>(),
672            vec![
673                Ok((0, 0, 0, 1, None, 2, 3, 4, 5, 6, 0)),
674                Ok((0, 1, 0, 1, Some(7), 8, 9, 10, 11, 12, 13))
675            ],
676        );
677    }
678
679    #[test]
680    fn submessage_stream_from_1_message_with_multiple_submessages_from_sect3() {
681        let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 2, 3, 4, 5, 6, 7, 3, 4, 5, 6, 7, 8]);
682
683        assert_eq!(
684            Grib2SubmessageStream::new(sects.into_iter())
685                .map(|result| result.map(digest_submessage_iter_item))
686                .collect::<Vec<_>>(),
687            vec![
688                Ok((0, 0, 0, 1, Some(2), 3, 4, 5, 6, 7, 0)),
689                Ok((0, 1, 0, 1, Some(2), 8, 9, 10, 11, 12, 13))
690            ],
691        );
692    }
693
694    #[test]
695    fn submessage_stream_from_1_message_with_multiple_submessages_from_sect3_without_sect2() {
696        let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 3, 4, 5, 6, 7, 3, 4, 5, 6, 7, 8]);
697
698        assert_eq!(
699            Grib2SubmessageStream::new(sects.into_iter())
700                .map(|result| result.map(digest_submessage_iter_item))
701                .collect::<Vec<_>>(),
702            vec![
703                Ok((0, 0, 0, 1, None, 2, 3, 4, 5, 6, 0)),
704                Ok((0, 1, 0, 1, None, 7, 8, 9, 10, 11, 12))
705            ],
706        );
707    }
708    #[test]
709    fn submessage_stream_from_1_message_with_multiple_submessages_from_sect4() {
710        let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7, 8]);
711
712        assert_eq!(
713            Grib2SubmessageStream::new(sects.into_iter())
714                .map(|result| result.map(digest_submessage_iter_item))
715                .collect::<Vec<_>>(),
716            vec![
717                Ok((0, 0, 0, 1, Some(2), 3, 4, 5, 6, 7, 0)),
718                Ok((0, 1, 0, 1, Some(2), 3, 8, 9, 10, 11, 12))
719            ],
720        );
721    }
722
723    #[test]
724    fn submessage_stream_from_1_message_with_multiple_submessages_from_sect4_without_sect2() {
725        let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 3, 4, 5, 6, 7, 4, 5, 6, 7, 8]);
726
727        assert_eq!(
728            Grib2SubmessageStream::new(sects.into_iter())
729                .map(|result| result.map(digest_submessage_iter_item))
730                .collect::<Vec<_>>(),
731            vec![
732                Ok((0, 0, 0, 1, None, 2, 3, 4, 5, 6, 0)),
733                Ok((0, 1, 0, 1, None, 2, 7, 8, 9, 10, 11))
734            ],
735        );
736    }
737
738    #[test]
739    fn submessage_stream_from_multiple_messages_and_submessages_with_sect2_toggled() {
740        // testing cache of submessage_count and sect2
741        let sects = new_sect_vec_with_dummy_offset(vec![
742            0, 1, 2, 3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 7, 8, 0, 1, 3, 4, 5, 6, 7, 8,
743        ]);
744
745        assert_eq!(
746            Grib2SubmessageStream::new(sects.into_iter())
747                .map(|result| result.map(digest_submessage_iter_item))
748                .collect::<Vec<_>>(),
749            vec![
750                Ok((0, 0, 0, 1, Some(2), 3, 4, 5, 6, 7, 0)),
751                Ok((0, 1, 0, 1, Some(8), 9, 10, 11, 12, 13, 14)),
752                Ok((1, 0, 15, 16, None, 17, 18, 19, 20, 21, 22))
753            ],
754        );
755    }
756
757    #[test]
758    fn submessage_stream_ending_with_sect0() {
759        let sects = new_sect_vec_with_dummy_offset(vec![0]);
760
761        assert_eq!(
762            Grib2SubmessageStream::new(sects.into_iter())
763                .map(|result| result.map(digest_submessage_iter_item))
764                .collect::<Vec<_>>(),
765            vec![Err(ParseError::UnexpectedEndOfData(0)),],
766        );
767    }
768
769    #[test]
770    fn submessage_stream_ending_with_sect1() {
771        let sects = new_sect_vec_with_dummy_offset(vec![0, 1]);
772
773        assert_eq!(
774            Grib2SubmessageStream::new(sects.into_iter())
775                .map(|result| result.map(digest_submessage_iter_item))
776                .collect::<Vec<_>>(),
777            vec![Err(ParseError::UnexpectedEndOfData(1)),],
778        );
779    }
780
781    #[test]
782    fn submessage_stream_ending_with_sect2() {
783        let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 2]);
784
785        assert_eq!(
786            Grib2SubmessageStream::new(sects.into_iter())
787                .map(|result| result.map(digest_submessage_iter_item))
788                .collect::<Vec<_>>(),
789            vec![Err(ParseError::UnexpectedEndOfData(2)),],
790        );
791    }
792
793    #[test]
794    fn submessage_stream_ending_with_sect3() {
795        let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 2, 3]);
796
797        assert_eq!(
798            Grib2SubmessageStream::new(sects.into_iter())
799                .map(|result| result.map(digest_submessage_iter_item))
800                .collect::<Vec<_>>(),
801            vec![Err(ParseError::UnexpectedEndOfData(3)),],
802        );
803    }
804
805    #[test]
806    fn submessage_stream_ending_with_sect3_without_sect2() {
807        let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 3]);
808
809        assert_eq!(
810            Grib2SubmessageStream::new(sects.into_iter())
811                .map(|result| result.map(digest_submessage_iter_item))
812                .collect::<Vec<_>>(),
813            vec![Err(ParseError::UnexpectedEndOfData(2)),],
814        );
815    }
816
817    #[test]
818    fn submessage_stream_ending_with_sect4() {
819        let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 2, 3, 4]);
820
821        assert_eq!(
822            Grib2SubmessageStream::new(sects.into_iter())
823                .map(|result| result.map(digest_submessage_iter_item))
824                .collect::<Vec<_>>(),
825            vec![Err(ParseError::UnexpectedEndOfData(4)),],
826        );
827    }
828
829    #[test]
830    fn submessage_stream_ending_with_sect4_without_sect2() {
831        let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 3, 4]);
832
833        assert_eq!(
834            Grib2SubmessageStream::new(sects.into_iter())
835                .map(|result| result.map(digest_submessage_iter_item))
836                .collect::<Vec<_>>(),
837            vec![Err(ParseError::UnexpectedEndOfData(3)),],
838        );
839    }
840
841    #[test]
842    fn submessage_stream_ending_with_sect7() {
843        let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 2, 3, 4, 5, 6, 7]);
844
845        assert_eq!(
846            Grib2SubmessageStream::new(sects.into_iter())
847                .map(|result| result.map(digest_submessage_iter_item))
848                .collect::<Vec<_>>(),
849            vec![Err(ParseError::UnexpectedEndOfData(7)),],
850        );
851    }
852
853    #[test]
854    fn submessage_stream_from_submessage_without_sect3() {
855        let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 4, 5, 6, 7, 8]);
856
857        assert_eq!(
858            Grib2SubmessageStream::new(sects.into_iter())
859                .map(|result| result.map(digest_submessage_iter_item))
860                .collect::<Vec<_>>(),
861            vec![Err(ParseError::NoGridDefinition(2)),],
862        );
863    }
864
865    #[test]
866    fn submessage_stream_wrongly_ordered_from_the_beginning() {
867        let sects = new_sect_vec_with_dummy_offset(vec![1, 0, 2, 3, 4, 5, 6, 7, 8]);
868
869        assert_eq!(
870            Grib2SubmessageStream::new(sects.into_iter())
871                .map(|result| result.map(digest_submessage_iter_item))
872                .collect::<Vec<_>>(),
873            vec![Err(ParseError::InvalidSectionOrder(0)),],
874        );
875    }
876
877    #[test]
878    fn submessage_stream_wrongly_ordered_after_sect0() {
879        let sects = new_sect_vec_with_dummy_offset(vec![0, 2, 1, 3, 4, 5, 6, 7, 8]);
880
881        assert_eq!(
882            Grib2SubmessageStream::new(sects.into_iter())
883                .map(|result| result.map(digest_submessage_iter_item))
884                .collect::<Vec<_>>(),
885            vec![Err(ParseError::InvalidSectionOrder(1)),],
886        );
887    }
888
889    #[test]
890    fn submessage_stream_wrongly_ordered_after_sect1() {
891        let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 5, 2, 3, 4, 6, 7, 8]);
892
893        assert_eq!(
894            Grib2SubmessageStream::new(sects.into_iter())
895                .map(|result| result.map(digest_submessage_iter_item))
896                .collect::<Vec<_>>(),
897            vec![Err(ParseError::InvalidSectionOrder(2)),],
898        );
899    }
900
901    #[test]
902    fn submessage_stream_wrongly_ordered_after_sect2() {
903        let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 2, 4, 3, 5, 6, 7, 8]);
904
905        assert_eq!(
906            Grib2SubmessageStream::new(sects.into_iter())
907                .map(|result| result.map(digest_submessage_iter_item))
908                .collect::<Vec<_>>(),
909            vec![Err(ParseError::InvalidSectionOrder(3)),],
910        );
911    }
912
913    #[test]
914    fn submessage_stream_wrongly_ordered_after_sect3() {
915        let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 2, 3, 5, 4, 6, 7, 8]);
916
917        assert_eq!(
918            Grib2SubmessageStream::new(sects.into_iter())
919                .map(|result| result.map(digest_submessage_iter_item))
920                .collect::<Vec<_>>(),
921            vec![Err(ParseError::InvalidSectionOrder(4)),],
922        );
923    }
924
925    #[test]
926    fn submessage_stream_wrongly_ordered_after_sect3_without_sect2() {
927        let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 3, 5, 4, 6, 7, 8]);
928
929        assert_eq!(
930            Grib2SubmessageStream::new(sects.into_iter())
931                .map(|result| result.map(digest_submessage_iter_item))
932                .collect::<Vec<_>>(),
933            vec![Err(ParseError::InvalidSectionOrder(3)),],
934        );
935    }
936
937    #[test]
938    fn submessage_stream_wrongly_ordered_after_sect4() {
939        let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 2, 3, 4, 6, 5, 7, 8]);
940
941        assert_eq!(
942            Grib2SubmessageStream::new(sects.into_iter())
943                .map(|result| result.map(digest_submessage_iter_item))
944                .collect::<Vec<_>>(),
945            vec![Err(ParseError::InvalidSectionOrder(5)),],
946        );
947    }
948
949    #[test]
950    fn submessage_stream_wrongly_ordered_after_sect4_without_sect2() {
951        let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 3, 4, 6, 5, 7, 8]);
952
953        assert_eq!(
954            Grib2SubmessageStream::new(sects.into_iter())
955                .map(|result| result.map(digest_submessage_iter_item))
956                .collect::<Vec<_>>(),
957            vec![Err(ParseError::InvalidSectionOrder(4)),],
958        );
959    }
960
961    #[test]
962    fn submessage_stream_wrongly_ordered_after_sect5() {
963        let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 2, 3, 4, 5, 7, 6, 8]);
964
965        assert_eq!(
966            Grib2SubmessageStream::new(sects.into_iter())
967                .map(|result| result.map(digest_submessage_iter_item))
968                .collect::<Vec<_>>(),
969            vec![Err(ParseError::InvalidSectionOrder(6)),],
970        );
971    }
972
973    #[test]
974    fn submessage_stream_wrongly_ordered_after_sect6() {
975        let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 2, 3, 4, 5, 6, 8, 7]);
976
977        assert_eq!(
978            Grib2SubmessageStream::new(sects.into_iter())
979                .map(|result| result.map(digest_submessage_iter_item))
980                .collect::<Vec<_>>(),
981            vec![Err(ParseError::InvalidSectionOrder(7)),],
982        );
983    }
984
985    #[test]
986    fn submessage_stream_with_2nd_submessage_wrongly_ordered_from_the_beginning() {
987        let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 2, 3, 4, 5, 6, 7, 0, 8]);
988
989        assert_eq!(
990            Grib2SubmessageStream::new(sects.into_iter())
991                .map(|result| result.map(digest_submessage_iter_item))
992                .collect::<Vec<_>>(),
993            vec![
994                Ok((0, 0, 0, 1, Some(2), 3, 4, 5, 6, 7, 0)),
995                Err(ParseError::InvalidSectionOrder(8)),
996            ],
997        );
998    }
999
1000    #[test]
1001    fn submessage_stream_with_2nd_submessage_wrongly_ordered_after_sect2() {
1002        let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 2, 3, 4, 5, 6, 7, 2, 8]);
1003
1004        assert_eq!(
1005            Grib2SubmessageStream::new(sects.into_iter())
1006                .map(|result| result.map(digest_submessage_iter_item))
1007                .collect::<Vec<_>>(),
1008            vec![
1009                Ok((0, 0, 0, 1, Some(2), 3, 4, 5, 6, 7, 0)),
1010                Err(ParseError::InvalidSectionOrder(9)),
1011            ],
1012        );
1013    }
1014
1015    #[test]
1016    fn submessage_stream_with_2nd_submessage_wrongly_ordered_after_sect4_without_sect2_and_sect3() {
1017        let sects = new_sect_vec_with_dummy_offset(vec![0, 1, 2, 3, 4, 5, 6, 7, 4, 8]);
1018
1019        assert_eq!(
1020            Grib2SubmessageStream::new(sects.into_iter())
1021                .map(|result| result.map(digest_submessage_iter_item))
1022                .collect::<Vec<_>>(),
1023            vec![
1024                Ok((0, 0, 0, 1, Some(2), 3, 4, 5, 6, 7, 0)),
1025                Err(ParseError::InvalidSectionOrder(9)),
1026            ],
1027        );
1028    }
1029
1030    fn new_sect_vec_with_dummy_offset_and_errors(
1031        vec: Vec<Result<u8, ParseError>>,
1032    ) -> Vec<Result<SectionInfo, ParseError>> {
1033        vec.iter()
1034            .enumerate()
1035            .map(|(index, result)| {
1036                result.clone().map(|num| SectionInfo {
1037                    num,
1038                    offset: index,
1039                    ..Default::default()
1040                })
1041            })
1042            .collect::<Vec<_>>()
1043    }
1044
1045    #[test]
1046    fn submessage_stream_with_sect_stream_error_at_sect0_in_1st_submessage() {
1047        let sects = new_sect_vec_with_dummy_offset_and_errors(vec![Err(ParseError::ReadError(
1048            "failed to fill whole buffer".to_owned(),
1049        ))]);
1050
1051        assert_eq!(
1052            Grib2SubmessageStream::new(sects.into_iter())
1053                .map(|result| result.map(digest_submessage_iter_item))
1054                .collect::<Vec<_>>(),
1055            vec![Err(ParseError::ReadError(
1056                "failed to fill whole buffer".to_owned()
1057            )),],
1058        );
1059    }
1060
1061    #[test]
1062    fn submessage_stream_with_sect_stream_error_at_sect1_in_1st_submessage() {
1063        let sects = new_sect_vec_with_dummy_offset_and_errors(vec![
1064            Ok(0),
1065            Err(ParseError::ReadError(
1066                "failed to fill whole buffer".to_owned(),
1067            )),
1068        ]);
1069
1070        assert_eq!(
1071            Grib2SubmessageStream::new(sects.into_iter())
1072                .map(|result| result.map(digest_submessage_iter_item))
1073                .collect::<Vec<_>>(),
1074            vec![Err(ParseError::ReadError(
1075                "failed to fill whole buffer".to_owned()
1076            )),],
1077        );
1078    }
1079
1080    #[test]
1081    fn submessage_stream_with_sect_stream_error_at_sect2_in_1st_submessage() {
1082        let sects = new_sect_vec_with_dummy_offset_and_errors(vec![
1083            Ok(0),
1084            Ok(1),
1085            Err(ParseError::ReadError(
1086                "failed to fill whole buffer".to_owned(),
1087            )),
1088        ]);
1089
1090        assert_eq!(
1091            Grib2SubmessageStream::new(sects.into_iter())
1092                .map(|result| result.map(digest_submessage_iter_item))
1093                .collect::<Vec<_>>(),
1094            vec![Err(ParseError::ReadError(
1095                "failed to fill whole buffer".to_owned()
1096            )),],
1097        );
1098    }
1099
1100    #[test]
1101    fn submessage_stream_with_sect_stream_error_at_sect3_in_1st_submessage() {
1102        let sects = new_sect_vec_with_dummy_offset_and_errors(vec![
1103            Ok(0),
1104            Ok(1),
1105            Ok(2),
1106            Err(ParseError::ReadError(
1107                "failed to fill whole buffer".to_owned(),
1108            )),
1109        ]);
1110
1111        assert_eq!(
1112            Grib2SubmessageStream::new(sects.into_iter())
1113                .map(|result| result.map(digest_submessage_iter_item))
1114                .collect::<Vec<_>>(),
1115            vec![Err(ParseError::ReadError(
1116                "failed to fill whole buffer".to_owned()
1117            )),],
1118        );
1119    }
1120
1121    #[test]
1122    fn submessage_stream_with_sect_stream_error_at_sect4_in_1st_submessage() {
1123        let sects = new_sect_vec_with_dummy_offset_and_errors(vec![
1124            Ok(0),
1125            Ok(1),
1126            Ok(2),
1127            Ok(3),
1128            Err(ParseError::ReadError(
1129                "failed to fill whole buffer".to_owned(),
1130            )),
1131        ]);
1132
1133        assert_eq!(
1134            Grib2SubmessageStream::new(sects.into_iter())
1135                .map(|result| result.map(digest_submessage_iter_item))
1136                .collect::<Vec<_>>(),
1137            vec![Err(ParseError::ReadError(
1138                "failed to fill whole buffer".to_owned()
1139            )),],
1140        );
1141    }
1142
1143    #[test]
1144    fn submessage_stream_with_sect_stream_error_at_sect5_in_1st_submessage() {
1145        let sects = new_sect_vec_with_dummy_offset_and_errors(vec![
1146            Ok(0),
1147            Ok(1),
1148            Ok(2),
1149            Ok(3),
1150            Ok(4),
1151            Err(ParseError::ReadError(
1152                "failed to fill whole buffer".to_owned(),
1153            )),
1154        ]);
1155
1156        assert_eq!(
1157            Grib2SubmessageStream::new(sects.into_iter())
1158                .map(|result| result.map(digest_submessage_iter_item))
1159                .collect::<Vec<_>>(),
1160            vec![Err(ParseError::ReadError(
1161                "failed to fill whole buffer".to_owned()
1162            )),],
1163        );
1164    }
1165
1166    #[test]
1167    fn submessage_stream_with_sect_stream_error_at_sect6_in_1st_submessage() {
1168        let sects = new_sect_vec_with_dummy_offset_and_errors(vec![
1169            Ok(0),
1170            Ok(1),
1171            Ok(2),
1172            Ok(3),
1173            Ok(4),
1174            Ok(5),
1175            Err(ParseError::ReadError(
1176                "failed to fill whole buffer".to_owned(),
1177            )),
1178        ]);
1179
1180        assert_eq!(
1181            Grib2SubmessageStream::new(sects.into_iter())
1182                .map(|result| result.map(digest_submessage_iter_item))
1183                .collect::<Vec<_>>(),
1184            vec![Err(ParseError::ReadError(
1185                "failed to fill whole buffer".to_owned()
1186            )),],
1187        );
1188    }
1189
1190    #[test]
1191    fn submessage_stream_with_sect_stream_error_at_sect7_in_1st_submessage() {
1192        let sects = new_sect_vec_with_dummy_offset_and_errors(vec![
1193            Ok(0),
1194            Ok(1),
1195            Ok(2),
1196            Ok(3),
1197            Ok(4),
1198            Ok(5),
1199            Ok(6),
1200            Err(ParseError::ReadError(
1201                "failed to fill whole buffer".to_owned(),
1202            )),
1203        ]);
1204
1205        assert_eq!(
1206            Grib2SubmessageStream::new(sects.into_iter())
1207                .map(|result| result.map(digest_submessage_iter_item))
1208                .collect::<Vec<_>>(),
1209            vec![Err(ParseError::ReadError(
1210                "failed to fill whole buffer".to_owned()
1211            )),],
1212        );
1213    }
1214
1215    #[test]
1216    fn submessage_stream_with_sect_stream_error_at_sect8_in_1st_submessage() {
1217        let sects = new_sect_vec_with_dummy_offset_and_errors(vec![
1218            Ok(0),
1219            Ok(1),
1220            Ok(2),
1221            Ok(3),
1222            Ok(4),
1223            Ok(5),
1224            Ok(6),
1225            Ok(7),
1226            Err(ParseError::ReadError(
1227                "failed to fill whole buffer".to_owned(),
1228            )),
1229        ]);
1230
1231        assert_eq!(
1232            Grib2SubmessageStream::new(sects.into_iter())
1233                .map(|result| result.map(digest_submessage_iter_item))
1234                .collect::<Vec<_>>(),
1235            vec![Err(ParseError::ReadError(
1236                "failed to fill whole buffer".to_owned()
1237            )),],
1238        );
1239    }
1240
1241    #[test]
1242    fn submessage_index_stream_from_multiple_messages_and_submessages_with_sect2_toggled() {
1243        // testing cache of submessage_count and sect2
1244        let sect_nums = vec![
1245            0, 1, 2, 3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 7, 8, 0, 1, 3, 4, 5, 6, 7, 8,
1246        ];
1247        let sects = new_sect_vec_with_dummy_offset(sect_nums.clone());
1248
1249        let mut cacher = Vec::new();
1250        let stream = Grib2SubmessageIndexStream::new(sects.into_iter()).with_cacher(&mut cacher);
1251        assert_eq!(
1252            stream
1253                .map(|result| result.map(digest_submessage_index_iter_item))
1254                .collect::<Vec<_>>(),
1255            vec![
1256                Ok((0, 0, 0, 1, Some(2), 3, 4, 5, 6, 7, 0)),
1257                Ok((0, 1, 0, 1, Some(8), 9, 10, 11, 12, 13, 14)),
1258                Ok((1, 0, 15, 16, None, 17, 18, 19, 20, 21, 22))
1259            ],
1260        );
1261        assert_eq!(cacher.iter().map(|s| s.num).collect::<Vec<_>>(), sect_nums,);
1262    }
1263}