oxedyne/fe2o3/fe2o3_core/src/alt.rs
3.2 KiB, 4 runs
created by r1870400018:60, which is this file's identity for as long as the history lasts, whatever it is later renamed to
download · who wrote it · its history
| 1 | use crate::prelude::*; |
| 2 | |
| 3 | use std::{ |
| 4 | borrow::Cow, |
| 5 | fmt::Debug, |
| 6 | }; |
| 7 | |
| 8 | |
| 9 | /// `Alt` is a non-binary superset of `std::option::Option` that differentiates between an |
| 10 | /// unspecified variant and none. |
| 11 | #[derive(Clone, Debug)] |
| 12 | pub enum Alt<S> { |
| 13 | Specific(Option<S>), |
| 14 | Unspecified, |
| 15 | } |
| 16 | |
| 17 | impl<S> Default for Alt<S> { |
| 18 | fn default() -> Self { |
| 19 | Alt::Unspecified |
| 20 | } |
| 21 | } |
| 22 | |
| 23 | impl<S> From<Option<S>> for Alt<S> { |
| 24 | fn from(opt: Option<S>) -> Self { |
| 25 | Self::Specific(opt) |
| 26 | } |
| 27 | } |
| 28 | |
| 29 | impl<S> Alt<S> { |
| 30 | pub fn is_unspecified(&self) -> bool { |
| 31 | match self { |
| 32 | Self::Unspecified => true, |
| 33 | _ => false, |
| 34 | } |
| 35 | } |
| 36 | pub fn is_none(&self) -> bool { |
| 37 | match self { |
| 38 | Self::Specific(None) => true, |
| 39 | _ => false, |
| 40 | } |
| 41 | } |
| 42 | pub fn is_some(&self) -> bool { |
| 43 | match self { |
| 44 | Self::Specific(Some(_)) => true, |
| 45 | _ => false, |
| 46 | } |
| 47 | } |
| 48 | } |
| 49 | |
| 50 | /// `DefAlt` is like an `Alt` that provides for a default value, potentially of a different type. |
| 51 | #[derive(Clone, Debug)] |
| 52 | pub enum DefAlt<D, G> { |
| 53 | Default(D), |
| 54 | Given(G), |
| 55 | None, |
| 56 | } |
| 57 | |
| 58 | impl<D, G> Default for DefAlt<D, G> { |
| 59 | fn default() -> Self { |
| 60 | DefAlt::None |
| 61 | } |
| 62 | } |
| 63 | |
| 64 | impl<D, G> From<Option<G>> for DefAlt<D, G> { |
| 65 | fn from(opt: Option<G>) -> Self { |
| 66 | match opt { |
| 67 | Some(g) => DefAlt::Given(g), |
| 68 | None => DefAlt::None, |
| 69 | } |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | impl<D, G> From<Alt<G>> for DefAlt<D, G> { |
| 74 | fn from(alt: Alt<G>) -> Self { |
| 75 | match alt { |
| 76 | Alt::Specific(Some(g)) => DefAlt::Given(g), |
| 77 | _ => DefAlt::None, |
| 78 | } |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | impl<D, G> DefAlt<D, G> { |
| 83 | |
| 84 | pub fn is_none(&self) -> bool { |
| 85 | match self { |
| 86 | Self::None => true, |
| 87 | _ => false, |
| 88 | } |
| 89 | } |
| 90 | |
| 91 | pub fn is_some(&self) -> bool { |
| 92 | match self { |
| 93 | Self::None => false, |
| 94 | _ => true, |
| 95 | } |
| 96 | } |
| 97 | } |
| 98 | |
| 99 | impl< |
| 100 | D: Clone + Debug, |
| 101 | G: Clone + Debug, |
| 102 | > |
| 103 | DefAlt<D, G> |
| 104 | { |
| 105 | pub fn from_or<'a>(&'a self, or: Override<D, G>) -> Cow<'a, Self> { |
| 106 | match or { |
| 107 | Override::PassThrough => Cow::Borrowed(self), |
| 108 | Override::Default(inner) => Cow::Owned(Self::Default(inner)), |
| 109 | Override::Given(inner) => Cow::Owned(Self::Given(inner)), |
| 110 | Override::None => Cow::Owned(Self::None), |
| 111 | } |
| 112 | } |
| 113 | } |
| 114 | |
| 115 | /// Useful in combination with `DefAlt`, `Override` expresses the possibility that we just go with |
| 116 | /// the value of a given `DefAlt` rather than override it. |
| 117 | #[derive(Clone, Debug)] |
| 118 | pub enum Override<D, G> { |
| 119 | PassThrough, |
| 120 | Default(D), |
| 121 | Given(G), |
| 122 | None, |
| 123 | } |
| 124 | |
| 125 | impl<D, G> Override<D, G> { |
| 126 | |
| 127 | pub fn is_some(&self) -> bool { |
| 128 | match self { |
| 129 | Self::None | Self::PassThrough => false, |
| 130 | _ => true, |
| 131 | } |
| 132 | } |
| 133 | } |
| 134 | |
| 135 | /// `Gnomon` is less linguistically definite than `std::option::Option`. It means "one that knows" |
| 136 | /// in Ancient Greek. |
| 137 | #[derive(Clone, Debug)] |
| 138 | pub enum Gnomon<T> { |
| 139 | Known(T), |
| 140 | Unknown, |
| 141 | } |
| 142 | |
| 143 | impl<T> Gnomon<T> { |
| 144 | pub fn required(&self, value_name: &str) -> Outcome<&T> { |
| 145 | match self { |
| 146 | Self::Known(v) => Ok(v), |
| 147 | Self::Unknown => Err(err!( |
| 148 | "A known value of {} is required.", value_name; |
| 149 | Data, Missing)), |
| 150 | } |
| 151 | } |
| 152 | } |