aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/feature_flags.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-08-22 12:44:16 +0100
committerAleksey Kladov <[email protected]>2019-08-22 13:07:31 +0100
commit69bbe79c5037eb3cd00744593d1836e45a6f56e1 (patch)
treefc48327d9d70b320c60e6c9fc19fdc5bdbff88f9 /crates/ra_ide_api/src/feature_flags.rs
parent4dd5afb7fe2eb20748ade9141e74b04f5dd2f922 (diff)
implement feature flags
Diffstat (limited to 'crates/ra_ide_api/src/feature_flags.rs')
-rw-r--r--crates/ra_ide_api/src/feature_flags.rs67
1 files changed, 67 insertions, 0 deletions
diff --git a/crates/ra_ide_api/src/feature_flags.rs b/crates/ra_ide_api/src/feature_flags.rs
new file mode 100644
index 000000000..9f82ac71c
--- /dev/null
+++ b/crates/ra_ide_api/src/feature_flags.rs
@@ -0,0 +1,67 @@
1use rustc_hash::FxHashMap;
2
3/// Feature flags hold fine-grained toggles for all *user-visible* features of
4/// rust-analyzer.
5///
6/// The exists such that users are able to disable any annoying feature (and,
7/// with many users and many features, some features are bound to be annoying
8/// for some users)
9///
10/// Note that we purposefully use run-time checked strings, and not something
11/// checked at compile time, to keep things simple and flexible.
12///
13/// Also note that, at the moment, `FeatureFlags` also store features for
14/// `ra_lsp_server`. This should be benign layering violation.
15#[derive(Debug)]
16pub struct FeatureFlags {
17 flags: FxHashMap<String, bool>,
18}
19
20impl FeatureFlags {
21 fn new(flags: &[(&str, bool)]) -> FeatureFlags {
22 let flags = flags
23 .iter()
24 .map(|&(name, value)| {
25 check_flag_name(name);
26 (name.to_string(), value)
27 })
28 .collect();
29 FeatureFlags { flags }
30 }
31
32 pub fn set(&mut self, flag: &str, value: bool) -> Result<(), ()> {
33 match self.flags.get_mut(flag) {
34 None => Err(()),
35 Some(slot) => {
36 *slot = value;
37 Ok(())
38 }
39 }
40 }
41
42 pub fn get(&self, flag: &str) -> bool {
43 match self.flags.get(flag) {
44 None => panic!("unknown flag: {:?}", flag),
45 Some(value) => *value,
46 }
47 }
48}
49
50impl Default for FeatureFlags {
51 fn default() -> FeatureFlags {
52 FeatureFlags::new(&[
53 ("lsp.diagnostics", true),
54 ("completion.insertion.add-call-parenthesis", true),
55 ("notifications.workspace-loaded", true),
56 ])
57 }
58}
59
60fn check_flag_name(flag: &str) {
61 for c in flag.bytes() {
62 match c {
63 b'a'..=b'z' | b'-' | b'.' => (),
64 _ => panic!("flag name does not match conventions: {:?}", flag),
65 }
66 }
67}