• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

geo-engine / geoengine / 13548366880

26 Feb 2025 04:12PM UTC coverage: 90.074% (-0.002%) from 90.076%
13548366880

Pull #1026

github

web-flow
Merge 35bae8752 into c96026921
Pull Request #1026: Ubuntu 24 LTS

60 of 63 new or added lines in 7 files covered. (95.24%)

2 existing lines in 2 files now uncovered.

126006 of 139891 relevant lines covered (90.07%)

57539.34 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

20.45
/datatypes/src/raster/data_type.rs
1
use super::{GridShape2D, GridShape3D};
2
use crate::error::{self, Error};
3
use crate::operations::image::RgbaTransmutable;
4
use crate::raster::TypedRasterConversion;
5
use crate::util::Result;
6
use gdal::raster::GdalDataType;
7
use num_traits::{AsPrimitive, Bounded, Num};
8
use postgres_types::{FromSql, ToSql};
9
use serde::{Deserialize, Serialize};
10
use std::convert::TryFrom;
11

12
/// A collection of required traits for a pixel type
13
pub trait Pixel:
14
    'static
15
    + Copy
16
    + std::fmt::Debug
17
    + Sync
18
    + Send
19
    + Num
20
    + Bounded
21
    + PartialOrd
22
    + AsPrimitive<u8>
23
    + AsPrimitive<i8>
24
    + AsPrimitive<u16>
25
    + AsPrimitive<i16>
26
    + AsPrimitive<u32>
27
    + AsPrimitive<i32>
28
    + AsPrimitive<u64>
29
    + AsPrimitive<i64>
30
    + AsPrimitive<f32>
31
    + AsPrimitive<f64>
32
    + AsPrimitive<Self>
33
    + FromPrimitive<u8>
34
    + FromPrimitive<i8>
35
    + FromPrimitive<u16>
36
    + FromPrimitive<i16>
37
    + FromPrimitive<u32>
38
    + FromPrimitive<i32>
39
    + FromPrimitive<u64>
40
    + FromPrimitive<i64>
41
    + FromPrimitive<f32>
42
    + FromPrimitive<f64>
43
    + FromPrimitive<Self>
44
    + StaticRasterDataType
45
    + RgbaTransmutable
46
    + TypedRasterConversion<GridShape2D>
47
    + TypedRasterConversion<GridShape3D>
48
    + SaturatingOps
49
{
50
}
51

52
pub trait FromPrimitive<T>
53
where
54
    T: Pixel,
55
{
56
    fn from_(value: T) -> Self;
57
}
58

59
impl<T, V> FromPrimitive<V> for T
60
where
61
    T: Pixel,
62
    V: Pixel + AsPrimitive<T>,
63
{
64
    fn from_(value: V) -> Self {
199,385✔
65
        value.as_()
199,385✔
66
    }
199,385✔
67
}
68

69
/// Saturating operations for the `Pixel` type that do not overflow.
70
pub trait SaturatingOps {
71
    fn saturating_add(self, rhs: Self) -> Self;
72
}
73

74
impl SaturatingOps for u8 {
75
    fn saturating_add(self, rhs: Self) -> Self {
104✔
76
        u8::saturating_add(self, rhs)
104✔
77
    }
104✔
78
}
79

80
impl SaturatingOps for u16 {
81
    fn saturating_add(self, rhs: Self) -> Self {
24✔
82
        u16::saturating_add(self, rhs)
24✔
83
    }
24✔
84
}
85

86
impl SaturatingOps for u32 {
87
    fn saturating_add(self, rhs: Self) -> Self {
×
88
        u32::saturating_add(self, rhs)
×
89
    }
×
90
}
91

92
impl SaturatingOps for u64 {
93
    fn saturating_add(self, rhs: Self) -> Self {
×
94
        u64::saturating_add(self, rhs)
×
95
    }
×
96
}
97

98
impl SaturatingOps for i8 {
99
    fn saturating_add(self, rhs: Self) -> Self {
×
100
        i8::saturating_add(self, rhs)
×
101
    }
×
102
}
103

104
impl SaturatingOps for i16 {
105
    fn saturating_add(self, rhs: Self) -> Self {
×
106
        i16::saturating_add(self, rhs)
×
107
    }
×
108
}
109

110
impl SaturatingOps for i32 {
111
    fn saturating_add(self, rhs: Self) -> Self {
×
112
        i32::saturating_add(self, rhs)
×
113
    }
×
114
}
115

116
impl SaturatingOps for i64 {
117
    fn saturating_add(self, rhs: Self) -> Self {
×
118
        i64::saturating_add(self, rhs)
×
119
    }
×
120
}
121

122
impl SaturatingOps for f32 {
123
    fn saturating_add(self, rhs: Self) -> Self {
×
124
        self + rhs
×
125
    }
×
126
}
127
impl SaturatingOps for f64 {
128
    fn saturating_add(self, rhs: Self) -> Self {
×
129
        self + rhs
×
130
    }
×
131
}
132

