use std::fmt;
use std::ops;
use serde::de;
use serde::de::{Deserialize, Deserializer, MapAccess, SeqAccess, Visitor};
use serde::ser::{Serialize, SerializeMap, SerializeSeq, Serializer};
use watson_rs::Value::*;
#[derive(PartialEq, Clone, Debug)]
pub struct Value {
value: watson_rs::Value,
}
impl Value {
pub fn new(v: watson_rs::Value) -> Self {
Value { value: v }
}
pub fn into_watson(self) -> watson_rs::Value {
self.value
}
}
impl From<watson_rs::Value> for Value {
fn from(v: watson_rs::Value) -> Self {
Value::new(v)
}
}
impl Serialize for Value {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
ValueRef::new(&self.value).serialize(serializer)
}
}
impl<'de> Deserialize<'de> for Value {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_any(ValueVisitor)
}
}
struct ValueVisitor;
impl<'de> Visitor<'de> for ValueVisitor {
type Value = Value;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("bool, integer, float, string, bytes, seq, or map")
}
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(Int(v).into())
}
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(Uint(v).into())
}
fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(Float(v).into())
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
self.visit_bytes(v.as_bytes())
}
fn visit_string<E>(self, v: std::string::String) -> Result<Self::Value, E>
where
E: de::Error,
{
self.visit_byte_buf(v.into_bytes())
}
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(String(v.to_owned()).into())
}
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(String(v).into())
}
fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
where
M: MapAccess<'de>,
{
let mut map = watson_rs::Map::with_capacity(access.size_hint().unwrap_or(0));
while let Some((key, value)) = access.next_entry::<Bytes, Value>()? {
map.insert(key.into_bytes(), value.into_watson());
}
Ok(Object(map).into())
}
fn visit_seq<S>(self, mut access: S) -> Result<Self::Value, S::Error>
where
S: SeqAccess<'de>,
{
let mut arr = Vec::with_capacity(access.size_hint().unwrap_or(0));
while let Some(elem) = access.next_element::<Value>()? {
arr.push(elem.into_watson());
}
Ok(Array(arr).into())
}
fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(Bool(v).into())
}
fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(Nil.into())
}
}
pub struct ValueRef<'a> {
value: &'a watson_rs::Value,
}
impl<'a> ValueRef<'a> {
pub fn new(v: &'a watson_rs::Value) -> Self {
ValueRef { value: v }
}
}
impl<'a> AsRef<watson_rs::Value> for ValueRef<'a> {
fn as_ref(&self) -> &watson_rs::Value {
self.value
}
}
impl<'a> ops::Deref for ValueRef<'a> {
type Target = watson_rs::Value;
fn deref(&self) -> &watson_rs::Value {
self.value
}
}
impl<'a> Serialize for ValueRef<'a> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match *self.value {
Int(n) => serializer.serialize_i64(n),
Uint(n) => serializer.serialize_u64(n),
Float(f) => serializer.serialize_f64(f),
String(ref s) => serializer.serialize_bytes(s),
Object(ref map) => {
let mut map_ser = serializer.serialize_map(Some(map.len()))?;
for (k, v) in map {
map_ser.serialize_entry(&BytesRef(k), &ValueRef::new(v))?;
}
map_ser.end()
}
Array(ref arr) => {
let mut seq_ser = serializer.serialize_seq(Some(arr.len()))?;
for i in arr {
seq_ser.serialize_element(&ValueRef::new(i))?;
}
seq_ser.end()
}
Bool(b) => serializer.serialize_bool(b),
Nil => serializer.serialize_none(),
}
}
}
struct BytesRef<'a>(&'a watson_rs::Bytes);
impl<'a> Serialize for BytesRef<'a> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_bytes(self.0)
}
}
struct Bytes(watson_rs::Bytes);
impl Bytes {
fn into_bytes(self) -> watson_rs::Bytes {
self.0
}
}
impl<'de> Deserialize<'de> for Bytes {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_bytes(BytesVisitor)
}
}
struct BytesVisitor;
impl<'de> Visitor<'de> for BytesVisitor {
type Value = Bytes;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("bytes")
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
self.visit_bytes(v.as_bytes())
}
fn visit_string<E>(self, v: std::string::String) -> Result<Self::Value, E>
where
E: de::Error,
{
self.visit_byte_buf(v.into_bytes())
}
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(Bytes(v.to_vec()))
}
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(Bytes(v))
}
}
#[cfg(test)]
mod test {
use serde_test::{assert_tokens, Token};
use watson_rs::Map;
use watson_rs::Value::*;
use super::*;
#[test]
fn ser_de_int() {
assert_tokens(&Value::new(Int(0)), &[Token::I64(0)]);
assert_tokens(&Value::new(Int(123)), &[Token::I64(123)]);
assert_tokens(&Value::new(Int(-123)), &[Token::I64(-123)]);
}
#[test]
fn ser_de_uint() {
assert_tokens(&Value::new(Uint(0)), &[Token::U64(0)]);
assert_tokens(&Value::new(Uint(123)), &[Token::U64(123)]);
assert_tokens(
&Value::new(Uint(0xdead_beef_fefe_aaaa)),
&[Token::U64(0xdead_beef_fefe_aaaa)],
);
}
#[test]
fn ser_de_float() {
assert_tokens(&Value::new(Float(0.0)), &[Token::F64(0.0)]);
assert_tokens(&Value::new(Float(1.23e45)), &[Token::F64(1.23e45)]);
assert_tokens(&Value::new(Float(6.78e-91)), &[Token::F64(6.78e-91)]);
}
#[test]
fn ser_de_string() {
assert_tokens(&Value::new(String(b"".to_vec())), &[Token::Bytes(b"")]);
assert_tokens(&Value::new(String(b"a".to_vec())), &[Token::Bytes(b"a")]);
assert_tokens(
&Value::new(String(b"hello world!".to_vec())),
&[Token::Bytes(b"hello world!")],
);
}
#[test]
fn ser_de_object() {
assert_tokens(
&Value::new(Object(Map::new())),
&[Token::Map { len: Some(0) }, Token::MapEnd],
);
assert_tokens(
&Value::new(Object(
vec![(b"value".to_vec(), Int(123))].into_iter().collect(),
)),
&[
Token::Map { len: Some(1) },
Token::Bytes(b"value"),
Token::I64(123),
Token::MapEnd,
],
);
}
#[test]
fn ser_de_array() {
assert_tokens(
&Value::new(Array(vec![])),
&[Token::Seq { len: Some(0) }, Token::SeqEnd],
);
assert_tokens(
&Value::new(Array(vec![Int(123)])),
&[Token::Seq { len: Some(1) }, Token::I64(123), Token::SeqEnd],
);
assert_tokens(
&Value::new(Array(vec![Int(123), String(b"hello".to_vec())])),
&[
Token::Seq { len: Some(2) },
Token::I64(123),
Token::Bytes(b"hello"),
Token::SeqEnd,
],
);
}
#[test]
fn ser_de_bool() {
assert_tokens(&Value::new(Bool(true)), &[Token::Bool(true)]);
assert_tokens(&Value::new(Bool(false)), &[Token::Bool(false)]);
}
#[test]
fn ser_de_nil() {
assert_tokens(&Value::new(Nil), &[Token::None]);
}
}