Skip to main content

hfx_core/
raster.rs

1//! Raster-related domain types.
2
3/// D8 flow direction encoding convention.
4///
5/// Declares which encoding convention a `flow_dir.tif` raster uses.
6/// The engine normalizes to its internal convention at read time.
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8pub enum FlowDirEncoding {
9    /// ESRI convention: powers of 2 (1, 2, 4, 8, 16, 32, 64, 128).
10    Esri,
11    /// TauDEM convention: 1-8, east origin, counter-clockwise.
12    Taudem,
13}
14
15impl std::fmt::Display for FlowDirEncoding {
16    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17        match self {
18            FlowDirEncoding::Esri => write!(f, "esri"),
19            FlowDirEncoding::Taudem => write!(f, "taudem"),
20        }
21    }
22}
23
24/// Error returned when parsing an unknown flow direction encoding string.
25#[derive(Debug, thiserror::Error)]
26#[error("unknown flow direction encoding: {value:?}, expected \"esri\" or \"taudem\"")]
27pub struct FlowDirEncodingError {
28    /// The unrecognized string.
29    pub value: String,
30}
31
32impl std::str::FromStr for FlowDirEncoding {
33    type Err = FlowDirEncodingError;
34    fn from_str(s: &str) -> Result<Self, Self::Err> {
35        match s {
36            "esri" => Ok(FlowDirEncoding::Esri),
37            "taudem" => Ok(FlowDirEncoding::Taudem),
38            _ => Err(FlowDirEncodingError {
39                value: s.to_owned(),
40            }),
41        }
42    }
43}
44
45#[cfg(test)]
46mod tests {
47    use super::*;
48
49    #[test]
50    fn flow_dir_encoding_variants_are_not_equal() {
51        assert_ne!(FlowDirEncoding::Esri, FlowDirEncoding::Taudem);
52    }
53
54    #[test]
55    fn flow_dir_encoding_clone_and_copy() {
56        let original = FlowDirEncoding::Esri;
57        let cloned = original;
58        // Copy: bind by value into a second variable.
59        let copied = original;
60        assert_eq!(original, cloned);
61        assert_eq!(original, copied);
62    }
63
64    #[test]
65    fn flow_dir_encoding_usable_as_hash_map_key() {
66        use std::collections::HashMap;
67        let mut map: HashMap<FlowDirEncoding, &str> = HashMap::new();
68        map.insert(FlowDirEncoding::Esri, "esri");
69        map.insert(FlowDirEncoding::Taudem, "taudem");
70        assert_eq!(map[&FlowDirEncoding::Esri], "esri");
71        assert_eq!(map[&FlowDirEncoding::Taudem], "taudem");
72    }
73
74    #[test]
75    fn flow_dir_encoding_display() {
76        assert_eq!(FlowDirEncoding::Esri.to_string(), "esri");
77        assert_eq!(FlowDirEncoding::Taudem.to_string(), "taudem");
78    }
79
80    #[test]
81    fn flow_dir_encoding_fromstr_valid() {
82        assert_eq!(
83            "esri".parse::<FlowDirEncoding>().unwrap(),
84            FlowDirEncoding::Esri
85        );
86        assert_eq!(
87            "taudem".parse::<FlowDirEncoding>().unwrap(),
88            FlowDirEncoding::Taudem
89        );
90    }
91
92    #[test]
93    fn flow_dir_encoding_fromstr_invalid() {
94        assert!("invalid".parse::<FlowDirEncoding>().is_err());
95        assert!("ESRI".parse::<FlowDirEncoding>().is_err());
96    }
97}