diff options
Diffstat (limited to 'crates/ra_project_model/src/cfg_flag.rs')
-rw-r--r-- | crates/ra_project_model/src/cfg_flag.rs | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/crates/ra_project_model/src/cfg_flag.rs b/crates/ra_project_model/src/cfg_flag.rs new file mode 100644 index 000000000..1bc5d4832 --- /dev/null +++ b/crates/ra_project_model/src/cfg_flag.rs | |||
@@ -0,0 +1,51 @@ | |||
1 | //! Parsing of CfgFlags as command line arguments, as in | ||
2 | //! | ||
3 | //! rustc main.rs --cfg foo --cfg 'feature="bar"' | ||
4 | use std::str::FromStr; | ||
5 | |||
6 | use ra_cfg::CfgOptions; | ||
7 | use stdx::split_delim; | ||
8 | |||
9 | #[derive(Clone, Eq, PartialEq, Debug)] | ||
10 | pub enum CfgFlag { | ||
11 | Atom(String), | ||
12 | KeyValue { key: String, value: String }, | ||
13 | } | ||
14 | |||
15 | impl FromStr for CfgFlag { | ||
16 | type Err = String; | ||
17 | fn from_str(s: &str) -> Result<Self, Self::Err> { | ||
18 | let res = match split_delim(s, '=') { | ||
19 | Some((key, value)) => { | ||
20 | if !(value.starts_with('"') && value.ends_with('"')) { | ||
21 | return Err(format!("Invalid cfg ({:?}), value should be in quotes", s)); | ||
22 | } | ||
23 | let key = key.to_string(); | ||
24 | let value = value[1..value.len() - 1].to_string(); | ||
25 | CfgFlag::KeyValue { key, value } | ||
26 | } | ||
27 | None => CfgFlag::Atom(s.into()), | ||
28 | }; | ||
29 | Ok(res) | ||
30 | } | ||
31 | } | ||
32 | |||
33 | impl<'de> serde::Deserialize<'de> for CfgFlag { | ||
34 | fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> | ||
35 | where | ||
36 | D: serde::Deserializer<'de>, | ||
37 | { | ||
38 | String::deserialize(deserializer)?.parse().map_err(serde::de::Error::custom) | ||
39 | } | ||
40 | } | ||
41 | |||
42 | impl Extend<CfgFlag> for CfgOptions { | ||
43 | fn extend<T: IntoIterator<Item = CfgFlag>>(&mut self, iter: T) { | ||
44 | for cfg_flag in iter { | ||
45 | match cfg_flag { | ||
46 | CfgFlag::Atom(it) => self.insert_atom(it.into()), | ||
47 | CfgFlag::KeyValue { key, value } => self.insert_key_value(key.into(), value.into()), | ||
48 | } | ||
49 | } | ||
50 | } | ||
51 | } | ||