Skip to main content

ordinal_map/ordinal/impls/
std.rs

1use std::convert::Infallible;
2
3use crate::Ordinal;
4
5impl<A: Ordinal> Ordinal for Option<A> {
6    const ORDINAL_SIZE: usize = A::ORDINAL_SIZE + 1;
7
8    fn ordinal(&self) -> usize {
9        match self {
10            None => 0,
11            Some(a) => a.ordinal() + 1,
12        }
13    }
14
15    fn from_ordinal(ordinal: usize) -> Option<Self> {
16        if ordinal == 0 {
17            Some(None)
18        } else {
19            A::from_ordinal(ordinal - 1).map(Some)
20        }
21    }
22}
23
24impl<A: Ordinal, B: Ordinal> Ordinal for Result<A, B> {
25    const ORDINAL_SIZE: usize = A::ORDINAL_SIZE + B::ORDINAL_SIZE;
26
27    fn ordinal(&self) -> usize {
28        match self {
29            Ok(a) => a.ordinal(),
30            Err(b) => A::ORDINAL_SIZE + b.ordinal(),
31        }
32    }
33
34    fn from_ordinal(ordinal: usize) -> Option<Self> {
35        if ordinal < A::ORDINAL_SIZE {
36            Some(Ok(A::from_ordinal(ordinal).unwrap()))
37        } else {
38            B::from_ordinal(ordinal - A::ORDINAL_SIZE).map(Err)
39        }
40    }
41}
42
43impl Ordinal for Infallible {
44    const ORDINAL_SIZE: usize = 0;
45
46    fn ordinal(&self) -> usize {
47        match *self {}
48    }
49
50    fn from_ordinal(_: usize) -> Option<Self> {
51        None
52    }
53}
54
55#[cfg(test)]
56mod tests {
57    use std::convert::Infallible;
58
59    use crate::tests::util::test_ordinal;
60
61    #[test]
62    fn test_option() {
63        test_ordinal([None, Some(false), Some(true)]);
64    }
65
66    #[test]
67    fn test_result() {
68        test_ordinal([
69            Ok(false),
70            Ok(true),
71            Err(None),
72            Err(Some(false)),
73            Err(Some(true)),
74        ]);
75    }
76
77    #[test]
78    fn test_infallible() {
79        test_ordinal::<Infallible>([]);
80    }
81}