orwith/
lib.rs

1/// Represents one, another, or two values. (Addtionally, as an edgecase, the `enum` contains a `Neither` value.)
2/// 
3/// # Example
4/// ```rust
5/// use orwith::Orwith;
6/// 
7/// let x:Option<&str> = Some("Hello!");
8/// let y:Option<&str> = Some("Goodbye!");
9/// 
10/// let v = Orwith::orwith(x, y); // Orwith::With(...)
11/// ```
12#[derive(Debug)]
13pub enum Orwith<T> {
14	/// Neither option was chosen or both options were refused.
15	Neither,
16	/// Both options were preferred.
17	With(T, T),
18	/// Only one option was preferred or the option not chosen was refused.
19	Or(T)
20}
21
22impl<T> Orwith<T> {
23	/// Takes two options and decides which variant to choose based on the presence of values.
24	pub fn orwith(x:Option<T>, y:Option<T>) -> Self {
25		match (x, y) {
26			(Some(vx), Some(vy))        => Self::With(vx, vy),
27			(Some(v), _) | (_, Some(v)) => Self::Or(v),
28			_                           => Self::Neither
29		}
30	}
31	
32	
33	
34	/// Returns a mutable reference to the first value.
35	pub fn first_mut(&mut self) -> Option<&mut T> {
36		match self {
37			Self::Neither    => None,
38			Self::With(v, _) => Some(v),
39			Self::Or(v)      => Some(v)
40		}
41	}
42	
43	/// Returns a mutable reference to the last value.
44	pub fn last_mut(&mut self) -> Option<&mut T> {
45		match self {
46			Self::With(_, v) => Some(v),
47			_ => self.first_mut()
48		}
49	}
50	
51	/// Returns the first item and consumes this `Orwith` value.
52	pub fn to_first(self) -> Option<T> { self.to_pair().0 }
53	
54	/// Returns the last item and consumes this `Orwith` value.
55	pub fn to_last(self) -> Option<T> { self.to_pair().1 }
56	
57	/// Returns the first and last items and consumes this `Orwith` value.
58	pub fn to_pair(self) -> (Option<T>, Option<T>) {
59		let mut p = (None, None);
60		match self {
61			Self::With(x, y) => { (p.0, p.1) = (Some(x), Some(y)); }
62			Self::Or(v) => { (p.0, p.1) = (Some(v), None); }
63			_ => {}
64		}
65		
66		p
67	}
68	
69	/// Returns an immutable reference to the first value.
70	pub fn first(&self) -> Option<&T> {
71		match self {
72			Self::Neither    => None,
73			Self::With(v, _) => Some(&v),
74			Self::Or(v)      => Some(&v)
75		}
76	}
77	
78	/// Returns an immutable reference to the last value.
79	pub fn last(&self) -> Option<&T> {
80		match self {
81			Self::With(_, v) => Some(v),
82			_ => self.first()
83		}
84	}
85}
86
87impl<T> Default for Orwith<T> {
88	fn default() -> Self { Self::Neither }
89}
90
91impl<T> From<(Option<T>, Option<T>)> for Orwith<T> {
92	fn from(v:(Option<T>, Option<T>)) -> Self { Self::orwith(v.0, v.1) }
93}
94
95impl<T> Into<(Option<T>, Option<T>)> for Orwith<T> {
96	fn into(self) -> (Option<T>, Option<T>) { self.to_pair() }
97}