133
impl Pixel for u8 {}
134
impl Pixel for i8 {}
135
impl Pixel for u16 {}
136
impl Pixel for i16 {}
137
impl Pixel for u32 {}
138
impl Pixel for i32 {}
139
impl Pixel for u64 {}
140
impl Pixel for i64 {}
141
impl Pixel for f32 {}
142
impl Pixel for f64 {}
143

144
#[derive(
145
    Debug, Ord, PartialOrd, Eq, PartialEq, Hash, Deserialize, Serialize, Copy, Clone, FromSql, ToSql,
×
146
)]
147
pub enum RasterDataType {
148
    U8,
149
    U16,
150
    U32,
151
    U64,
152
    I8,
153
    I16,
154
    I32,
155
    I64,
156
    F32,
157
    F64,
158
}
159

160
impl RasterDataType {
161
    /// Returns true if the given `value` is valid for the `RasterDataType` variant,
162
    /// i.e. it can be represented by a variable of the corresponding primitive data type
163
    #[allow(clippy::float_cmp)]
164
    #[allow(clippy::cast_lossless)]
165
    pub fn is_valid(self, value: f64) -> bool {
6✔
166
        match self {
6✔
167
            RasterDataType::U8 => value as u8 as f64 == value,
4✔
168
            RasterDataType::U16 => value as u16 as f64 == value,
×
169
            RasterDataType::U32 => value as u32 as f64 == value,
×
170
            RasterDataType::U64 => value as u64 as f64 == value,
×
171
            RasterDataType::I8 => value as i8 as f64 == value,
×
172
            RasterDataType::I16 => value as i16 as f64 == value,
×
173
            RasterDataType::I32 => value as i32 as f64 == value,
×
174
            RasterDataType::I64 => value as i64 as f64 == value,
×
175
            RasterDataType::F32 => value.is_nan() || value as f32 as f64 == value,
2✔
176
            RasterDataType::F64 => true,
×
177
        }
178
    }
6✔
179

180
    pub fn from_gdal_data_type(gdal_data_type: GdalDataType) -> Result<Self> {
488✔
181
        match gdal_data_type {
488✔
182
            GdalDataType::Int8 => Ok(Self::I8),
48✔
183
            GdalDataType::UInt8 => Ok(Self::U8),
×
184
            GdalDataType::UInt16 => Ok(Self::U16),
×
185
            GdalDataType::Int16 => Ok(Self::I16),
440✔
186
            GdalDataType::UInt32 => Ok(Self::U32),
×
187
            GdalDataType::Int32 => Ok(Self::I32),
×
NEW
188
            GdalDataType::Int64 => Ok(Self::I64),
×
NEW
189
            GdalDataType::UInt64 => Ok(Self::U64),
×
190
            GdalDataType::Float32 => Ok(Self::F32),
×
191
            GdalDataType::Float64 => Ok(Self::F64),
×
192
            GdalDataType::Unknown => Err(Error::GdalRasterDataTypeNotSupported),
×
193
        }
194
    }
488✔
195
}
196

197
#[derive(Debug, PartialEq, Deserialize, Serialize, Copy, Clone)]
198
pub enum TypedValue {
199
    U8(u8),
200
    U16(u16),
201
    U32(u32),
202
    U64(u64),
203
    I8(i8),
204
    I16(i16),
205
    I32(i32),
206
    I64(i64),
207
    F32(f32),
208
    F64(f64),
209
}
210

211
impl TryFrom<TypedValue> for u8 {
212
    type Error = crate::error::Error;
213

214
    fn try_from(value: TypedValue) -> Result<Self, Self::Error> {
×
215
        if let TypedValue::U8(v) = value {
×
216
            return Ok(v);
×
217
        }
×
218
        Err(error::Error::InvalidTypedValueConversion)
×
219
    }
×
220
}
221

222
impl TryFrom<TypedValue> for u16 {
223
    type Error = crate::error::Error;
224

225
    fn try_from(value: TypedValue) -> Result<Self, Self::Error> {
×
226
        if let TypedValue::U16(v) = value {
×
227
            return Ok(v);
×
228
        }
×
229
        Err(error::Error::InvalidTypedValueConversion)
×
230
    }
×
231
}
232

233
impl TryFrom<TypedValue> for u32 {
234
    type Error = crate::error::Error;
235

236
    fn try_from(value: TypedValue) -> Result<Self, Self::Error> {
×
237
        if let TypedValue::U32(v) = value {
×
238
            return Ok(v);
×
239
        }
×
240
        Err(error::Error::InvalidTypedValueConversion)
×
241
    }
×
242
}
243

244
impl TryFrom<TypedValue> for u64 {
245
    type Error = crate::error::Error;
246

247
    fn try_from(value: TypedValue) -> Result<Self, Self::Error> {
×
248
        if let TypedValue::U64(v) = value {
×
249
            return Ok(v);
×
250
        }
×
251
        Err(error::Error::InvalidTypedValueConversion)
×
252
    }
×
253
}
254

