use crate::Error;
use serde::{Deserialize, Serialize};
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug, Hash)]
pub enum ValueType {
Bool,
Fixed,
Float,
Currency,
U8,
U16,
U32,
U64,
I8,
I16,
I32,
I64,
Int,
String,
Range,
Array,
Object,
Numeric,
Collection,
Any,
}
impl Serialize for ValueType {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(self.to_string().as_str())
}
}
impl<'de> Deserialize<'de> for ValueType {
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let s = String::deserialize(deserializer)?;
ValueType::try_from(s.as_str()).map_err(serde::de::Error::custom)
}
}
impl std::fmt::Display for ValueType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ValueType::Bool => write!(f, "bool"),
ValueType::Fixed => write!(f, "fixed"),
ValueType::Float => write!(f, "float"),
ValueType::Currency => write!(f, "currency"),
ValueType::U8 => write!(f, "u8"),
ValueType::U16 => write!(f, "u16"),
ValueType::U32 => write!(f, "u32"),
ValueType::U64 => write!(f, "u64"),
ValueType::I8 => write!(f, "i8"),
ValueType::I16 => write!(f, "i16"),
ValueType::I32 => write!(f, "i32"),
ValueType::I64 => write!(f, "i64"),
ValueType::Int => write!(f, "int"),
ValueType::String => write!(f, "string"),
ValueType::Range => write!(f, "range"),
ValueType::Array => write!(f, "array"),
ValueType::Object => write!(f, "object"),
ValueType::Numeric => write!(f, "numeric"),
ValueType::Collection => write!(f, "collection"),
ValueType::Any => write!(f, "any"),
}
}
}
impl TryFrom<&str> for ValueType {
type Error = Error;
fn try_from(s: &str) -> Result<Self, Error> {
match s.to_lowercase().as_str() {
"bool" => Ok(ValueType::Bool),
"fixed" => Ok(ValueType::Fixed),
"float" => Ok(ValueType::Float),
"currency" => Ok(ValueType::Currency),
"u8" => Ok(ValueType::U8),
"u16" => Ok(ValueType::U16),
"u32" => Ok(ValueType::U32),
"u64" => Ok(ValueType::U64),
"i8" => Ok(ValueType::I8),
"i16" => Ok(ValueType::I16),
"i32" => Ok(ValueType::I32),
"i64" => Ok(ValueType::I64),
"int" => Ok(ValueType::Int),
"string" => Ok(ValueType::String),
"range" => Ok(ValueType::Range),
"array" => Ok(ValueType::Array),
"object" => Ok(ValueType::Object),
"numeric" => Ok(ValueType::Numeric),
"collection" => Ok(ValueType::Collection),
"any" => Ok(ValueType::Any),
_ => Err(Error::UnrecognizedType(s.to_string())),
}
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_valuetype() {
let serialized = serde_json::to_string(&ValueType::Bool).unwrap();
let deserialized: ValueType = serde_json::from_str(&serialized).unwrap();
assert_eq!(deserialized, ValueType::Bool);
assert_eq!(format!("{}", ValueType::Bool), "bool");
assert_eq!(format!("{}", ValueType::Fixed), "fixed");
assert_eq!(format!("{}", ValueType::Float), "float");
assert_eq!(format!("{}", ValueType::Currency), "currency");
assert_eq!(format!("{}", ValueType::Int), "int");
assert_eq!(format!("{}", ValueType::String), "string");
assert_eq!(format!("{}", ValueType::Array), "array");
assert_eq!(format!("{}", ValueType::Object), "object");
assert_eq!(format!("{}", ValueType::Range), "range");
assert_eq!(format!("{}", ValueType::Collection), "collection");
assert_eq!(format!("{}", ValueType::Numeric), "numeric");
assert_eq!(format!("{}", ValueType::Any), "any");
assert_eq!(format!("{}", ValueType::U8), "u8");
assert_eq!(format!("{}", ValueType::U16), "u16");
assert_eq!(format!("{}", ValueType::U32), "u32");
assert_eq!(format!("{}", ValueType::U64), "u64");
assert_eq!(format!("{}", ValueType::I8), "i8");
assert_eq!(format!("{}", ValueType::I16), "i16");
assert_eq!(format!("{}", ValueType::I32), "i32");
assert_eq!(format!("{}", ValueType::I64), "i64");
assert_eq!(ValueType::try_from("bool").unwrap(), ValueType::Bool);
assert_eq!(ValueType::try_from("Bool").unwrap(), ValueType::Bool);
assert_eq!(ValueType::try_from("fixed").unwrap(), ValueType::Fixed);
assert_eq!(ValueType::try_from("float").unwrap(), ValueType::Float);
assert_eq!(
ValueType::try_from("currency").unwrap(),
ValueType::Currency
);
assert_eq!(ValueType::try_from("int").unwrap(), ValueType::Int);
assert_eq!(ValueType::try_from("string").unwrap(), ValueType::String);
assert_eq!(ValueType::try_from("array").unwrap(), ValueType::Array);
assert_eq!(ValueType::try_from("object").unwrap(), ValueType::Object);
assert_eq!(ValueType::try_from("range").unwrap(), ValueType::Range);
assert_eq!(
ValueType::try_from("collection").unwrap(),
ValueType::Collection
);
assert_eq!(ValueType::try_from("numeric").unwrap(), ValueType::Numeric);
assert_eq!(ValueType::try_from("any").unwrap(), ValueType::Any);
ValueType::try_from("poo").unwrap_err();
}
}