| // Copyright 2012 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef TOOLS_JSON_SCHEMA_COMPILER_UTIL_H_ |
| #define TOOLS_JSON_SCHEMA_COMPILER_UTIL_H_ |
| |
| #include <memory> |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| #include "base/format_macros.h" |
| #include "base/strings/stringprintf.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "base/values.h" |
| |
| namespace json_schema_compiler { |
| |
| namespace util { |
| |
| // Populates the item |out| from the value |from|. These are used by template |
| // specializations of |Get(Optional)ArrayFromList|. |
| bool PopulateItem(const base::Value& from, base::Value& out); |
| |
| bool PopulateItem(const base::Value& from, int& out); |
| bool PopulateItem(const base::Value& from, int& out, std::u16string& error); |
| bool PopulateItem(const base::Value& from, bool& out); |
| bool PopulateItem(const base::Value& from, bool& out, std::u16string& error); |
| bool PopulateItem(const base::Value& from, double& out); |
| bool PopulateItem(const base::Value& from, double& out, std::u16string& error); |
| bool PopulateItem(const base::Value& from, std::string& out); |
| bool PopulateItem(const base::Value& from, |
| std::string& out, |
| std::u16string& error); |
| bool PopulateItem(const base::Value& from, std::vector<uint8_t>& out); |
| bool PopulateItem(const base::Value& from, |
| std::vector<uint8_t>& out, |
| std::u16string& error); |
| bool PopulateItem(const base::Value& from, |
| base::Value& out, |
| std::u16string& error); |
| |
| // This template is used for types generated by tools/json_schema_compiler. |
| template <class T> |
| bool PopulateItem(const base::Value& from, T& out) { |
| T obj; |
| if (!T::Populate(from, obj)) { |
| return false; |
| } |
| out = std::move(obj); |
| return true; |
| } |
| |
| // This template is used for types generated by tools/json_schema_compiler with |
| // error generation enabled. |
| template <class T> |
| bool PopulateItem(const base::Value& from, T& out, std::u16string& error) { |
| T obj; |
| if (!T::Populate(from, obj, error)) { |
| return false; |
| } |
| out = std::move(obj); |
| return true; |
| } |
| |
| // Populates |out| with |list|. Returns false if there is no list at the |
| // specified key or if the list has anything other than |T|. |
| template <class T> |
| bool PopulateArrayFromList(const base::Value::List& list, std::vector<T>& out) { |
| out.clear(); |
| out.reserve(list.size()); |
| T item; |
| for (const auto& value : list) { |
| if (!PopulateItem(value, item)) { |
| return false; |
| } |
| // T might not be movable, but in that case it should be copyable, and this |
| // will still work. |
| out.push_back(std::move(item)); |
| } |
| |
| return true; |
| } |
| |
| // Populates |out| with |list|. Returns false and sets |error| if there is no |
| // list at the specified key or if the list has anything other than |T|. |
| template <class T> |
| bool PopulateArrayFromList(const base::Value::List& list, |
| std::vector<T>& out, |
| std::u16string& error) { |
| out.clear(); |
| out.reserve(list.size()); |
| T item; |
| std::u16string item_error; |
| for (size_t i = 0; i < list.size(); ++i) { |
| if (!PopulateItem(list[i], item, item_error)) { |
| DCHECK(error.empty()); |
| error = base::ASCIIToUTF16( |
| base::StringPrintf("Parsing array failed at index %" PRIuS ": %s", i, |
| base::UTF16ToASCII(item_error).c_str())); |
| return false; |
| } |
| out.push_back(std::move(item)); |
| } |
| |
| return true; |
| } |
| |
| // Creates a new vector containing |list| at |out|. Returns |
| // true on success or if there is nothing at the specified key. Returns false |
| // if anything other than a list of |T| is at the specified key. |
| template <class T> |
| bool PopulateOptionalArrayFromList(const base::Value::List& list, |
| std::optional<std::vector<T>>& out) { |
| std::vector<T> populated; |
| if (!PopulateArrayFromList(list, populated)) { |
| return false; |
| } |
| out = std::move(populated); |
| return true; |
| } |
| |
| template <class T> |
| bool PopulateOptionalArrayFromList(const base::Value::List& list, |
| std::optional<std::vector<T>>& out, |
| std::u16string& error) { |
| std::vector<T> populated; |
| if (!PopulateArrayFromList(list, populated, error)) { |
| return false; |
| } |
| out = std::move(populated); |
| return true; |
| } |
| |
| // Appends a Value newly created from |from| to |out|. These used by template |
| // specializations of |Set(Optional)ArrayToList|. |
| void AddItemToList(const int from, base::Value::List& out); |
| void AddItemToList(const bool from, base::Value::List& out); |
| void AddItemToList(const double from, base::Value::List& out); |
| void AddItemToList(const std::string& from, base::Value::List& out); |
| void AddItemToList(const std::vector<uint8_t>& from, base::Value::List& out); |
| void AddItemToList(const base::Value& from, base::Value::List& out); |
| void AddItemToList(const base::Value::Dict& from, base::Value::List& out); |
| |
| // This template is used for types generated by tools/json_schema_compiler. |
| template <class T> |
| void AddItemToList(const std::unique_ptr<T>& from, base::Value::List& out) { |
| out.Append(from->ToValue()); |
| } |
| |
| // This template is used for types generated by tools/json_schema_compiler. |
| template <class T> |
| void AddItemToList(const T& from, base::Value::List& out) { |
| out.Append(from.ToValue()); |
| } |
| |
| // Returns a list matching the contents of |from|. Requires PopulateItem to be |
| // implemented for |T|. |
| template <class T> |
| base::Value::List CreateValueFromArray(const std::vector<T>& from) { |
| base::Value::List list; |
| for (const T& item : from) { |
| AddItemToList(item, list); |
| } |
| return list; |
| } |
| |
| template <class T> |
| void AppendToContainer(base::Value::List& container, T&& value) { |
| container.Append(std::forward<T>(value)); |
| } |
| |
| template <class C, class T> |
| void AppendToContainer(std::vector<C>& container, T&& value) { |
| container.emplace_back(std::forward<T>(value)); |
| } |
| |
| } // namespace util |
| } // namespace json_schema_compiler |
| |
| #endif // TOOLS_JSON_SCHEMA_COMPILER_UTIL_H_ |