Skip to main content

grib/encoder/message/
multigrid.rs

1use std::iter::{Once, once};
2
3use super::{
4    GpvEncoder, WriteGrib2GridDef, WriteGrib2Ident, WriteGrib2LocalUse, WriteGrib2Message,
5    WriteGrib2MessageIterL1, WriteGrib2MessageIterL2, WriteGrib2ProductDef,
6};
7
8/// A writer for GRIB2 messages containing multiple submessages with different
9/// grids.
10pub struct MultiGridGrib2Message<'d, I, L, G, P> {
11    discipline: u8,
12    ident: I,
13    local_use: Option<L>,
14    grid_product_values: Vec<(G, P, GpvEncoder<'d>)>,
15}
16
17impl<'d, I, L, G, P> MultiGridGrib2Message<'d, I, L, G, P> {
18    pub fn new(
19        discipline: u8,
20        ident: I,
21        local_use: Option<L>,
22        grid_product_values: Vec<(G, P, GpvEncoder<'d>)>,
23    ) -> Self {
24        Self {
25            discipline,
26            ident,
27            local_use,
28            grid_product_values,
29        }
30    }
31}
32
33impl<'d, I, L, G, P> WriteGrib2Message for MultiGridGrib2Message<'d, I, L, G, P>
34where
35    I: WriteGrib2Ident,
36    L: WriteGrib2LocalUse,
37    G: WriteGrib2GridDef,
38    P: WriteGrib2ProductDef,
39{
40    type S1<'a>
41        = I
42    where
43        Self: 'a;
44
45    type Item<'a>
46        = (&'a Option<L>, &'a Vec<(G, P, GpvEncoder<'d>)>)
47    where
48        Self: 'a;
49
50    type Iter<'a>
51        = Once<(&'a Option<L>, &'a Vec<(G, P, GpvEncoder<'d>)>)>
52    where
53        Self: 'a;
54
55    fn discipline(&self) -> u8 {
56        self.discipline
57    }
58
59    fn section1(&self) -> &Self::S1<'_> {
60        &self.ident
61    }
62
63    fn iter(&self) -> Self::Iter<'_> {
64        once((&self.local_use, &self.grid_product_values))
65    }
66}
67
68impl<'a, 'd, L, G, P> WriteGrib2MessageIterL1 for (&'a Option<L>, &'a Vec<(G, P, GpvEncoder<'d>)>)
69where
70    L: WriteGrib2LocalUse,
71    G: WriteGrib2GridDef,
72    P: WriteGrib2ProductDef,
73{
74    type S2<'s>
75        = L
76    where
77        Self: 's;
78
79    type Item<'s>
80        = &'a (G, P, GpvEncoder<'d>)
81    where
82        Self: 's;
83
84    type Iter<'s>
85        = std::slice::Iter<'a, (G, P, GpvEncoder<'d>)>
86    where
87        Self: 's;
88
89    fn section2(&self) -> Option<&Self::S2<'_>> {
90        self.0.as_ref()
91    }
92
93    fn iter(&self) -> Self::Iter<'_> {
94        self.1.iter()
95    }
96}
97
98impl<'a, 'd, G, P> WriteGrib2MessageIterL2 for &'a (G, P, GpvEncoder<'d>)
99where
100    G: WriteGrib2GridDef,
101    P: WriteGrib2ProductDef,
102{
103    type S3<'s>
104        = G
105    where
106        Self: 's;
107
108    type Item<'s>
109        = (&'a P, &'a GpvEncoder<'d>)
110    where
111        Self: 's;
112
113    type Iter<'s>
114        = Once<(&'a P, &'a GpvEncoder<'d>)>
115    where
116        Self: 's;
117
118    fn section3(&self) -> &Self::S3<'_> {
119        &self.0
120    }
121
122    fn iter(&self) -> Self::Iter<'_> {
123        once((&self.1, &self.2))
124    }
125}