Skip to main content

grib/encoder/message/
multiproduct.rs

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