summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRyan Leckey <ryan@launchbadge.com>2017-06-01 21:36:59 -0700
committerRyan Leckey <ryan@launchbadge.com>2017-06-01 21:36:59 -0700
commit6e71949a7f7895bba255d26d71777f2e5f5d8789 (patch)
tree27e329f6b9b346f92009223954b3a7e09bf9ca99
parent2dc6a74b84825f65142c1fa7d3e67cd4f35ee3cb (diff)
parentfbcc7238e100e07d279e100a36a2eb76f53e7006 (diff)
Merge branch 'impowski-serde' into serde
-rw-r--r--lib/src/de.rs216
-rw-r--r--lib/src/error.rs5
-rw-r--r--lib/src/value.rs98
3 files changed, 94 insertions, 225 deletions
diff --git a/lib/src/de.rs b/lib/src/de.rs
index a59d950..369d6de 100644
--- a/lib/src/de.rs
+++ b/lib/src/de.rs
@@ -1,6 +1,7 @@
use serde::de;
use value::{Value, ValueKind};
use error::*;
+use std::borrow::Cow;
use std::iter::Peekable;
use std::collections::HashMap;
use std::collections::hash_map::Drain;
@@ -9,177 +10,36 @@ 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::Boolean(value) => {
- visitor.visit_bool(value)
- }
-
- ValueKind::Table(map) => {
- visitor.visit_map(MapVisitor::new(map))
- }
-
+ ValueKind::Integer(i) => visitor.visit_i64(i),
+ ValueKind::Boolean(b) => visitor.visit_bool(b),
+ ValueKind::Float(f) => visitor.visit_f64(f),
+ ValueKind::String(s) => visitor.visit_string(s),
+ ValueKind::Array(values) => unimplemented!(),
+ ValueKind::Table(map) => visitor.visit_map(MapVisitor::new(map)),
_ => { unimplemented!(); }
}
}
- #[inline]
- fn deserialize_bool<V: de::Visitor>(self, visitor: V) -> Result<V::Value> {
- visitor.visit_bool(self.into_bool()?)
- }
-
- #[inline]
- fn deserialize_u8<V: de::Visitor>(self, visitor: V) -> Result<V::Value> {
- unimplemented!();
- }
-
- #[inline]
- fn deserialize_u16<V: de::Visitor>(self, visitor: V) -> Result<V::Value> {
- unimplemented!();
- }
-
- #[inline]
- fn deserialize_u32<V: de::Visitor>(self, visitor: V) -> Result<V::Value> {
- unimplemented!();
- }
-
- #[inline]
- fn deserialize_u64<V: de::Visitor>(self, visitor: V) -> Result<V::Value> {
- unimplemented!();
- }
-
- #[inline]
- fn deserialize_i8<V: de::Visitor>(self, visitor: V) -> Result<V::Value> {
- unimplemented!();
- }
-
- #[inline]
- fn deserialize_i16<V: de::Visitor>(self, visitor: V) -> Result<V::Value> {
- unimplemented!();
- }
-
- #[inline]
- fn deserialize_i32<V: de::Visitor>(self, visitor: V) -> Result<V::Value> {
- unimplemented!();
- }
-
- #[inline]
- fn deserialize_i64<V: de::Visitor>(self, visitor: V) -> Result<V::Value> {
- visitor.visit_i64(self.into_int()?)
- }
-
- #[inline]
- fn deserialize_f32<V: de::Visitor>(self, visitor: V) -> Result<V::Value> {
- unimplemented!();
- }
-
- #[inline]
- fn deserialize_f64<V: de::Visitor>(self, visitor: V) -> Result<V::Value> {
- visitor.visit_f64(self.into_float()?)
- }
-
- #[inline]
- fn deserialize_char<V: de::Visitor>(self, visitor: V) -> Result<V::Value> {
- unimplemented!();
- }
-
- #[inline]
- fn deserialize_str<V: de::Visitor>(self, visitor: V) -> Result<V::Value> {
- unimplemented!();
- }
-
- #[inline]
- fn deserialize_string<V: de::Visitor>(self, visitor: V) -> Result<V::Value> {
- unimplemented!();
- }
-
- #[inline]
- fn deserialize_bytes<V: de::Visitor>(self, visitor: V) -> Result<V::Value> {
- unimplemented!();
- }
-
- #[inline]
- fn deserialize_byte_buf<V: de::Visitor>(self, visitor: V) -> Result<V::Value> {
- unimplemented!();
- }
-
- #[inline]
- fn deserialize_option<V: de::Visitor>(self, visitor: V) -> Result<V::Value> {
- unimplemented!();
- }
-
- #[inline]
- fn deserialize_unit<V: de::Visitor>(self, visitor: V) -> Result<V::Value> {
- unimplemented!();
- }
-
- #[inline]
- fn deserialize_unit_struct<V: de::Visitor>(self,
- name: &'static str,
- visitor: V)
- -> Result<V::Value> {
- unimplemented!();
- }
-
- #[inline]
- fn deserialize_newtype_struct<V: de::Visitor>(self,
- name: &'static str,
- visitor: V)
- -> Result<V::Value> {
- unimplemented!();
- }
-
- #[inline]
- fn deserialize_seq<V: de::Visitor>(self, visitor: V) -> Result<V::Value> {
- unimplemented!();
- }
-
- #[inline]
- fn deserialize_seq_fixed_size<V: de::Visitor>(self,
- len: usize,
- visitor: V)
- -> Result<V::Value> {
- unimplemented!();
- }
-
- #[inline]
- fn deserialize_tuple<V: de::Visitor>(self, len: usize, visitor: V) -> Result<V::Value> {
- unimplemented!();
- }
-
- #[inline]
- fn deserialize_tuple_struct<V: de::Visitor>(self,
- name: &'static str,
- len: usize,
- visitor: V)
- -> Result<V::Value> {
- unimplemented!();
- }
-
- #[inline]
- fn deserialize_enum<V: de::Visitor>(self,
- name: &'static str,
- variants: &'static [&'static str],
- visitor: V)
- -> Result<V::Value> {
- unimplemented!();
- }
-
- #[inline]
- fn deserialize_ignored_any<V: de::Visitor>(self, visitor: V) -> Result<V::Value> {
- unimplemented!();
- }
-
forward_to_deserialize! {
- map
- struct
- struct_field
+ 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
}
}
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;
@@ -189,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
}
}
@@ -227,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 }
}
}
@@ -242,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))
diff --git a/lib/src/error.rs b/lib/src/error.rs
index 390057f..b97ebac 100644
--- a/lib/src/error.rs
+++ b/lib/src/error.rs
@@ -1,4 +1,5 @@
use std::error::Error;
+use std::borrow::Cow;
use std::result;
use std::fmt;
use serde::de;
@@ -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,
@@ -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())
}
}
diff --git a/lib/src/value.rs b/lib/src/value.rs
index 87e45bc..5b0014a 100644
--- a/lib/src/value.rs
+++ b/lib/src/value.rs
@@ -6,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
@@ -23,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,
@@ -32,31 +35,31 @@ 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)
}
}
@@ -64,7 +67,7 @@ impl From<bool> for ValueKind {
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 {
@@ -78,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 {
@@ -115,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 {
@@ -137,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")),
}
}
@@ -155,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")),
}
}
@@ -175,30 +178,61 @@ 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")),
}
}
+
+ /// Returns `self` into a str, if possible.
+ pub fn into_str(self) -> Result<String> {
+ match self.kind {
+ 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")),
+ }
+ }
+
+ /// Returns `self` into an array, if possible
+ pub fn into_array(self) -> Result<Vec<Value>> {
+ match self.kind {
+ 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")),
+ }
+ }
+
/// If the `Value` is a Table, returns the associated Map.
pub fn into_table(self) -> Result<HashMap<String, Value>> {
match self.kind {
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")),
}
}
}
@@ -206,7 +240,7 @@ impl Value {
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(),