Oregami
Repositories/oxedyne/fe2o3

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

1use crate::prelude::*;
2
3use 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)]
12pub enum Alt<S> {
13 Specific(Option<S>),
14 Unspecified,
15}
16
17impl<S> Default for Alt<S> {
18 fn default() -> Self {
19 Alt::Unspecified
20 }
21}
22
23impl<S> From<Option<S>> for Alt<S> {
24 fn from(opt: Option<S>) -> Self {
25 Self::Specific(opt)
26 }
27}
28
29impl<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)]
52pub enum DefAlt<D, G> {
53 Default(D),
54 Given(G),
55 None,
56}
57
58impl<D, G> Default for DefAlt<D, G> {
59 fn default() -> Self {
60 DefAlt::None
61 }
62}
63
64impl<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
73impl<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
82impl<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
99impl<
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)]
118pub enum Override<D, G> {
119 PassThrough,
120 Default(D),
121 Given(G),
122 None,
123}
124
125impl<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)]
138pub enum Gnomon<T> {
139 Known(T),
140 Unknown,
141}
142
143impl<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}