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
|
use rustc_hash::FxHashMap;
/// Feature flags hold fine-grained toggles for all *user-visible* features of
/// rust-analyzer.
///
/// The exists such that users are able to disable any annoying feature (and,
/// with many users and many features, some features are bound to be annoying
/// for some users)
///
/// Note that we purposefully use run-time checked strings, and not something
/// checked at compile time, to keep things simple and flexible.
///
/// Also note that, at the moment, `FeatureFlags` also store features for
/// `ra_lsp_server`. This should be benign layering violation.
#[derive(Debug)]
pub struct FeatureFlags {
flags: FxHashMap<String, bool>,
}
impl FeatureFlags {
fn new(flags: &[(&str, bool)]) -> FeatureFlags {
let flags = flags
.iter()
.map(|&(name, value)| {
check_flag_name(name);
(name.to_string(), value)
})
.collect();
FeatureFlags { flags }
}
pub fn set(&mut self, flag: &str, value: bool) -> Result<(), ()> {
match self.flags.get_mut(flag) {
None => Err(()),
Some(slot) => {
*slot = value;
Ok(())
}
}
}
pub fn get(&self, flag: &str) -> bool {
match self.flags.get(flag) {
None => panic!("unknown flag: {:?}", flag),
Some(value) => *value,
}
}
}
impl Default for FeatureFlags {
fn default() -> FeatureFlags {
FeatureFlags::new(&[
("lsp.diagnostics", true),
("completion.insertion.add-call-parenthesis", true),
("notifications.workspace-loaded", true),
])
}
}
fn check_flag_name(flag: &str) {
for c in flag.bytes() {
match c {
b'a'..=b'z' | b'-' | b'.' => (),
_ => panic!("flag name does not match conventions: {:?}", flag),
}
}
}
|