Skip to content

Commit 729e567

Browse files
committed
Auto merge of #8454 - GabrielMajeri:config-option-enum, r=ehuss
Add support for deserializing enums in config files Implements `deserialize_enum` functionality to allow config options which are Rust enums. @ehuss The code currently has some `todo!`s because I'm not sure how the custom `Deserializer` is supposed to do error handling. Fixes #8450
2 parents 548eea7 + 65fc4ce commit 729e567

File tree

2 files changed

+61
-1
lines changed

2 files changed

+61
-1
lines changed

src/cargo/util/config/de.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,11 +195,31 @@ impl<'de, 'config> de::Deserializer<'de> for Deserializer<'config> {
195195
}
196196
}
197197

198+
fn deserialize_enum<V>(
199+
self,
200+
_name: &'static str,
201+
_variants: &'static [&'static str],
202+
visitor: V,
203+
) -> Result<V::Value, Self::Error>
204+
where
205+
V: de::Visitor<'de>,
206+
{
207+
let value = self
208+
.config
209+
.get_string_priv(&self.key)?
210+
.ok_or_else(|| ConfigError::missing(&self.key))?;
211+
212+
let Value { val, definition } = value;
213+
visitor
214+
.visit_enum(val.into_deserializer())
215+
.map_err(|e: ConfigError| e.with_key_context(&self.key, definition))
216+
}
217+
198218
// These aren't really supported, yet.
199219
serde::forward_to_deserialize_any! {
200220
f32 f64 char str bytes
201221
byte_buf unit unit_struct
202-
enum identifier ignored_any
222+
identifier ignored_any
203223
}
204224
}
205225

tests/testsuite/config.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Tests for config settings.
22
3+
use cargo::core::profiles::Strip;
34
use cargo::core::{enable_nightly_features, Shell};
45
use cargo::util::config::{self, Config, SslVersionConfig, StringList};
56
use cargo::util::interning::InternedString;
@@ -1259,3 +1260,42 @@ fn string_list_advanced_env() {
12591260
"error in environment variable `CARGO_KEY3`: expected string, found integer",
12601261
);
12611262
}
1263+
1264+
#[cargo_test]
1265+
fn parse_enum() {
1266+
write_config(
1267+
"\
1268+
[profile.release]
1269+
strip = 'debuginfo'
1270+
",
1271+
);
1272+
1273+
let config = new_config();
1274+
1275+
let p: toml::TomlProfile = config.get("profile.release").unwrap();
1276+
let strip = p.strip.unwrap();
1277+
assert_eq!(strip, Strip::DebugInfo);
1278+
}
1279+
1280+
#[cargo_test]
1281+
fn parse_enum_fail() {
1282+
write_config(
1283+
"\
1284+
[profile.release]
1285+
strip = 'invalid'
1286+
",
1287+
);
1288+
1289+
let config = new_config();
1290+
1291+
assert_error(
1292+
config
1293+
.get::<toml::TomlProfile>("profile.release")
1294+
.unwrap_err(),
1295+
"\
1296+
error in [..]/.cargo/config: could not load config key `profile.release.strip`
1297+
1298+
Caused by:
1299+
unknown variant `invalid`, expected one of `debuginfo`, `none`, `symbols`",
1300+
);
1301+
}

0 commit comments

Comments
 (0)