Drop num_traits and rely on serde to handle numeric limits.

This commit is contained in:
Eric Huss 2018-05-22 15:06:06 -07:00
parent 5b44581a69
commit 7c0b5fae8a
4 changed files with 66 additions and 48 deletions

View File

@ -30,7 +30,6 @@ extern crate libgit2_sys;
#[macro_use]
extern crate log;
extern crate num_cpus;
extern crate num_traits;
extern crate same_file;
extern crate semver;
#[macro_use]

View File

@ -19,7 +19,6 @@ use curl::easy::Easy;
use failure;
use jobserver;
use lazycell::LazyCell;
use num_traits;
use serde::{de, de::IntoDeserializer, Serialize, Serializer};
use toml;
@ -494,49 +493,18 @@ impl Config {
.map_err(|e| e.into())
}
fn get_integer<T>(&self, key: &ConfigKey) -> Result<Option<Value<T>>, ConfigError>
where
T: FromStr + num_traits::NumCast + num_traits::Bounded + num_traits::Zero + fmt::Display,
<T as FromStr>::Err: fmt::Display,
{
fn get_integer(&self, key: &ConfigKey) -> Result<Option<Value<i64>>, ConfigError> {
let config_key = key.to_config();
let v = match self.get_env::<i64>(key)? {
Some(v) => v,
match self.get_env::<i64>(key)? {
Some(v) => Ok(Some(v)),
None => match self.get_cv(&config_key)? {
Some(CV::Integer(i, path)) => Value {
Some(CV::Integer(i, path)) => Ok(Some(Value {
val: i,
definition: Definition::Path(path),
},
})),
Some(cv) => return Err(ConfigError::expected(&config_key, "an integer", &cv)),
None => return Ok(None),
},
};
// Attempt to cast to the correct type, otherwise return a helpful
// error message.
match num_traits::cast(v.val) {
Some(casted_v) => Ok(Some(Value {
val: casted_v,
definition: v.definition,
})),
None => {
if T::min_value().is_zero() && v.val < 0 {
Err(ConfigError::new(
format!("`{}` must be positive, found {}", config_key, v.val),
v.definition,
))
} else {
Err(ConfigError::new(
format!(
"`{}` is too large (min/max {}/{}), found {}",
config_key,
T::min_value(),
T::max_value(),
v.val
),
v.definition,
))
}
}
}
}
@ -1043,14 +1011,14 @@ impl<'de, 'config> de::Deserializer<'de> for Deserializer<'config> {
}
deserialize_method!(deserialize_bool, visit_bool, get_bool_priv);
deserialize_method!(deserialize_i8, visit_i8, get_integer);
deserialize_method!(deserialize_i16, visit_i16, get_integer);
deserialize_method!(deserialize_i32, visit_i32, get_integer);
deserialize_method!(deserialize_i8, visit_i64, get_integer);
deserialize_method!(deserialize_i16, visit_i64, get_integer);
deserialize_method!(deserialize_i32, visit_i64, get_integer);
deserialize_method!(deserialize_i64, visit_i64, get_integer);
deserialize_method!(deserialize_u8, visit_u8, get_integer);
deserialize_method!(deserialize_u16, visit_u16, get_integer);
deserialize_method!(deserialize_u32, visit_u32, get_integer);
deserialize_method!(deserialize_u64, visit_u64, get_integer);
deserialize_method!(deserialize_u8, visit_i64, get_integer);
deserialize_method!(deserialize_u16, visit_i64, get_integer);
deserialize_method!(deserialize_u32, visit_i64, get_integer);
deserialize_method!(deserialize_u64, visit_i64, get_integer);
deserialize_method!(deserialize_string, visit_string, get_string_priv);
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>

View File

@ -241,7 +241,9 @@ fn bad_cargo_config_jobs() {
execs()
.with_status(101)
.with_stderr("\
[ERROR] error in [..].cargo[/]config: `build.jobs` must be positive, found -1
[ERROR] error in [..].cargo[/]config: \
could not load config key `build.jobs`: \
invalid value: integer `-1`, expected u32
"),
);
}

View File

@ -361,7 +361,8 @@ big = 123456789
);
assert_error(
config.get::<u8>("S.big").unwrap_err(),
"error in [..][/].cargo[/]config: `S.big` is too large (min/max 0/255), found 123456789",
"error in [..].cargo[/]config: could not load config key `S.big`: \
invalid value: integer `123456789`, expected u8",
);
// Environment variable type errors.
@ -372,7 +373,8 @@ big = 123456789
assert_error(
config.get::<i8>("e.big").unwrap_err(),
"error in environment variable `CARGO_E_BIG`: \
`e.big` is too large (min/max -128/127), found 123456789",
could not load config key `e.big`: \
invalid value: integer `123456789`, expected i8",
);
#[derive(Debug, Deserialize)]
@ -620,3 +622,50 @@ abs = '{}'
paths::root().join("a/b")
);
}
#[test]
fn config_get_integers() {
write_config(
"\
npos = 123456789
nneg = -123456789
i64max = 9223372036854775807
",
);
let config = new_config(&[
("CARGO_EPOS", "123456789"),
("CARGO_ENEG", "-1"),
("CARGO_EI64MAX", "9223372036854775807"),
]);
assert_eq!(config.get::<u64>("i64max").unwrap(), 9223372036854775807);
assert_eq!(config.get::<i64>("i64max").unwrap(), 9223372036854775807);
assert_eq!(config.get::<u64>("ei64max").unwrap(), 9223372036854775807);
assert_eq!(config.get::<i64>("ei64max").unwrap(), 9223372036854775807);
assert_error(
config.get::<u32>("nneg").unwrap_err(),
"error in [..].cargo[/]config: \
could not load config key `nneg`: \
invalid value: integer `-123456789`, expected u32",
);
assert_error(
config.get::<u32>("eneg").unwrap_err(),
"error in environment variable `CARGO_ENEG`: \
could not load config key `eneg`: \
invalid value: integer `-1`, expected u32",
);
assert_error(
config.get::<i8>("npos").unwrap_err(),
"error in [..].cargo[/]config: \
could not load config key `npos`: \
invalid value: integer `123456789`, expected i8",
);
assert_error(
config.get::<i8>("epos").unwrap_err(),
"error in environment variable `CARGO_EPOS`: \
could not load config key `epos`: \
invalid value: integer `123456789`, expected i8",
);
}