blob: 1d1c26d2a40a2fab8914bc5d6ca5b79cb24f4ae8 [file] [log] [blame]
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -07001// Copyright 2014 The Chromium OS 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#ifndef BUFFET_COMMANDS_PROP_VALUES_H_
6#define BUFFET_COMMANDS_PROP_VALUES_H_
7
8#include <map>
9#include <memory>
10#include <string>
11
Alex Vakulenkoa6fb4ed2014-08-22 15:05:35 -070012#include <chromeos/any.h>
Alex Vakulenkoa8b95bc2014-08-27 11:00:57 -070013#include <chromeos/errors/error.h>
Alex Vakulenko5f472062014-08-14 17:54:04 -070014
Alex Vakulenko66ec2922014-06-17 15:30:22 -070015#include "buffet/commands/schema_utils.h"
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070016
17namespace base {
18class Value;
19class DictionaryValue;
20} // namespace base
21
22namespace buffet {
23
24// Enumeration to indicate supported command parameter types.
25enum class ValueType {
26 Int,
27 Double,
28 String,
Alex Vakulenko66ec2922014-06-17 15:30:22 -070029 Boolean,
30 Object
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070031};
32
Alex Vakulenko66ec2922014-06-17 15:30:22 -070033class PropValue;
34class IntValue;
35class DoubleValue;
36class StringValue;
37class BooleanValue;
38class ObjectValue;
39
40class PropType;
41
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070042// Helper methods to get the parameter type enum value for the given
43// native C++ data representation.
44// The generic GetValueType<T>() is undefined, however particular
45// type specializations return the appropriate ValueType.
46template<typename T> ValueType GetValueType(); // Undefined.
Alex Vakulenko66ec2922014-06-17 15:30:22 -070047template<>
48inline ValueType GetValueType<int>() { return ValueType::Int; }
49template<>
50inline ValueType GetValueType<double>() { return ValueType::Double; }
51template<>
52inline ValueType GetValueType<std::string>() { return ValueType::String; }
53template<>
54inline ValueType GetValueType<bool>() { return ValueType::Boolean; }
55template<>
56inline ValueType GetValueType<native_types::Object>() {
57 return ValueType::Object;
58}
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070059
Alex Vakulenko66ec2922014-06-17 15:30:22 -070060// The base class for property values.
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070061// Concrete value classes of various types will be derived from this base.
Alex Vakulenko66ec2922014-06-17 15:30:22 -070062// A property value is the actual command parameter value (or a concrete value
63// that can be used in constraints and presets). The PropValue is mostly
64// just parsed content of base::Value when a command is dispatched, however
65// it does have some additional functionality:
66// - it has a reference to the type definition (PropType) which is used
67// when validating the value, especially for "object" types.
68// - it can be compared with another instances of values of the same type.
69// This is used to validate the values against "enum"/"one of" constraints.
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070070class PropValue {
71 public:
Alex Vakulenko66ec2922014-06-17 15:30:22 -070072 explicit PropValue(const PropType* type)
73 : type_(type) {}
74 virtual ~PropValue() = default;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070075
76 // Gets the type of the value.
77 virtual ValueType GetType() const = 0;
78
79 // Type conversion methods. Used in lieu of RTTI and dynamic_cast<>.
80 virtual IntValue* GetInt() { return nullptr; }
81 virtual IntValue const* GetInt() const { return nullptr; }
82 virtual DoubleValue* GetDouble() { return nullptr; }
83 virtual DoubleValue const* GetDouble() const { return nullptr; }
84 virtual StringValue* GetString() { return nullptr; }
85 virtual StringValue const* GetString() const { return nullptr; }
86 virtual BooleanValue* GetBoolean() { return nullptr; }
87 virtual BooleanValue const* GetBoolean() const { return nullptr; }
Alex Vakulenko66ec2922014-06-17 15:30:22 -070088 virtual ObjectValue* GetObject() { return nullptr; }
89 virtual ObjectValue const* GetObject() const { return nullptr; }
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070090
91 // Makes a full copy of this value class.
92 virtual std::shared_ptr<PropValue> Clone() const = 0;
93
94 // Saves the value as a JSON object.
95 // If it fails, returns nullptr value and fills in the details for the
96 // failure in the |error| parameter.
Alex Vakulenko5f472062014-08-14 17:54:04 -070097 virtual std::unique_ptr<base::Value> ToJson(
98 chromeos::ErrorPtr* error) const = 0;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070099 // Parses a value from JSON.
100 // If it fails, it returns false and provides additional information
101 // via the |error| parameter.
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700102 virtual bool FromJson(const base::Value* value,
Alex Vakulenko5f472062014-08-14 17:54:04 -0700103 chromeos::ErrorPtr* error) = 0;
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700104
105 // Returns the contained C++ value as Any.
Alex Vakulenkoa6fb4ed2014-08-22 15:05:35 -0700106 virtual chromeos::Any GetValueAsAny() const = 0;
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700107
108 // Return the type definition of this value.
109 const PropType* GetPropType() const { return type_; }
110 // Compares two values and returns true if they are equal.
111 virtual bool IsEqual(const PropValue* value) const = 0;
112
113 protected:
114 const PropType* type_; // weak pointer
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700115};
116
117// A helper template base class for implementing simple (non-Object) value
118// classes.
119template<typename Derived, typename T>
120class TypedValueBase : public PropValue {
121 public:
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700122 // To help refer to this base class from derived classes, define _Base to
123 // be this class.
124 using _Base = TypedValueBase<Derived, T>;
125 // Expose the non-default constructor of the base class.
126 using PropValue::PropValue;
127
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700128 // Overrides from PropValue base class.
Alex Vakulenko5a9e7182014-08-11 15:59:58 -0700129 ValueType GetType() const override { return GetValueType<T>(); }
130 std::shared_ptr<PropValue> Clone() const override {
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700131 return std::make_shared<Derived>(*static_cast<const Derived*>(this));
132 }
133
Alex Vakulenko5f472062014-08-14 17:54:04 -0700134 std::unique_ptr<base::Value> ToJson(
135 chromeos::ErrorPtr* error) const override {
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700136 return TypedValueToJson(value_, error);
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700137 }
138
Alex Vakulenko5f472062014-08-14 17:54:04 -0700139 bool FromJson(const base::Value* value, chromeos::ErrorPtr* error) override {
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700140 return TypedValueFromJson(value, GetPropType()->GetObjectSchemaPtr(),
141 &value_, error);
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700142 }
143
Alex Vakulenko5a9e7182014-08-11 15:59:58 -0700144 bool IsEqual(const PropValue* value) const override {
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700145 if (GetType() != value->GetType())
146 return false;
147 const _Base* value_base = static_cast<const _Base*>(value);
148 return CompareValue(GetValue(), value_base->GetValue());
149 }
150
151 // Helper methods to get and set the C++ representation of the value.
Alex Vakulenkoa6fb4ed2014-08-22 15:05:35 -0700152 chromeos::Any GetValueAsAny() const override { return value_; }
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700153 const T& GetValue() const { return value_; }
154 void SetValue(T value) { value_ = std::move(value); }
155
156 protected:
157 T value_{}; // The value of the parameter in C++ data representation.
158};
159
160// Value of type Integer.
161class IntValue final : public TypedValueBase<IntValue, int> {
162 public:
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700163 using _Base::_Base; // Expose the custom constructor of the base class.
Alex Vakulenko5a9e7182014-08-11 15:59:58 -0700164 IntValue* GetInt() override { return this; }
165 IntValue const* GetInt() const override { return this; }
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700166};
167
168// Value of type Number.
169class DoubleValue final : public TypedValueBase<DoubleValue, double> {
170 public:
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700171 using _Base::_Base; // Expose the custom constructor of the base class.
Alex Vakulenko5a9e7182014-08-11 15:59:58 -0700172 DoubleValue* GetDouble() override { return this; }
173 DoubleValue const* GetDouble() const override { return this; }
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700174};
175
176// Value of type String.
177class StringValue final : public TypedValueBase<StringValue, std::string> {
178 public:
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700179 using _Base::_Base; // Expose the custom constructor of the base class.
Alex Vakulenko5a9e7182014-08-11 15:59:58 -0700180 StringValue* GetString() override { return this; }
181 StringValue const* GetString() const override { return this; }
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700182};
183
184// Value of type Boolean.
185class BooleanValue final : public TypedValueBase<BooleanValue, bool> {
186 public:
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700187 using _Base::_Base; // Expose the custom constructor of the base class.
Alex Vakulenko5a9e7182014-08-11 15:59:58 -0700188 BooleanValue* GetBoolean() override { return this; }
189 BooleanValue const* GetBoolean() const override { return this; }
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700190};
191
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700192// Value of type Object.
193class ObjectValue final : public TypedValueBase<ObjectValue,
194 native_types::Object> {
195 public:
196 using _Base::_Base; // Expose the custom constructor of the base class.
Alex Vakulenko5a9e7182014-08-11 15:59:58 -0700197 ObjectValue* GetObject() override { return this; }
198 ObjectValue const* GetObject() const override { return this; }
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700199};
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700200} // namespace buffet
201
202#endif // BUFFET_COMMANDS_PROP_VALUES_H_