// 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 #include #include #include #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& out); bool PopulateItem(const base::Value& from, std::vector& 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 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 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 bool PopulateArrayFromList(const base::Value::List& list, std::vector& 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 bool PopulateArrayFromList(const base::Value::List& list, std::vector& 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 bool PopulateOptionalArrayFromList(const base::Value::List& list, std::optional>& out) { std::vector populated; if (!PopulateArrayFromList(list, populated)) { return false; } out = std::move(populated); return true; } template bool PopulateOptionalArrayFromList(const base::Value::List& list, std::optional>& out, std::u16string& error) { std::vector 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& 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 void AddItemToList(const std::unique_ptr& from, base::Value::List& out) { out.Append(from->ToValue()); } // This template is used for types generated by tools/json_schema_compiler. template 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 base::Value::List CreateValueFromArray(const std::vector& from) { base::Value::List list; for (const T& item : from) { AddItemToList(item, list); } return list; } template void AppendToContainer(base::Value::List& container, T&& value) { container.Append(std::forward(value)); } template void AppendToContainer(std::vector& container, T&& value) { container.emplace_back(std::forward(value)); } } // namespace util } // namespace json_schema_compiler #endif // TOOLS_JSON_SCHEMA_COMPILER_UTIL_H_