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

geo-engine / geoengine / 13053993104

30 Jan 2025 01:35PM UTC coverage: 90.027% (-0.07%) from 90.093%
13053993104

push

github

web-flow
Merge pull request #1011 from geo-engine/update-2025-01-17

update to rust 1.84

46 of 54 new or added lines in 14 files covered. (85.19%)

102 existing lines in 41 files now uncovered.

125596 of 139510 relevant lines covered (90.03%)

57696.13 hits per line

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

20.16
/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(
UNCOV
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::UInt8 => Ok(Self::U8),
×
183
            GdalDataType::UInt16 => Ok(Self::U16),
×
184
            GdalDataType::Int16 => Ok(Self::I16),
488✔
185
            GdalDataType::UInt32 => Ok(Self::U32),
×
186
            GdalDataType::Int32 => Ok(Self::I32),
×
187
            GdalDataType::Float32 => Ok(Self::F32),
×
188
            GdalDataType::Float64 => Ok(Self::F64),
×
189
            GdalDataType::Unknown => Err(Error::GdalRasterDataTypeNotSupported),
×
190
        }
191
    }
488✔
192
}
193

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

208
impl TryFrom<TypedValue> for u8 {
209
    type Error = crate::error::Error;
210

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

219
impl TryFrom<TypedValue> for u16 {
220
    type Error = crate::error::Error;
221

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

230
impl TryFrom<TypedValue> for u32 {
231
    type Error = crate::error::Error;
232

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

241
impl TryFrom<TypedValue> for u64 {
242
    type Error = crate::error::Error;
243

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

252
impl TryFrom<TypedValue> for i8 {
253
    type Error = crate::error::Error;
254

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

263
impl TryFrom<TypedValue> for i16 {
264
    type Error = crate::error::Error;
265

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

274
impl TryFrom<TypedValue> for i32 {
275
    type Error = crate::error::Error;
276

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

285
impl TryFrom<TypedValue> for i64 {
286
    type Error = crate::error::Error;
287

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

296
impl TryFrom<TypedValue> for f32 {
297
    type Error = crate::error::Error;
298

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

307
impl TryFrom<TypedValue> for f64 {
308
    type Error = crate::error::Error;
309

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

318
// TODO: use a macro?
319
pub trait StaticRasterDataType: Copy + Default + 'static {
320
    const TYPE: RasterDataType;
321
}
322

323
impl StaticRasterDataType for u8 {
324
    const TYPE: RasterDataType = RasterDataType::U8;
325
}
326

327
impl StaticRasterDataType for u16 {
328
    const TYPE: RasterDataType = RasterDataType::U16;
329
}
330

331
impl StaticRasterDataType for u32 {
332
    const TYPE: RasterDataType = RasterDataType::U32;
333
}
334

335
impl StaticRasterDataType for u64 {
336
    const TYPE: RasterDataType = RasterDataType::U64;
337
}
338

339
impl StaticRasterDataType for i8 {
340
    const TYPE: RasterDataType = RasterDataType::I8;
341
}
342

343
impl StaticRasterDataType for i16 {
344
    const TYPE: RasterDataType = RasterDataType::I16;
345
}
346

347
impl StaticRasterDataType for i32 {
348
    const TYPE: RasterDataType = RasterDataType::I32;
349
}
350

351
impl StaticRasterDataType for i64 {
352
    const TYPE: RasterDataType = RasterDataType::I64;
353
}
354

355
impl StaticRasterDataType for f32 {
356
    const TYPE: RasterDataType = RasterDataType::F32;
357
}
358

359
impl StaticRasterDataType for f64 {
360
    const TYPE: RasterDataType = RasterDataType::F64;
361
}
362

363
pub trait DynamicRasterDataType {
364
    fn raster_data_type(&self) -> RasterDataType;
365
}
366

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

376
#[cfg(test)]
377
mod tests {
378
    use super::*;
379

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

387
        assert!(RasterDataType::F32.is_valid(1.5));
1✔
388
        assert!(!RasterDataType::F32.is_valid(f64::MIN));
1✔
389
    }
1✔
390
}
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