substrait_explain/
precision.rs1use std::fmt;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
16pub(crate) enum SupportedPrecision {
17 Seconds, Milliseconds, Microseconds, Nanoseconds, Picoseconds, }
23
24impl SupportedPrecision {
25 pub fn units(self) -> i32 {
27 match self {
28 SupportedPrecision::Seconds => 0,
29 SupportedPrecision::Milliseconds => 3,
30 SupportedPrecision::Microseconds => 6,
31 SupportedPrecision::Nanoseconds => 9,
32 SupportedPrecision::Picoseconds => 12,
33 }
34 }
35
36 pub fn from_units(units: i32) -> Option<Self> {
38 match units {
39 0 => Some(SupportedPrecision::Seconds),
40 3 => Some(SupportedPrecision::Milliseconds),
41 6 => Some(SupportedPrecision::Microseconds),
42 9 => Some(SupportedPrecision::Nanoseconds),
43 12 => Some(SupportedPrecision::Picoseconds),
44 _ => None,
45 }
46 }
47
48 pub fn subsecond_unit(self) -> Option<&'static str> {
52 match self {
53 SupportedPrecision::Seconds => None,
54 SupportedPrecision::Milliseconds => Some("ms"),
55 SupportedPrecision::Microseconds => Some("us"),
56 SupportedPrecision::Nanoseconds => Some("ns"),
57 SupportedPrecision::Picoseconds => Some("ps"),
58 }
59 }
60
61 pub fn from_subsecond_unit(unit: &str) -> Option<Self> {
63 match unit {
64 "ms" => Some(SupportedPrecision::Milliseconds),
65 "us" => Some(SupportedPrecision::Microseconds),
66 "ns" => Some(SupportedPrecision::Nanoseconds),
67 "ps" => Some(SupportedPrecision::Picoseconds),
68 _ => None,
69 }
70 }
71}
72
73impl fmt::Display for SupportedPrecision {
74 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75 write!(f, "{}", self.units())
76 }
77}
78
79#[cfg(test)]
80mod tests {
81 use super::*;
82
83 #[test]
84 fn test_units_roundtrip() {
85 for units in [0, 3, 6, 9, 12] {
86 let precision = SupportedPrecision::from_units(units).unwrap();
87 assert_eq!(precision.units(), units);
88 }
89 assert_eq!(SupportedPrecision::from_units(4), None);
91 assert_eq!(SupportedPrecision::from_units(13), None);
92 assert_eq!(SupportedPrecision::from_units(-1), None);
93 }
94
95 #[test]
96 fn test_subsecond_unit_roundtrip() {
97 for unit in ["ms", "us", "ns", "ps"] {
98 let precision = SupportedPrecision::from_subsecond_unit(unit).unwrap();
99 assert_eq!(precision.subsecond_unit(), Some(unit));
100 }
101 assert_eq!(SupportedPrecision::Seconds.subsecond_unit(), None);
103 assert_eq!(SupportedPrecision::from_subsecond_unit("s"), None);
104 }
105}