1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
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)
    }
}