1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// This file provides a builders for DictionaryValue and ListValue. These
6// aren't specific to extensions and could move up to base/ if there's interest
7// from other sub-projects.
8//
9// The pattern is to write:
10//
11// std::unique_ptr<BuiltType> result(FooBuilder()
12// .Set(args)
13// .Set(args)
14// .Build());
15//
16// The Build() method invalidates its builder, and returns ownership of the
17// built value.
18//
19// These objects are intended to be used as temporaries rather than stored
20// anywhere, so the use of non-const reference parameters is likely to cause
21// less confusion than usual.
22
23#ifndef EXTENSIONS_COMMON_VALUE_BUILDER_H_
24#define EXTENSIONS_COMMON_VALUE_BUILDER_H_
25
26#include <memory>
27#include <string>
28#include <utility>
29
30#include "base/macros.h"
31#include "base/strings/string16.h"
32#include "base/strings/string_piece_forward.h"
33#include "base/values.h"
34
35namespace extensions {
36
37class DictionaryBuilder {
38 public:
39 DictionaryBuilder();
40 explicit DictionaryBuilder(const base::DictionaryValue& init);
41 ~DictionaryBuilder();
42
43 // Can only be called once, after which it's invalid to use the builder.
44 std::unique_ptr<base::DictionaryValue> Build() { return std::move(dict_); }
45
46 // Immediately serializes the current state to JSON. Can be called as many
47 // times as you like.
48 std::string ToJSON() const;
49
50 template <typename T>
51 DictionaryBuilder& Set(base::StringPiece key, T in_value) {
52 dict_->SetKey(key, base::Value(in_value));
53 return *this;
54 }
55
56 // NOTE(devlin): This overload is really just for passing
57 // std::unique_ptr<base::[SomeTypeOf]Value>, but the argument resolution
58 // would require us to define a template specialization for each of the value
59 // types. Just define this; it will fail to compile if <T> is anything but
60 // a base::Value (or one of its subclasses).
61 template <typename T>
62 DictionaryBuilder& Set(base::StringPiece key, std::unique_ptr<T> in_value) {
63 dict_->SetKey(key, std::move(*in_value));
64 return *this;
65 }
66
67 private:
68 std::unique_ptr<base::DictionaryValue> dict_;
69
70 DISALLOW_COPY_AND_ASSIGN(DictionaryBuilder);
71};
72
73class ListBuilder {
74 public:
75 ListBuilder();
76 explicit ListBuilder(const base::ListValue& init);
77 ~ListBuilder();
78
79 // Can only be called once, after which it's invalid to use the builder.
80 std::unique_ptr<base::ListValue> Build() { return std::move(list_); }
81
82 template <typename T>
83 ListBuilder& Append(T in_value) {
84 list_->GetList().emplace_back(in_value);
85 return *this;
86 }
87
88 // See note on DictionaryBuilder::Set().
89 template <typename T>
90 ListBuilder& Append(std::unique_ptr<T> in_value) {
91 list_->GetList().push_back(std::move(*in_value));
92 return *this;
93 }
94
95 private:
96 std::unique_ptr<base::ListValue> list_;
97
98 DISALLOW_COPY_AND_ASSIGN(ListBuilder);
99};
100
101} // namespace extensions
102
103#endif // EXTENSIONS_COMMON_VALUE_BUILDER_H_
104