1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file provides a builders for DictionaryValue and ListValue.  These
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// aren't specific to extensions and could move up to base/ if there's interest
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// from other sub-projects.
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The general pattern is to write:
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  scoped_ptr<BuiltType> result(FooBuilder()
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                               .Set(args)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                               .Set(args)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                               .Build());
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For methods that take other built types, you can pass the builder directly
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to the setter without calling Build():
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DictionaryBuilder().Set("key", ListBuilder()
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                         .Append("foo").Append("bar") /* No .Build() */);
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Because of limitations in C++03, and to avoid extra copies, you can't pass a
23a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// just-constructed Builder into another Builder's method directly. Use the
24a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Pass() method.
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The Build() method invalidates its builder, and returns ownership of the
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// built value.
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// These objects are intended to be used as temporaries rather than stored
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// anywhere, so the use of non-const reference parameters is likely to cause
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// less confusion than usual.
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#ifndef EXTENSIONS_COMMON_VALUE_BUILDER_H_
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#define EXTENSIONS_COMMON_VALUE_BUILDER_H_
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ListBuilder;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DictionaryBuilder {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DictionaryBuilder();
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit DictionaryBuilder(const base::DictionaryValue& init);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~DictionaryBuilder();
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Workaround to allow you to pass rvalue ExtensionBuilders by reference to
53a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // other functions.
54a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DictionaryBuilder& Pass() { return *this; }
55a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Can only be called once, after which it's invalid to use the builder.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::DictionaryValue> Build() { return dict_.Pass(); }
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DictionaryBuilder& Set(const std::string& path, int in_value);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DictionaryBuilder& Set(const std::string& path, double in_value);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DictionaryBuilder& Set(const std::string& path, const std::string& in_value);
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DictionaryBuilder& Set(const std::string& path,
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         const base::string16& in_value);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DictionaryBuilder& Set(const std::string& path, DictionaryBuilder& in_value);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DictionaryBuilder& Set(const std::string& path, ListBuilder& in_value);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Named differently because overload resolution is too eager to
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // convert implicitly to bool.
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DictionaryBuilder& SetBoolean(const std::string& path, bool in_value);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::DictionaryValue> dict_;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ListBuilder {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ListBuilder();
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit ListBuilder(const base::ListValue& init);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~ListBuilder();
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Workaround to allow you to pass rvalue ExtensionBuilders by reference to
82a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // other functions.
83a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ListBuilder& Pass() { return *this; }
84a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Can only be called once, after which it's invalid to use the builder.
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::ListValue> Build() { return list_.Pass(); }
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ListBuilder& Append(int in_value);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ListBuilder& Append(double in_value);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ListBuilder& Append(const std::string& in_value);
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ListBuilder& Append(const base::string16& in_value);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ListBuilder& Append(DictionaryBuilder& in_value);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ListBuilder& Append(ListBuilder& in_value);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Named differently because overload resolution is too eager to
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // convert implicitly to bool.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ListBuilder& AppendBoolean(bool in_value);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::ListValue> list_;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}  // namespace extensions
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif  // EXTENSIONS_COMMON_VALUE_BUILDER_H_
106