jsonway 2.0.0

JSON building DSL and configurable serializers for Rust
Documentation
use serde_json::{Value, to_value};
use serde::{Serialize, Serializer};

pub type JsonArray = Vec<Value>;

use object_builder;

pub struct ArrayBuilder {
    pub array: JsonArray,
    pub null: bool,
    pub skip: bool,
    pub root: Option<String>
}

/// Use ArrayBuilder to produce JSON arrays
impl ArrayBuilder {

    pub fn new() -> ArrayBuilder {
        ArrayBuilder {
            array: vec![],
            null: false,
            skip: false,
            root: None
        }
    }

    /// Initialize builder with initial value.
    pub fn from_json(array: Value) -> Option<ArrayBuilder> {
        match array {
            Value::Array(array) => Some(ArrayBuilder {
                array: array,
                null: false,
                skip: false,
                root: None
            }),
            _ => None
        }
    }

    /// Create new ArrayBuilder, pass it to closure as mutable ref and return.
    pub fn build<F>(builder: F) -> ArrayBuilder where F: FnOnce(&mut ArrayBuilder) {
        let mut bldr = ArrayBuilder::new();
        builder(&mut bldr);

        bldr
    }

    /// Push JSON value to array.
    pub fn push_json(&mut self, value: Value) {
        self.array.push(value);
    }

    /// Create new array and push it.
    pub fn array<F>(&mut self, builder: F) where F: FnOnce(&mut ArrayBuilder) {
        self.push(ArrayBuilder::build(builder).unwrap());
    }

    /// Create new object and push it
    pub fn object<F>(&mut self, builder: F) where F: FnOnce(&mut object_builder::ObjectBuilder) {
        self.push(object_builder::ObjectBuilder::build(builder).unwrap());
    }

    /// It you call `null`, this array will be converted to null when converting
    /// to raw JSON value.
    pub fn null(&mut self) {
        self.null = true;
    }

    /// It you call `skip`, this array 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()
        }
    }

    /// Move out internal JSON value.
    #[inline]
    fn unwrap_internal(self) -> Value {
        if self.null {
            Value::Null
        } else {
            Value::Array(self.array)
        }
    }
}

impl ArrayBuilder {
    /// Push to array something that can be converted to JSON.
    pub fn push<T: Serialize>(&mut self, value: T) {
        self.push_json(to_value(&value).unwrap());
    }
}

impl ArrayBuilder {

    /// Fill this array by objects builded from iterator.
    pub fn objects<A, T: Iterator<Item=A>, F>(&mut self, iter: T, func: F) where F: Fn(A, &mut object_builder::ObjectBuilder) {
        for a in iter {
            let mut bldr = object_builder::ObjectBuilder::new();
            func(a, &mut bldr);
            if !bldr.skip {
                self.push(bldr.unwrap())
            }
        }
    }

    // Fill this array by arrays builded from iterator.
    pub fn arrays<A, T: Iterator<Item=A>, F>(&mut self, iter: T, func: F) where F: Fn(A, &mut ArrayBuilder) {
        for a in iter {
            let mut bldr = ArrayBuilder::new();
            func(a, &mut bldr);
            if !bldr.skip {
                self.push(bldr.unwrap())
            }
        }
    }

    /// Fill this array by JSON values builded from iterator.
    pub fn map<A, T: Iterator<Item=A>, F>(&mut self, iter: T, func: F) where F: Fn(A) -> Value {
        for a in iter {
            self.push(func(a))
        }
    }
}

impl Serialize for ArrayBuilder {
    /// 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.array).unwrap() };
        json_object.serialize(serializer)
    }
}