Skip to main content

grib/encoder/message/
impls.rs

1use super::*;
2
3impl<T: WriteGrib2Message + ?Sized> WriteGrib2Message for &T {
4    type S1<'a>
5        = <T as WriteGrib2Message>::S1<'a>
6    where
7        Self: 'a;
8
9    type Item<'a>
10        = <T as WriteGrib2Message>::Item<'a>
11    where
12        Self: 'a;
13
14    type Iter<'a>
15        = <T as WriteGrib2Message>::Iter<'a>
16    where
17        Self: 'a;
18
19    fn discipline(&self) -> u8 {
20        (*self).discipline()
21    }
22
23    fn section1(&self) -> &Self::S1<'_> {
24        (*self).section1()
25    }
26
27    fn iter(&self) -> Self::Iter<'_> {
28        (*self).iter()
29    }
30}
31
32impl<T: WriteGrib2MessageIterL1 + ?Sized> WriteGrib2MessageIterL1 for &T {
33    type S2<'a>
34        = <T as WriteGrib2MessageIterL1>::S2<'a>
35    where
36        Self: 'a;
37
38    type Item<'a>
39        = <T as WriteGrib2MessageIterL1>::Item<'a>
40    where
41        Self: 'a;
42
43    type Iter<'a>
44        = <T as WriteGrib2MessageIterL1>::Iter<'a>
45    where
46        Self: 'a;
47
48    fn section2(&self) -> Option<&Self::S2<'_>> {
49        (*self).section2()
50    }
51
52    fn iter(&self) -> Self::Iter<'_> {
53        (*self).iter()
54    }
55}
56
57impl<T: WriteGrib2MessageIterL2 + ?Sized> WriteGrib2MessageIterL2 for &T {
58    type S3<'a>
59        = <T as WriteGrib2MessageIterL2>::S3<'a>
60    where
61        Self: 'a;
62
63    type Item<'a>
64        = <T as WriteGrib2MessageIterL2>::Item<'a>
65    where
66        Self: 'a;
67
68    type Iter<'a>
69        = <T as WriteGrib2MessageIterL2>::Iter<'a>
70    where
71        Self: 'a;
72
73    fn section3(&self) -> &Self::S3<'_> {
74        (*self).section3()
75    }
76
77    fn iter(&self) -> Self::Iter<'_> {
78        (*self).iter()
79    }
80}
81
82impl<T: WriteGrib2MessageIterL3 + ?Sized> WriteGrib2MessageIterL3 for &T {
83    type S4<'a>
84        = <T as WriteGrib2MessageIterL3>::S4<'a>
85    where
86        Self: 'a;
87
88    type SD<'a>
89        = <T as WriteGrib2MessageIterL3>::SD<'a>
90    where
91        Self: 'a;
92
93    fn section4(&self) -> &Self::S4<'_> {
94        (*self).section4()
95    }
96
97    fn data_sections(&self) -> &Self::SD<'_> {
98        (*self).data_sections()
99    }
100}
101
102macro_rules! add_impl_for_references {
103    ($(($trait:path,$len_method:ident,$write_method:ident),)*) => ($(
104        impl<T: $trait + ?Sized> $trait for &T {
105            fn $len_method(&self) -> usize {
106                (*self).$len_method()
107            }
108
109            fn $write_method(&self, buf: &mut [u8]) -> Result<usize, &'static str> {
110                (*self).$write_method(buf)
111            }
112        }
113    )*);
114}
115
116add_impl_for_references![
117    (WriteGrib2Ident, section1_len, write_section1),
118    (WriteGrib2LocalUse, section2_len, write_section2),
119    (WriteGrib2GridDef, section3_len, write_section3),
120    (WriteGrib2ProductDef, section4_len, write_section4),
121    (
122        WriteGrib2PointValues,
123        data_sections_len,
124        write_data_sections
125    ),
126];
127
128macro_rules! add_impl_for_u8_slices {
129    ($(($trait:ty,$len_method:ident,$write_method:ident,$sect_num:expr),)*) => ($(
130        impl $trait for [u8] {
131            fn $len_method(&self) -> usize {
132                self.as_ref().len() + 5
133            }
134
135            fn $write_method(&self, buf: &mut [u8]) -> Result<usize, &'static str> {
136                let len = self.$len_method();
137                if buf.len() < len {
138                    return Err("destination buffer is too small");
139                }
140
141                let mut pos = 0;
142                pos += write_section_header(len as u32, $sect_num, &mut buf[pos..])?;
143                buf[pos..len].copy_from_slice(self.as_ref());
144                Ok(len)
145            }
146        }
147    )*);
148}
149
150add_impl_for_u8_slices![
151    (WriteGrib2Ident, section1_len, write_section1, 1),
152    (WriteGrib2LocalUse, section2_len, write_section2, 2),
153    (WriteGrib2GridDef, section3_len, write_section3, 3),
154    (WriteGrib2ProductDef, section4_len, write_section4, 4),
155];
156
157macro_rules! add_impl_for_payload_structs {
158    ($(($trait:ty,$ty:ty,$len_method:ident,$write_method:ident,$sect_num:expr),)*) => ($(
159        impl $trait for $ty {
160            fn $len_method(&self) -> usize {
161                self.num_bytes_required() + 5
162            }
163
164            fn $write_method(&self, buf: &mut [u8]) -> Result<usize, &'static str> {
165                let len = self.$len_method();
166                if buf.len() < len {
167                    return Err("destination buffer is too small");
168                }
169
170                let mut pos = 0;
171                pos += write_section_header(len as u32, $sect_num, &mut buf[pos..])?;
172                pos += self.write_to_buffer(&mut buf[pos..])?;
173                Ok(pos)
174            }
175        }
176    )*);
177}
178
179add_impl_for_payload_structs![
180    (
181        WriteGrib2Ident,
182        crate::def::grib2::Section1Payload,
183        section1_len,
184        write_section1,
185        1
186    ),
187    (
188        WriteGrib2GridDef,
189        crate::def::grib2::Section3Payload,
190        section3_len,
191        write_section3,
192        3
193    ),
194    (
195        WriteGrib2ProductDef,
196        crate::def::grib2::Section4Payload,
197        section4_len,
198        write_section4,
199        4
200    ),
201];
202
203impl<T: WriteGrib2DataSections + ?Sized> WriteGrib2DataSections for &T {
204    fn section5_len(&self) -> usize {
205        (*self).section5_len()
206    }
207
208    fn write_section5(&self, buf: &mut [u8]) -> Result<usize, &'static str> {
209        (*self).write_section5(buf)
210    }
211
212    fn section6_len(&self) -> usize {
213        (*self).section6_len()
214    }
215
216    fn write_section6(&self, buf: &mut [u8]) -> Result<usize, &'static str> {
217        (*self).write_section6(buf)
218    }
219
220    fn section7_len(&self) -> usize {
221        (*self).section7_len()
222    }
223
224    fn write_section7(&self, buf: &mut [u8]) -> Result<usize, &'static str> {
225        (*self).write_section7(buf)
226    }
227}
228
229impl<'a, 'd, P> WriteGrib2MessageIterL3 for (&'a P, &'a GpvEncoder<'d>)
230where
231    P: WriteGrib2ProductDef,
232{
233    type S4<'s>
234        = P
235    where
236        Self: 's;
237
238    type SD<'s>
239        = GpvEncoder<'d>
240    where
241        Self: 's;
242
243    fn section4(&self) -> &Self::S4<'_> {
244        self.0
245    }
246
247    fn data_sections(&self) -> &Self::SD<'_> {
248        self.1
249    }
250}