blob: 15404a8a05494f7128918b42ece96a8c4b6afb4c [file] [log] [blame]
use serde_json::{Value, to_value};
use serde::{Serialize, Serializer};
pub type Object = ::serde_json::Map<String, Value>;
use array_builder;
pub struct ObjectBuilder {
pub object: Object,
pub null: bool,
pub skip: bool,
pub root: Option<String>
}
/// ObjectBuilder is used to produce JSON objects
impl ObjectBuilder {
pub fn new() -> ObjectBuilder {
ObjectBuilder {
object: ::serde_json::Map::new(),
null: false,
skip: false,
root: None
}
}
/// Initialize builder with initial value.
pub fn from_json(object: Value) -> Option<ObjectBuilder> {
match object {
Value::Object(object) => Some(ObjectBuilder {
object: object,
null: false,
skip: false,
root: None
}),
_ => None
}
}
/// Create new builder, pass it to closure as mutable ref and return.
pub fn build<F>(builder: F) -> ObjectBuilder where F: FnOnce(&mut ObjectBuilder) {
let mut bldr = ObjectBuilder::new();
builder(&mut bldr);
bldr
}
/// It you call `null`, this object will be converted to null.
pub fn null(&mut self) {
self.null = true;
}
/// It you call `skip`, this object will be skipped.
pub fn skip(&mut self) {
self.skip = true;
}
// Set custom root for result Value object
pub fn root(&mut self, root: &str) {
self.root = Some(root.to_string());
}
pub fn has_root(&mut self) -> bool {
self.root.is_some()
}
/// Move out internal JSON value.
pub fn unwrap(self) -> Value {
if self.root.is_some() {
let mut obj = ::serde_json::Map::new();
let root = self.root.as_ref().unwrap().to_string();
let self_json = self.unwrap_internal();
obj.insert(root, self_json);
Value::Object(obj)
} else {
self.unwrap_internal()
}
}
#[inline]
fn unwrap_internal(self) -> Value {
if self.null {
Value::Null
} else {
Value::Object(self.object)
}
}
}
impl ObjectBuilder {
/// Set object's `name` field with something that can be
/// converted to Value value.
pub fn set<V: Serialize, N: Into<String>>(&mut self, name: N, value: V) {
self.set_json(name, to_value(&value).unwrap());
}
/// Stub for future use
pub fn call<V: Serialize, N: Into<String>>(&mut self, name: N, value: V) {
self.set(name, value);
}
}
impl ObjectBuilder {
/// Set object's `name` field with raw Value value.
pub fn set_json<N: Into<String>>(&mut self, name: N, value: Value) {
self.object.insert(name.into(), value);
}
/// Build new array and set object's `name` field with it.
pub fn array<N: Into<String>, F>(&mut self, name: N, builder: F) where F: FnOnce(&mut array_builder::ArrayBuilder) {
self.set(name.into(), array_builder::ArrayBuilder::build(builder).unwrap());
}
/// Build new object and set object's `name` field with it.
pub fn object<N: Into<String>, F>(&mut self, name: N, builder: F) where F: FnOnce(&mut ObjectBuilder) {
self.set(name.into(), ObjectBuilder::build(builder).unwrap());
}
}
impl Serialize for ObjectBuilder {
/// Copy self to new JSON instance.
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
let json_object = if self.null { Value::Null } else { to_value(&self.object).unwrap() };
json_object.serialize(serializer)
}
}