Skip to content

Commit

Permalink
Started refactoring on Value and Deserialization
Browse files Browse the repository at this point in the history
  • Loading branch information
impowski committed Mar 10, 2017
1 parent 61fa320 commit fbcc723
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 82 deletions.
52 changes: 17 additions & 35 deletions lib/src/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@ impl de::Deserializer for Value {
type Error = ConfigError;

#[inline]
fn deserialize<V: de::Visitor>(self, visitor: V) -> Result<V::Value> {
fn deserialize<V>(self, visitor: V) -> Result<V::Value>
where V: de::Visitor,
{
// Deserialize based on the underlying type
match self.kind {
ValueKind::Integer(i) => visitor.visit_i64(i),
ValueKind::Boolean(b) => visitor.visit_bool(b),
ValueKind::Float(f) => visitor.visit_f64(f),
// ValueKind::String(Cow::Borrowed(s)) => visitor.visit_str(s),
// ValueKind::String(Cow::Owned(s)) => visitor.visit_string(s),
ValueKind::String(s) => visitor.visit_string(s),
ValueKind::Array(values) => unimplemented!(),
ValueKind::Table(map) => visitor.visit_map(MapVisitor::new(map)),
_ => { unimplemented!(); }
}
Expand All @@ -32,6 +34,12 @@ impl de::Deserializer for Value {

struct StrDeserializer<'a>(&'a str);

impl<'a> StrDeserializer<'a> {
fn new(key: &'a str) -> Self {
StrDeserializer(key)
}
}

impl<'a> de::Deserializer for StrDeserializer<'a> {
type Error = ConfigError;

Expand All @@ -41,35 +49,9 @@ impl<'a> de::Deserializer for StrDeserializer<'a> {
}

forward_to_deserialize! {
bool
u8
u16
u32
u64
i8
i16
i32
i64
f32
f64
char
str
string
bytes
byte_buf
option
unit
unit_struct
newtype_struct
seq
seq_fixed_size
tuple
tuple_struct
map
struct
struct_field
enum
ignored_any
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq
seq_fixed_size bytes byte_buf map struct unit enum newtype_struct
struct_field ignored_any unit_struct tuple_struct tuple option
}
}

Expand All @@ -79,7 +61,7 @@ struct MapVisitor {
}

impl MapVisitor {
fn new(mut table: HashMap<String, Value>) -> MapVisitor {
fn new(mut table: HashMap<String, Value>) -> Self {
MapVisitor { elements: table.drain().collect(), index: 0 }
}
}
Expand All @@ -94,8 +76,8 @@ impl de::MapVisitor for MapVisitor {
return Ok(None);
}

let ref key_s = self.elements[0].0;
let key_de = StrDeserializer(&key_s);
let key_s = &self.elements[0].0;
let key_de = StrDeserializer(key_s);
let key = de::DeserializeSeed::deserialize(seed, key_de)?;

Ok(Some(key))
Expand Down
5 changes: 3 additions & 2 deletions lib/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::error::Error;
use std::borrow::Cow;
use std::result;
use std::fmt;
use serde::de;
Expand Down Expand Up @@ -61,7 +62,7 @@ pub enum ConfigError {
impl ConfigError {
// FIXME: pub(crate)
#[doc(hidden)]
pub fn invalid_type(origin: Option<String>, unexpected: Unexpected, expected: &'static str) -> ConfigError {
pub fn invalid_type(origin: Option<String>, unexpected: Unexpected, expected: &'static str) -> Self {
ConfigError::Type {
origin: origin,
unexpected: unexpected,
Expand Down Expand Up @@ -148,7 +149,7 @@ impl Error for ConfigError {
}

impl de::Error for ConfigError {
fn custom<T: fmt::Display>(msg: T) -> ConfigError {
fn custom<T: fmt::Display>(msg: T) -> Self {
ConfigError::Message(msg.to_string())
}
}
92 changes: 47 additions & 45 deletions lib/src/value.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use std::borrow::Cow;
use std::collections::HashMap;
use std::fmt::Display;
use error::*;
Expand All @@ -7,14 +6,17 @@ use error::*;
#[derive(Debug, Clone)]
pub enum ValueKind {
Nil,
String(String),
Boolean(bool),
Integer(i64),
Float(f64),
Boolean(bool),
Table(HashMap<String, Value>),
Array(Vec<Value>),
String(String),
Table(Table),
Array(Array),
}

pub type Array = Vec<Value>;
pub type Table = HashMap<String, Value>;

impl Default for ValueKind {
fn default() -> Self {
ValueKind::Nil
Expand All @@ -24,7 +26,7 @@ impl Default for ValueKind {
impl<T> From<Option<T>> for ValueKind
where T: Into<ValueKind>
{
fn from(value: Option<T>) -> ValueKind {
fn from(value: Option<T>) -> Self {
match value {
Some(value) => value.into(),
None => ValueKind::Nil,
Expand All @@ -33,39 +35,39 @@ impl<T> From<Option<T>> for ValueKind
}

impl From<String> for ValueKind {
fn from(value: String) -> ValueKind {
fn from(value: String) -> Self {
ValueKind::String(value.into())
}
}

impl<'a> From<&'a str> for ValueKind {
fn from(value: &'a str) -> ValueKind {
fn from(value: &'a str) -> Self {
ValueKind::String(value.into())
}
}

impl From<i64> for ValueKind {
fn from(value: i64) -> ValueKind {
fn from(value: i64) -> Self {
ValueKind::Integer(value)
}
}

impl From<f64> for ValueKind {
fn from(value: f64) -> ValueKind {
fn from(value: f64) -> Self {
ValueKind::Float(value)
}
}

impl From<bool> for ValueKind {
fn from(value: bool) -> ValueKind {
fn from(value: bool) -> Self {
ValueKind::Boolean(value)
}
}

impl<T> From<HashMap<String, T>> for ValueKind
where T: Into<Value>
{
fn from(values: HashMap<String, T>) -> ValueKind {
fn from(values: HashMap<String, T>) -> Self {
let mut r = HashMap::new();

for (k, v) in values {
Expand All @@ -79,7 +81,7 @@ impl<T> From<HashMap<String, T>> for ValueKind
impl<T> From<Vec<T>> for ValueKind
where T: Into<Value>
{
fn from(values: Vec<T>) -> ValueKind {
fn from(values: Vec<T>) -> Self {
let mut l = Vec::new();

for v in values {
Expand Down Expand Up @@ -116,7 +118,7 @@ pub struct Value {
}

impl Value {
pub fn new<V>(origin: Option<&String>, kind: V) -> Value
pub fn new<V>(origin: Option<&String>, kind: V) -> Self
where V: Into<ValueKind>
{
Value {
Expand All @@ -138,14 +140,14 @@ impl Value {
"0" | "false" | "off" | "no" => Ok(false),

// Unexpected string value
s @ _ => Err(ConfigError::invalid_type(self.origin.clone(), Unexpected::Str(s.into()), &"a boolean")),
s @ _ => Err(ConfigError::invalid_type(self.origin.clone(), Unexpected::Str(s.into()), "a boolean")),
}
}

// Unexpected type
ValueKind::Nil => Err(ConfigError::invalid_type(self.origin.clone(), Unexpected::Unit, &"a boolean")),
ValueKind::Table(_) => Err(ConfigError::invalid_type(self.origin.clone(), Unexpected::Map, &"a boolean")),
ValueKind::Array(_) => Err(ConfigError::invalid_type(self.origin.clone(), Unexpected::Seq, &"a boolean")),
ValueKind::Nil => Err(ConfigError::invalid_type(self.origin.clone(), Unexpected::Unit, "a boolean")),
ValueKind::Table(_) => Err(ConfigError::invalid_type(self.origin.clone(), Unexpected::Map, "a boolean")),
ValueKind::Array(_) => Err(ConfigError::invalid_type(self.origin.clone(), Unexpected::Seq, "a boolean")),
}
}

Expand All @@ -156,16 +158,16 @@ impl Value {

ValueKind::String(ref s) => s.parse().map_err(|_| {
// Unexpected string
ConfigError::invalid_type(self.origin.clone(), Unexpected::Str(s.clone()), &"an integer")
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 i64),

// Unexpected type
ValueKind::Nil => Err(ConfigError::invalid_type(self.origin.clone(), Unexpected::Unit, &"an integer")),
ValueKind::Table(_) => Err(ConfigError::invalid_type(self.origin.clone(), Unexpected::Map, &"an integer")),
ValueKind::Array(_) => Err(ConfigError::invalid_type(self.origin.clone(), Unexpected::Seq, &"an integer")),
ValueKind::Nil => Err(ConfigError::invalid_type(self.origin.clone(), Unexpected::Unit, "an integer")),
ValueKind::Table(_) => Err(ConfigError::invalid_type(self.origin.clone(), Unexpected::Map, "an integer")),
ValueKind::Array(_) => Err(ConfigError::invalid_type(self.origin.clone(), Unexpected::Seq, "an integer")),
}
}

Expand All @@ -176,16 +178,16 @@ impl Value {

ValueKind::String(ref s) => s.parse().map_err(|_| {
// Unexpected string
ConfigError::invalid_type(self.origin.clone(), Unexpected::Str(s.clone()), &"a floating point")
ConfigError::invalid_type(self.origin.clone(), Unexpected::Str(s.clone()), "a floating point")
}),

ValueKind::Integer(value) => Ok(value as f64),
ValueKind::Boolean(value) => Ok(if value { 1.0 } else { 0.0 }),

// Unexpected type
ValueKind::Nil => Err(ConfigError::invalid_type(self.origin.clone(), Unexpected::Unit, &"a floating point")),
ValueKind::Table(_) => Err(ConfigError::invalid_type(self.origin.clone(), Unexpected::Map, &"a floating point")),
ValueKind::Array(_) => Err(ConfigError::invalid_type(self.origin.clone(), Unexpected::Seq, &"a floating point")),
ValueKind::Nil => Err(ConfigError::invalid_type(self.origin.clone(), Unexpected::Unit, "a floating point")),
ValueKind::Table(_) => Err(ConfigError::invalid_type(self.origin.clone(), Unexpected::Map, "a floating point")),
ValueKind::Array(_) => Err(ConfigError::invalid_type(self.origin.clone(), Unexpected::Seq, "a floating point")),
}
}

Expand All @@ -195,12 +197,12 @@ impl Value {
ValueKind::String(value) => Ok(value),

// Cannot convert
ValueKind::Float(value) => Err(ConfigError::invalid_type(self.origin, Unexpected::Float(value), &"a string")),
ValueKind::Integer(value) => Err(ConfigError::invalid_type(self.origin, Unexpected::Integer(value), &"a string")),
ValueKind::Boolean(value) => Err(ConfigError::invalid_type(self.origin, Unexpected::Bool(value), &"a string")),
ValueKind::Nil => Err(ConfigError::invalid_type(self.origin, Unexpected::Unit, &"a string")),
ValueKind::Table(_) => Err(ConfigError::invalid_type(self.origin, Unexpected::Map, &"a string")),
ValueKind::Array(_) => Err(ConfigError::invalid_type(self.origin, Unexpected::Seq, &"a string")),
ValueKind::Float(value) => Err(ConfigError::invalid_type(self.origin, Unexpected::Float(value), "a string")),
ValueKind::Integer(value) => Err(ConfigError::invalid_type(self.origin, Unexpected::Integer(value), "a string")),
ValueKind::Boolean(value) => Err(ConfigError::invalid_type(self.origin, Unexpected::Bool(value), "a string")),
ValueKind::Nil => Err(ConfigError::invalid_type(self.origin, Unexpected::Unit, "a string")),
ValueKind::Table(_) => Err(ConfigError::invalid_type(self.origin, Unexpected::Map, "a string")),
ValueKind::Array(_) => Err(ConfigError::invalid_type(self.origin, Unexpected::Seq, "a string")),
}
}

Expand All @@ -210,12 +212,12 @@ impl Value {
ValueKind::Array(value) => Ok(value),

// Cannot convert
ValueKind::Float(value) => Err(ConfigError::invalid_type(self.origin, Unexpected::Float(value), &"an array")),
ValueKind::String(value) => Err(ConfigError::invalid_type(self.origin, Unexpected::Str(value), &"an array")),
ValueKind::Integer(value) => Err(ConfigError::invalid_type(self.origin, Unexpected::Integer(value), &"an array")),
ValueKind::Boolean(value) => Err(ConfigError::invalid_type(self.origin, Unexpected::Bool(value), &"an array")),
ValueKind::Nil => Err(ConfigError::invalid_type(self.origin, Unexpected::Unit, &"an array")),
ValueKind::Table(_) => Err(ConfigError::invalid_type(self.origin, Unexpected::Map, &"an array")),
ValueKind::Float(value) => Err(ConfigError::invalid_type(self.origin, Unexpected::Float(value), "an array")),
ValueKind::String(value) => Err(ConfigError::invalid_type(self.origin, Unexpected::Str(value), "an array")),
ValueKind::Integer(value) => Err(ConfigError::invalid_type(self.origin, Unexpected::Integer(value), "an array")),
ValueKind::Boolean(value) => Err(ConfigError::invalid_type(self.origin, Unexpected::Bool(value), "an array")),
ValueKind::Nil => Err(ConfigError::invalid_type(self.origin, Unexpected::Unit, "an array")),
ValueKind::Table(_) => Err(ConfigError::invalid_type(self.origin, Unexpected::Map, "an array")),
}
}

Expand All @@ -225,20 +227,20 @@ impl Value {
ValueKind::Table(value) => Ok(value),

// Cannot convert
ValueKind::Float(value) => Err(ConfigError::invalid_type(self.origin, Unexpected::Float(value), &"a map")),
ValueKind::String(value) => Err(ConfigError::invalid_type(self.origin, Unexpected::Str(value), &"a map")),
ValueKind::Integer(value) => Err(ConfigError::invalid_type(self.origin, Unexpected::Integer(value), &"a map")),
ValueKind::Boolean(value) => Err(ConfigError::invalid_type(self.origin, Unexpected::Bool(value), &"a map")),
ValueKind::Nil => Err(ConfigError::invalid_type(self.origin, Unexpected::Unit, &"a map")),
ValueKind::Array(_) => Err(ConfigError::invalid_type(self.origin, Unexpected::Seq, &"a map")),
ValueKind::Float(value) => Err(ConfigError::invalid_type(self.origin, Unexpected::Float(value), "a map")),
ValueKind::String(value) => Err(ConfigError::invalid_type(self.origin, Unexpected::Str(value), "a map")),
ValueKind::Integer(value) => Err(ConfigError::invalid_type(self.origin, Unexpected::Integer(value), "a map")),
ValueKind::Boolean(value) => Err(ConfigError::invalid_type(self.origin, Unexpected::Bool(value), "a map")),
ValueKind::Nil => Err(ConfigError::invalid_type(self.origin, Unexpected::Unit, "a map")),
ValueKind::Array(_) => Err(ConfigError::invalid_type(self.origin, Unexpected::Seq, "a map")),
}
}
}

impl<T> From<T> for Value
where T: Into<ValueKind>
{
fn from(value: T) -> Value {
fn from(value: T) -> Self {
Value {
origin: None,
kind: value.into(),
Expand Down

0 comments on commit fbcc723

Please sign in to comment.