#![deny(
missing_docs,
unused_imports,
missing_debug_implementations,
missing_copy_implementations,
trivial_casts,
trivial_numeric_casts,
unsafe_code,
unstable_features,
unused_import_braces,
unused_qualifications
)]
#![doc(html_root_url = "https://docs.rs/serializers/0.2.3")]
extern crate serde;
#[macro_use]
extern crate serde_json;
use serde::Serialize;
use serde_json::Value;
use std::collections::HashMap;
mod macros;
pub trait Serializer<T> {
fn serialize_into(&self, value: &T, builder: &mut Builder);
fn to_value(&self, value: &T) -> Value {
let mut builder = Builder::new();
self.serialize_into(value, &mut builder);
builder.to_value()
}
fn serialize(&self, value: &T) -> String {
self.to_value(value).to_string()
}
fn serialize_iter<'a, I>(&self, values: I) -> String
where
I: IntoIterator<Item = &'a T>,
T: 'a,
{
let acc: Vec<_> = values.into_iter().map(|v| self.to_value(&v)).collect();
json!(acc).to_string()
}
}
#[derive(Debug)]
pub struct Builder {
map: HashMap<String, Value>,
}
impl Builder {
fn new() -> Self {
Builder {
map: HashMap::new(),
}
}
fn to_value(&self) -> Value {
json!(self.map)
}
pub fn attr<K, V>(&mut self, key: K, value: &V) -> &mut Self
where
K: Into<String>,
V: Serialize,
{
let key: String = key.into();
let value: Value = json!(value);
self.map.insert(key, value);
self
}
pub fn has_one<K, V, S>(&mut self, key: K, value: &V, serializer: &S) -> &mut Self
where
K: Into<String>,
S: Serializer<V>,
{
let key: String = key.into();
let value: Value = serializer.to_value(value);
self.map.insert(key, value);
self
}
pub fn has_many<'a, K, V: 'a, S, I>(&mut self, key: K, values: I, serializer: &S) -> &mut Self
where
K: Into<String>,
S: Serializer<V>,
I: IntoIterator<Item = &'a V>,
{
let key: String = key.into();
let value = values
.into_iter()
.map(|v| serializer.to_value(&v))
.collect::<Vec<_>>();
self.map.insert(key, json!(value));
self
}
}
#[cfg(test)]
mod tests {
use super::*;
macro_rules! test_user_serializer {
{
$($tokens:tt)*
} => {
struct User {
id: u64,
}
serializer! {
$($tokens)*
}
let bob = User { id: 1 };
let json: String = UserSerializer::serialize(&bob);
assert_eq!(json, json!({ "id": 1 }).to_string());
};
}
#[test]
fn test_pub_crate() {
test_user_serializer! {
pub(crate) struct UserSerializer<User> { attr(id) }
};
}
#[test]
fn test_pub() {
test_user_serializer! {
pub struct UserSerializer<User> { attr(id) }
};
}
#[test]
fn test_private() {
test_user_serializer! {
struct UserSerializer<User> { attr(id) }
};
}
#[test]
fn test_pub_crate_attrs() {
test_user_serializer! {
#[derive(PartialEq, Eq, Debug)]
pub(crate) struct UserSerializer<User> { attr(id) }
};
assert_eq!(UserSerializer, UserSerializer);
}
#[test]
fn test_pub_attrs() {
test_user_serializer! {
#[derive(PartialEq, Eq, Debug)]
pub struct UserSerializer<User> { attr(id) }
};
assert_eq!(UserSerializer, UserSerializer);
}
#[test]
fn test_private_attrs() {
test_user_serializer! {
#[derive(PartialEq, Eq, Debug)]
struct UserSerializer<User> { attr(id) }
};
assert_eq!(UserSerializer, UserSerializer);
}
#[test]
fn generated_associated_function() {
struct User {
id: u64,
}
serializer! {
struct UserSerializer<User> {
attr(id)
}
}
let bob = User { id: 1 };
let json: String = UserSerializer::serialize(&bob);
assert_eq!(json, json!({ "id": 1 }).to_string());
}
}