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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
use std::{borrow::Cow, path::PathBuf, str::FromStr};
use confindent::Confindent;
use crate::{
Scurvy,
formula::{Formula, PathFormula},
};
impl Scurvy {
pub fn with_confindent(self, confindent: Confindent) -> ConfigurationPair {
ConfigurationPair::new(self, confindent)
}
pub fn with_configuration_key<P: Into<PathBuf>>(
self,
key: &str,
default_conf: P,
) -> ConfigurationPair {
let path = self.parse_or(key, PathFormula::new(), default_conf.into());
match Confindent::from_file(&path) {
Err(_) => {
eprintln!(
"Unable to find configuration file at path '{}'",
path.to_string_lossy()
);
std::process::exit(-1)
}
Ok(confindent) => ConfigurationPair {
scurvy: self,
confindent,
},
}
}
}
pub struct ConfigurationPair {
scurvy: Scurvy,
confindent: Confindent,
}
impl ConfigurationPair {
pub(crate) fn new(scurvy: Scurvy, confindent: Confindent) -> Self {
Self { scurvy, confindent }
}
}
impl ConfigurationPair {
pub fn has<K: Into<ConfigurationKey<'static>>>(&self, key: K) -> bool {
self.get(key).is_some()
}
pub fn get<K: Into<ConfigurationKey<'static>>>(&self, key: K) -> Option<&str> {
let key = key.into();
self.scurvy
.get(&key.scurvy())
.or_else(|| self.confindent.get(&key.confindent()))
}
pub fn get_req<K: Into<ConfigurationKey<'static>>>(&self, key: K) -> &str {
let key = key.into();
match self.get(key) {
None => {
let pair = self.scurvy.get_pair(&key.scurvy()).unwrap();
self.scurvy.print_missing_and_die(pair.key.preferred_key());
}
Some(s) => s,
}
}
pub fn parse<T, F, K>(&self, key: K, formula: F) -> Option<T>
where
T: FromStr,
F: Into<Formula<T>>,
K: Into<ConfigurationKey<'static>>,
{
let key = key.into();
let formula = formula.into();
let maybe_scurvy = self.scurvy.get(&key.scurvy());
let maybe_confindent = self.confindent.get(&key.confindent());
maybe_scurvy
.or(maybe_confindent)
.map(|got| self.scurvy.check_formula(&key.scurvy(), got, formula))
.flatten()
}
pub fn parse_req<T, F, K>(&self, key: K, formula: F) -> T
where
T: FromStr,
F: Into<Formula<T>>,
K: Into<ConfigurationKey<'static>>,
{
let key = key.into();
let formula = formula.into();
let missing = formula.missing.clone();
match self.parse(key, formula) {
None => self.scurvy.handle_missing(&key.scurvy(), missing),
Some(o) => o,
}
}
}
#[derive(Copy, Clone, Debug)]
pub enum ConfigurationKey<'s> {
Scurvy(&'s str),
Both(&'s str, &'s str),
}
impl<'s> ConfigurationKey<'s> {
pub fn scurvy(&self) -> Cow<'s, str> {
match self {
Self::Scurvy(s) => Cow::Borrowed(s),
Self::Both(s, _) => Cow::Borrowed(s),
}
}
pub fn confindent(&self) -> Cow<'s, str> {
match self {
Self::Scurvy(s) => {
let mut c = s.chars();
match c.next() {
None => Cow::Borrowed(""),
Some(f) => Cow::Owned(f.to_uppercase().chain(c).collect()),
}
}
Self::Both(_, c) => Cow::Borrowed(c),
}
}
}
impl<'s> From<&'s str> for ConfigurationKey<'s> {
fn from(value: &'s str) -> Self {
Self::Scurvy(value)
}
}
impl<'s> From<[&'s str; 2]> for ConfigurationKey<'s> {
fn from(value: [&'s str; 2]) -> Self {
Self::Both(value[0], value[1])
}
}
|