diff options
author | Matthias Beyer <mail@beyermatthias.de> | 2021-03-19 09:38:17 +0100 |
---|---|---|
committer | Matthias Beyer <mail@beyermatthias.de> | 2021-11-21 12:20:21 +0100 |
commit | 3c1a0ffb4b57bcaaee399625a4e20d4f3c0c96aa (patch) | |
tree | e7d24288c59629aa439e965899cccf61ddb36824 /src/value.rs | |
parent | 9b187e655f25f7386be4b96a707dfb3867ff309b (diff) |
Add support for unsigned integers
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
Diffstat (limited to 'src/value.rs')
-rw-r--r-- | src/value.rs | 193 |
1 files changed, 192 insertions, 1 deletions
diff --git a/src/value.rs b/src/value.rs index a2a5785..6825284 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), |