summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2021-03-19 09:38:17 +0100
committerMatthias Beyer <mail@beyermatthias.de>2021-07-10 15:36:15 +0200
commit30df24333b21cea57aa2bbab96ec7bb450346eea (patch)
tree43c50132d468021fcdc8aba47a1a115bc399b597
parent2b14af663470354cc25b075a5b787c54d6c5d93e (diff)
Add support for unsigned integersintegers
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
-rw-r--r--src/de.rs4
-rw-r--r--src/error.rs4
-rw-r--r--src/value.rs193
3 files changed, 200 insertions, 1 deletions
diff --git a/src/de.rs b/src/de.rs
index c439da0..4736deb 100644
--- a/src/de.rs
+++ b/src/de.rs
@@ -20,6 +20,8 @@ impl<'de> de::Deserializer<'de> for Value {
ValueKind::Nil => visitor.visit_unit(),
ValueKind::I64(i) => visitor.visit_i64(i),
ValueKind::I128(i) => visitor.visit_i128(i),
+ ValueKind::U64(i) => visitor.visit_u64(i),
+ ValueKind::U128(i) => visitor.visit_u128(i),
ValueKind::Boolean(b) => visitor.visit_bool(b),
ValueKind::Float(f) => visitor.visit_f64(f),
ValueKind::String(s) => visitor.visit_string(s),
@@ -347,6 +349,8 @@ impl<'de> de::Deserializer<'de> for Config {
ValueKind::Nil => visitor.visit_unit(),
ValueKind::I64(i) => visitor.visit_i64(i),
ValueKind::I128(i) => visitor.visit_i128(i),
+ ValueKind::U64(i) => visitor.visit_u64(i),
+ ValueKind::U128(i) => visitor.visit_u128(i),
ValueKind::Boolean(b) => visitor.visit_bool(b),
ValueKind::Float(f) => visitor.visit_f64(f),
ValueKind::String(s) => visitor.visit_string(s),
diff --git a/src/error.rs b/src/error.rs
index db5813e..84984ba 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -10,6 +10,8 @@ pub enum Unexpected {
Bool(bool),
I64(i64),
I128(i128),
+ U64(u64),
+ U128(u128),
Float(f64),
Str(String),
Unit,
@@ -23,6 +25,8 @@ impl fmt::Display for Unexpected {
Unexpected::Bool(b) => write!(f, "boolean `{}`", b),
Unexpected::I64(i) => write!(f, "integer 64 bit `{}`", i),
Unexpected::I128(i) => write!(f, "integer 128 bit `{}`", i),
+ Unexpected::U64(i) => write!(f, "unsigned integer 64 bit `{}`", i),
+ Unexpected::U128(i) => write!(f, "unsigned integer 128 bit `{}`", i),
Unexpected::Float(v) => write!(f, "floating point `{}`", v),
Unexpected::Str(ref s) => write!(f, "string {:?}", s),
Unexpected::Unit => write!(f, "unit value"),
diff --git a/src/value.rs b/src/value.rs
index a57f899..da70714 100644
--- a/src/value.rs
+++ b/src/value.rs
@@ -17,6 +17,8 @@ pub enum ValueKind {
Boolean(bool),
I64(i64),
I128(i128),
+ U64(u64),
+ U128(u128),
Float(f64),
String(String),
Table(Table),
@@ -86,6 +88,36 @@ impl From<i128> for ValueKind {
}
}
+impl From<u8> for ValueKind {
+ fn from(value: u8) -> Self {
+ ValueKind::U64(value as u64)
+ }
+}
+
+impl From<u16> for ValueKind {
+ fn from(value: u16) -> Self {
+ ValueKind::U64(value as u64)
+ }
+}
+
+impl From<u32> for ValueKind {
+ fn from(value: u32) -> Self {
+ ValueKind::U64(value as u64)
+ }
+}
+
+impl From<u64> for ValueKind {
+ fn from(value: u64) -> Self {
+ ValueKind::U64(value)
+ }
+}
+
+impl From<u128> for ValueKind {
+ fn from(value: u128) -> Self {
+ ValueKind::U128(value)
+ }
+}
+
impl From<f64> for ValueKind {
fn from(value: f64) -> Self {
ValueKind::Float(value)
@@ -124,6 +156,8 @@ impl Display for ValueKind {
ValueKind::Boolean(value) => write!(f, "{}", value),
ValueKind::I64(value) => write!(f, "{}", value),
ValueKind::I128(value) => write!(f, "{}", value),
+ ValueKind::U64(value) => write!(f, "{}", value),
+ ValueKind::U128(value) => write!(f, "{}", value),
ValueKind::Float(value) => write!(f, "{}", value),
ValueKind::Nil => write!(f, "nil"),
ValueKind::Table(ref table) => write!(f, "{{ {} }}", {
@@ -188,6 +222,8 @@ impl Value {
ValueKind::Boolean(value) => Ok(value),
ValueKind::I64(value) => Ok(value != 0),
ValueKind::I128(value) => Ok(value != 0),
+ ValueKind::U64(value) => Ok(value != 0),
+ ValueKind::U128(value) => Ok(value != 0),
ValueKind::Float(value) => Ok(value != 0.0),
ValueKind::String(ref value) => {
@@ -231,7 +267,17 @@ impl Value {
ValueKind::I128(value) => Err(ConfigError::invalid_type(
self.origin,
Unexpected::I128(value),
- "an 64 bit or less integer",
+ "an signed 64 bit or less integer",
+ )),
+ ValueKind::U64(value) => Err(ConfigError::invalid_type(
+ self.origin,
+ Unexpected::U64(value),
+ "an signed 64 bit or less integer",
+ )),
+ ValueKind::U128(value) => Err(ConfigError::invalid_type(
+ self.origin,
+ Unexpected::U128(value),
+ "an signed 64 bit or less integer",
)),
ValueKind::String(ref s) => {
@@ -278,6 +324,12 @@ impl Value {
match self.kind {
ValueKind::I64(value) => Ok(value as i128),
ValueKind::I128(value) => Ok(value),
+ ValueKind::U64(value) => Ok(value as i128),
+ ValueKind::U128(value) => Err(ConfigError::invalid_type(
+ self.origin,
+ Unexpected::U128(value),
+ "an signed 128 bit integer",
+ )),
ValueKind::String(ref s) => {
match s.to_lowercase().as_ref() {
@@ -318,6 +370,121 @@ impl Value {
}
}
+ /// Returns `self` into an u64, if possible.
+ // FIXME: Should this not be `try_into_*` ?
+ pub fn into_uint(self) -> Result<u64> {
+ match self.kind {
+ ValueKind::U64(value) => Ok(value),
+ ValueKind::U128(value) => Err(ConfigError::invalid_type(
+ self.origin,
+ Unexpected::U128(value),
+ "an unsigned 64 bit or less integer",
+ )),
+ ValueKind::I64(value) => Err(ConfigError::invalid_type(
+ self.origin,
+ Unexpected::I64(value),
+ "an unsigned 64 bit or less integer",
+ )),
+ ValueKind::I128(value) => Err(ConfigError::invalid_type(
+ self.origin,
+ Unexpected::I128(value),
+ "an unsigned 64 bit or less integer",
+ )),
+
+ ValueKind::String(ref s) => {
+ match s.to_lowercase().as_ref() {
+ "true" | "on" | "yes" => Ok(1),
+ "false" | "off" | "no" => Ok(0),
+ _ => {
+ s.parse().map_err(|_| {
+ // Unexpected string
+ ConfigError::invalid_type(
+ self.origin.clone(),
+ Unexpected::Str(s.clone()),
+ "an integer",
+ )
+ })
+ }
+ }
+ }
+
+ ValueKind::Boolean(value) => Ok(if value { 1 } else { 0 }),
+ ValueKind::Float(value) => Ok(value.round() as u64),
+
+ // Unexpected type
+ ValueKind::Nil => Err(ConfigError::invalid_type(
+ self.origin,
+ Unexpected::Unit,
+ "an integer",
+ )),
+ ValueKind::Table(_) => Err(ConfigError::invalid_type(
+ self.origin,
+ Unexpected::Map,
+ "an integer",
+ )),
+ ValueKind::Array(_) => Err(ConfigError::invalid_type(
+ self.origin,
+ Unexpected::Seq,
+ "an integer",
+ )),
+ }
+ }
+
+ /// Returns `self` into an u128, if possible.
+ pub fn into_uint128(self) -> Result<u128> {
+ match self.kind {
+ ValueKind::U64(value) => Ok(value as u128),
+ ValueKind::U128(value) => Ok(value),
+ ValueKind::I64(value) => Err(ConfigError::invalid_type(
+ self.origin,
+ Unexpected::I64(value),
+ "an unsigned 128 bit or less integer",
+ )),
+ ValueKind::I128(value) => Err(ConfigError::invalid_type(
+ self.origin,
+ Unexpected::I128(value),
+ "an unsigned 128 bit or less integer",
+ )),
+
+ ValueKind::String(ref s) => {
+ match s.to_lowercase().as_ref() {
+ "true" | "on" | "yes" => Ok(1),
+ "false" | "off" | "no" => Ok(0),
+ _ => {
+ s.parse().map_err(|_| {
+ // Unexpected string
+ ConfigError::invalid_type(
+ self.origin.clone(),
+ Unexpected::Str(s.clone()),
+ "an integer",
+ )
+ })
+ }
+ }
+ }
+
+ ValueKind::Boolean(value) => Ok(if value { 1 } else { 0 }),
+ ValueKind::Float(value) => Ok(value.round() as u128),
+
+ // Unexpected type
+ ValueKind::Nil => Err(ConfigError::invalid_type(
+ self.origin,
+ Unexpected::Unit,
+ "an integer",
+ )),
+ ValueKind::Table(_) => Err(ConfigError::invalid_type(
+ self.origin,
+ Unexpected::Map,
+ "an integer",
+ )),
+ ValueKind::Array(_) => Err(ConfigError::invalid_type(
+ self.origin,
+ Unexpected::Seq,
+ "an integer",
+ )),
+ }
+ }
+
/// Returns `self` into a f64, if possible.
// FIXME: Should this not be `try_into_*` ?
pub fn into_float(self) -> Result<f64> {
@@ -343,6 +510,8 @@ impl Value {
ValueKind::I64(value) => Ok(value as f64),
ValueKind::I128(value) => Ok(value as f64),
+ ValueKind::U64(value) => Ok(value as f64),
+ ValueKind::U128(value) => Ok(value as f64),
ValueKind::Boolean(value) => Ok(if value { 1.0 } else { 0.0 }),
// Unexpected type
@@ -373,6 +542,8 @@ impl Value {
ValueKind::Boolean(value) => Ok(value.to_string()),
ValueKind::I64(value) => Ok(value.to_string()),
ValueKind::I128(value) => Ok(value.to_string()),
+ ValueKind::U64(value) => Ok(value.to_string()),
+ ValueKind::U128(value) => Ok(value.to_string()),
ValueKind::Float(value) => Ok(value.to_string()),
// Cannot convert
@@ -421,6 +592,16 @@ impl Value {
Unexpected::I128(value),
"an array",
)),
+ ValueKind::U64(value) => Err(ConfigError::invalid_type(
+ self.origin,
+ Unexpected::U64(value),
+ "an array",
+ )),
+ ValueKind::U128(value) => Err(ConfigError::invalid_type(
+ self.origin,
+ Unexpected::U128(value),
+ "an array",
+ )),
ValueKind::Boolean(value) => Err(ConfigError::invalid_type(
self.origin,
Unexpected::Bool(value),
@@ -466,6 +647,16 @@ impl Value {
Unexpected::I128(value),
"a map",
)),
+ ValueKind::U64(value) => Err(ConfigError::invalid_type(
+ self.origin,
+ Unexpected::U64(value),
+ "a map",
+ )),
+ ValueKind::U128(value) => Err(ConfigError::invalid_type(
+ self.origin,
+ Unexpected::U128(value),
+ "a map",
+ )),
ValueKind::Boolean(value) => Err(ConfigError::invalid_type(
self.origin,
Unexpected::Bool(value),