-
Notifications
You must be signed in to change notification settings - Fork 396
/
get.rs
111 lines (106 loc) · 3.87 KB
/
get.rs
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
use std::collections::HashMap;
use crate::cli;
use crate::features;
use crate::git_config::{self, GitConfigGet};
use crate::options::option_value::{OptionValue, ProvenancedOptionValue};
use ProvenancedOptionValue::*;
/// Look up a value of type `T` associated with `option name`. The search rules are:
///
/// 1. If there is a value associated with `option_name` in the main [delta] git config
/// section, then stop searching and return that value.
///
/// 2. For each feature in the ordered list of enabled features:
///
/// 2.1 Look-up the value, treating `feature` as a custom feature.
/// I.e., if there is a value associated with `option_name` in a git config section
/// named [delta "`feature`"] then stop searching and return that value.
///
/// 2.2 Look-up the value, treating `feature` as a builtin feature.
/// I.e., if there is a value (not a default value) associated with `option_name` in a
/// builtin feature named `feature`, then stop searching and return that value.
/// Otherwise, record the default value and continue searching.
///
/// 3. Return the last default value that was encountered.
pub fn get_option_value<T>(
option_name: &str,
builtin_features: &HashMap<String, features::BuiltinFeature>,
opt: &cli::Opt,
git_config: &mut Option<git_config::GitConfig>,
) -> Option<T>
where
T: GitConfigGet,
T: GetOptionValue,
T: From<OptionValue>,
T: Into<OptionValue>,
{
T::get_option_value(option_name, builtin_features, opt, git_config)
}
pub trait GetOptionValue {
fn get_option_value(
option_name: &str,
builtin_features: &HashMap<String, features::BuiltinFeature>,
opt: &cli::Opt,
git_config: &mut Option<git_config::GitConfig>,
) -> Option<Self>
where
Self: Sized,
Self: GitConfigGet,
Self: From<OptionValue>,
Self: Into<OptionValue>,
{
if let Some(git_config) = git_config {
if let Some(value) = git_config.get::<Self>(&format!("delta.{}", option_name)) {
return Some(value);
}
}
for feature in opt.features.to_lowercase().split_whitespace().rev() {
match Self::get_provenanced_value_for_feature(
option_name,
&feature,
&builtin_features,
opt,
git_config,
) {
Some(GitConfigValue(value)) | Some(DefaultValue(value)) => {
return Some(value.into());
}
None => {}
}
}
None
}
/// Return the value, or default value, associated with `option_name` under feature name
/// `feature`. This may refer to a custom feature, or a builtin feature, or both. Only builtin
/// features have defaults. See `GetOptionValue::get_option_value`.
fn get_provenanced_value_for_feature(
option_name: &str,
feature: &str,
builtin_features: &HashMap<String, features::BuiltinFeature>,
opt: &cli::Opt,
git_config: &mut Option<git_config::GitConfig>,
) -> Option<ProvenancedOptionValue>
where
Self: Sized,
Self: GitConfigGet,
Self: Into<OptionValue>,
{
if let Some(git_config) = git_config {
if let Some(value) =
git_config.get::<Self>(&format!("delta.{}.{}", feature, option_name))
{
return Some(GitConfigValue(value.into()));
}
}
if let Some(builtin_feature) = builtin_features.get(feature) {
if let Some(value_function) = builtin_feature.get(option_name) {
return Some(value_function(opt, &git_config));
}
}
None
}
}
impl GetOptionValue for Option<String> {}
impl GetOptionValue for String {}
impl GetOptionValue for bool {}
impl GetOptionValue for f64 {}
impl GetOptionValue for usize {}