]> git.lizzy.rs Git - rust.git/blob - crates/ra_ide_api/src/feature_flags.rs
Implement postfix completions feature flag
[rust.git] / crates / ra_ide_api / src / feature_flags.rs
1 //! FIXME: write short doc here
2
3 use rustc_hash::FxHashMap;
4
5 /// Feature flags hold fine-grained toggles for all *user-visible* features of
6 /// rust-analyzer.
7 ///
8 /// The exists such that users are able to disable any annoying feature (and,
9 /// with many users and many features,  some features are bound to be annoying
10 /// for some users)
11 ///
12 /// Note that we purposefully use run-time checked strings, and not something
13 /// checked at compile time, to keep things simple and flexible.
14 ///
15 /// Also note that, at the moment, `FeatureFlags` also store features for
16 /// `ra_lsp_server`. This should be benign layering violation.
17 #[derive(Debug)]
18 pub struct FeatureFlags {
19     flags: FxHashMap<String, bool>,
20 }
21
22 impl FeatureFlags {
23     fn new(flags: &[(&str, bool)]) -> FeatureFlags {
24         let flags = flags
25             .iter()
26             .map(|&(name, value)| {
27                 check_flag_name(name);
28                 (name.to_string(), value)
29             })
30             .collect();
31         FeatureFlags { flags }
32     }
33
34     pub fn set(&mut self, flag: &str, value: bool) -> Result<(), ()> {
35         match self.flags.get_mut(flag) {
36             None => Err(()),
37             Some(slot) => {
38                 *slot = value;
39                 Ok(())
40             }
41         }
42     }
43
44     pub fn get(&self, flag: &str) -> bool {
45         match self.flags.get(flag) {
46             None => panic!("unknown flag: {:?}", flag),
47             Some(value) => *value,
48         }
49     }
50 }
51
52 impl Default for FeatureFlags {
53     fn default() -> FeatureFlags {
54         FeatureFlags::new(&[
55             ("lsp.diagnostics", true),
56             ("completion.insertion.add-call-parenthesis", true),
57             ("completion.enable-postfix", true),
58             ("notifications.workspace-loaded", true),
59         ])
60     }
61 }
62
63 fn check_flag_name(flag: &str) {
64     for c in flag.bytes() {
65         match c {
66             b'a'..=b'z' | b'-' | b'.' => (),
67             _ => panic!("flag name does not match conventions: {:?}", flag),
68         }
69     }
70 }