// Copyright 2016 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef HEADLESS_PUBLIC_INTERNAL_VALUE_CONVERSIONS_H_ #define HEADLESS_PUBLIC_INTERNAL_VALUE_CONVERSIONS_H_ #include #include "base/memory/ptr_util.h" #include "headless/public/util/error_reporter.h" namespace headless { namespace internal { // Generic conversion from a type to a base::Value. Implemented in // types_DOMAIN.cc after all type-specific ToValueImpls have been defined. template std::unique_ptr ToValue(const T& value); // Generic conversion from a base::Value to a type. Note that this generic // variant is never defined. Instead, we declare a specific template // specialization for all the used types. template struct FromValue { static std::unique_ptr Parse(const base::Value& value, ErrorReporter* errors); }; // ToValueImpl is a helper used by the ToValue template for dispatching into // type-specific serializers. It uses a dummy |T*| argument as a way to // partially specialize vector types. template std::unique_ptr ToValueImpl(int value, T*) { return base::MakeUnique(value); } template std::unique_ptr ToValueImpl(double value, T*) { return base::MakeUnique(value); } template std::unique_ptr ToValueImpl(bool value, T*) { return base::MakeUnique(value); } template std::unique_ptr ToValueImpl(const std::string& value, T*) { return base::MakeUnique(value); } template std::unique_ptr ToValueImpl(const base::Value& value, T*) { return value.CreateDeepCopy(); } template std::unique_ptr ToValueImpl(const std::vector& vector, const std::vector*) { std::unique_ptr result(new base::ListValue()); for (const auto& it : vector) result->Append(ToValue(it)); return std::move(result); } template std::unique_ptr ToValueImpl(const std::unique_ptr& value, std::unique_ptr*) { return ToValue(*value); } // FromValue specializations for basic types. template <> struct FromValue { static bool Parse(const base::Value& value, ErrorReporter* errors) { bool result = false; if (!value.GetAsBoolean(&result)) errors->AddError("boolean value expected"); return result; } }; template <> struct FromValue { static int Parse(const base::Value& value, ErrorReporter* errors) { int result = 0; if (!value.GetAsInteger(&result)) errors->AddError("integer value expected"); return result; } }; template <> struct FromValue { static double Parse(const base::Value& value, ErrorReporter* errors) { double result = 0; if (!value.GetAsDouble(&result)) errors->AddError("double value expected"); return result; } }; template <> struct FromValue { static std::string Parse(const base::Value& value, ErrorReporter* errors) { std::string result; if (!value.GetAsString(&result)) errors->AddError("string value expected"); return result; } }; template <> struct FromValue { static std::unique_ptr Parse(const base::Value& value, ErrorReporter* errors) { const base::DictionaryValue* result; if (!value.GetAsDictionary(&result)) { errors->AddError("dictionary value expected"); return nullptr; } return result->CreateDeepCopy(); } }; template <> struct FromValue { static std::unique_ptr Parse(const base::Value& value, ErrorReporter* errors) { return value.CreateDeepCopy(); } }; template struct FromValue> { static std::unique_ptr Parse(const base::Value& value, ErrorReporter* errors) { return FromValue::Parse(value, errors); } }; template struct FromValue> { static std::vector Parse(const base::Value& value, ErrorReporter* errors) { std::vector result; const base::ListValue* list; if (!value.GetAsList(&list)) { errors->AddError("list value expected"); return result; } errors->Push(); for (const auto& item : *list) result.push_back(FromValue::Parse(item, errors)); errors->Pop(); return result; } }; } // namespace internal } // namespace headless #endif // HEADLESS_PUBLIC_INTERNAL_VALUE_CONVERSIONS_H_