255
impl TryFrom<TypedValue> for i8 {
256
    type Error = crate::error::Error;
257

258
    fn try_from(value: TypedValue) -> Result<Self, Self::Error> {
×
259
        if let TypedValue::I8(v) = value {
×
260
            return Ok(v);
×
261
        }
×
262
        Err(error::Error::InvalidTypedValueConversion)
×
263
    }
×
264
}
265

266
impl TryFrom<TypedValue> for i16 {
267
    type Error = crate::error::Error;
268

269
    fn try_from(value: TypedValue) -> Result<Self, Self::Error> {
×
270
        if let TypedValue::I16(v) = value {
×
271
            return Ok(v);
×
272
        }
×
273
        Err(error::Error::InvalidTypedValueConversion)
×
274
    }
×
275
}
276

277
impl TryFrom<TypedValue> for i32 {
278
    type Error = crate::error::Error;
279

280
    fn try_from(value: TypedValue) -> Result<Self, Self::Error> {
×
281
        if let TypedValue::I32(v) = value {
×
282
            return Ok(v);
×
283
        }
×
284
        Err(error::Error::InvalidTypedValueConversion)
×
285
    }
×
286
}
287

288
impl TryFrom<TypedValue> for i64 {
289
    type Error = crate::error::Error;
290

291
    fn try_from(value: TypedValue) -> Result<Self, Self::Error> {
×
292
        if let TypedValue::I64(v) = value {
×
293
            return Ok(v);
×
294
        }
×
295
        Err(error::Error::InvalidTypedValueConversion)
×
296
    }
×
297
}
298

299
impl TryFrom<TypedValue> for f32 {
300
    type Error = crate::error::Error;
301

302
    fn try_from(value: TypedValue) -> Result<Self, Self::Error> {
×
303
        if let TypedValue::F32(v) = value {
×
304
            return Ok(v);
×
305
        }
×
306
        Err(error::Error::InvalidTypedValueConversion)
×
307
    }
×
308
}
309

310
impl TryFrom<TypedValue> for f64 {
311
    type Error = crate::error::Error;
312

313
    fn try_from(value: TypedValue) -> Result<Self, Self::Error> {
×
314
        if let TypedValue::F64(v) = value {
×
315
            return Ok(v);
×
316
        }
×
317
        Err(error::Error::InvalidTypedValueConversion)
×
318
    }
×
319
}
320

321
// TODO: use a macro?
322
pub trait StaticRasterDataType: Copy + Default + 'static {
323
    const TYPE: RasterDataType;
324
}
325

326
impl StaticRasterDataType for u8 {
327
    const TYPE: RasterDataType = RasterDataType::U8;
328
}
329

330
impl StaticRasterDataType for u16 {
331
    const TYPE: RasterDataType = RasterDataType::U16;
332
}
333

334
impl StaticRasterDataType for u32 {
335
    const TYPE: RasterDataType = RasterDataType::U32;
336
}
337

338
impl StaticRasterDataType for u64 {
339
    const TYPE: RasterDataType = RasterDataType::U64;
340
}
341

342
impl StaticRasterDataType for i8 {
343
    const TYPE: RasterDataType = RasterDataType::I8;
344
}
345

346
impl StaticRasterDataType for i16 {
347
    const TYPE: RasterDataType = RasterDataType::I16;
348
}
349

350
impl StaticRasterDataType for i32 {
351
    const TYPE: RasterDataType = RasterDataType::I32;
352
}
353

354
impl StaticRasterDataType for i64 {
355
    const TYPE: RasterDataType = RasterDataType::I64;
356
}
357

358
impl StaticRasterDataType for f32 {
359
    const TYPE: RasterDataType = RasterDataType::F32;
360
}
361

362
impl StaticRasterDataType for f64 {
363
    const TYPE: RasterDataType = RasterDataType::F64;
364
}
365

366
pub trait DynamicRasterDataType {
367
    fn raster_data_type(&self) -> RasterDataType;
368
}
369

370
impl<R> DynamicRasterDataType for R
371
where
372
    R: StaticRasterDataType,
373
{
374
    fn raster_data_type(&self) -> RasterDataType {
×
375
        R::TYPE
×
376
    }
×
377
}
378

379
#[cfg(test)]
380
mod tests {
381
    use super::*;
382

383
    #[test]
384
    fn valid_values() {
1✔
385
        assert!(RasterDataType::U8.is_valid(0.0));
1✔
386
        assert!(RasterDataType::U8.is_valid(255.0));
1✔
387
        assert!(!RasterDataType::U8.is_valid(0.1));
1✔
388
        assert!(!RasterDataType::U8.is_valid(-1.0));
1✔
389

390
        assert!(RasterDataType::F32.is_valid(1.5));
1✔
391
        assert!(!RasterDataType::F32.is_valid(f64::MIN));
1✔
392
    }
1✔
393
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc