1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
use std::{
fmt::{self, Write as _},
str,
};
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Hash)]
pub enum Preference<T> {
Any,
Specific(T),
}
impl<T> Preference<T> {
pub fn is_any(&self) -> bool {
matches!(self, Self::Any)
}
pub fn is_specific(&self) -> bool {
matches!(self, Self::Specific(_))
}
pub fn item(&self) -> Option<&T> {
match self {
Preference::Specific(ref item) => Some(item),
Preference::Any => None,
}
}
pub fn into_item(self) -> Option<T> {
match self {
Preference::Specific(item) => Some(item),
Preference::Any => None,
}
}
}
impl<T: fmt::Display> fmt::Display for Preference<T> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Preference::Any => f.write_char('*'),
Preference::Specific(item) => fmt::Display::fmt(item, f),
}
}
}
impl<T: str::FromStr> str::FromStr for Preference<T> {
type Err = T::Err;
#[inline]
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.trim() {
"*" => Ok(Self::Any),
other => other.parse().map(Preference::Specific),
}
}
}