blob: adaa91dc338533f1f4f9c5aedac06bcaad0417e7 [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 Vakulenko66ec2922014-06-17 15:30:22 -070012#include "buffet/any.h"
13#include "buffet/commands/schema_utils.h"
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070014#include "buffet/error.h"
15
16namespace base {
17class Value;
18class DictionaryValue;
19} // namespace base
20
21namespace buffet {
22
23// Enumeration to indicate supported command parameter types.
24enum class ValueType {
25 Int,
26 Double,
27 String,
Alex Vakulenko66ec2922014-06-17 15:30:22 -070028 Boolean,
29 Object
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070030};
31
Alex Vakulenko66ec2922014-06-17 15:30:22 -070032class PropValue;
33class IntValue;
34class DoubleValue;
35class StringValue;
36class BooleanValue;
37class ObjectValue;
38
39class PropType;
40
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070041// Helper methods to get the parameter type enum value for the given
42// native C++ data representation.
43// The generic GetValueType<T>() is undefined, however particular
44// type specializations return the appropriate ValueType.
45template<typename T> ValueType GetValueType(); // Undefined.
Alex Vakulenko66ec2922014-06-17 15:30:22 -070046template<>
47inline ValueType GetValueType<int>() { return ValueType::Int; }
48template<>
49inline ValueType GetValueType<double>() { return ValueType::Double; }
50template<>
51inline ValueType GetValueType<std::string>() { return ValueType::String; }
52template<>
53inline ValueType GetValueType<bool>() { return ValueType::Boolean; }
54template<>
55inline ValueType GetValueType<native_types::Object>() {
56 return ValueType::Object;
57}
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070058
Alex Vakulenko66ec2922014-06-17 15:30:22 -070059// The base class for property values.
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070060// Concrete value classes of various types will be derived from this base.
Alex Vakulenko66ec2922014-06-17 15:30:22 -070061// A property value is the actual command parameter value (or a concrete value
62// that can be used in constraints and presets). The PropValue is mostly
63// just parsed content of base::Value when a command is dispatched, however
64// it does have some additional functionality:
65// - it has a reference to the type definition (PropType) which is used
66// when validating the value, especially for "object" types.
67// - it can be compared with another instances of values of the same type.
68// This is used to validate the values against "enum"/"one of" constraints.
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070069class PropValue {
70 public:
Alex Vakulenko66ec2922014-06-17 15:30:22 -070071 explicit PropValue(const PropType* type)
72 : type_(type) {}
73 virtual ~PropValue() = default;
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070074
75 // Gets the type of the value.
76 virtual ValueType GetType() const = 0;
77
78 // Type conversion methods. Used in lieu of RTTI and dynamic_cast<>.
79 virtual IntValue* GetInt() { return nullptr; }
80 virtual IntValue const* GetInt() const { return nullptr; }
81 virtual DoubleValue* GetDouble() { return nullptr; }
82 virtual DoubleValue const* GetDouble() const { return nullptr; }
83 virtual StringValue* GetString() { return nullptr; }
84 virtual StringValue const* GetString() const { return nullptr; }
85 virtual BooleanValue* GetBoolean() { return nullptr; }
86 virtual BooleanValue const* GetBoolean() const { return nullptr; }
Alex Vakulenko66ec2922014-06-17 15:30:22 -070087 virtual ObjectValue* GetObject() { return nullptr; }
88 virtual ObjectValue const* GetObject() const { return nullptr; }
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070089
90 // Makes a full copy of this value class.
91 virtual std::shared_ptr<PropValue> Clone() const = 0;
92
93 // Saves the value as a JSON object.
94 // If it fails, returns nullptr value and fills in the details for the
95 // failure in the |error| parameter.
96 virtual std::unique_ptr<base::Value> ToJson(ErrorPtr* error) const = 0;
97 // Parses a value from JSON.
98 // If it fails, it returns false and provides additional information
99 // via the |error| parameter.
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700100 virtual bool FromJson(const base::Value* value,
101 ErrorPtr* error) = 0;
102
103 // Returns the contained C++ value as Any.
104 virtual Any GetValueAsAny() const = 0;
105
106 // Return the type definition of this value.
107 const PropType* GetPropType() const { return type_; }
108 // Compares two values and returns true if they are equal.
109 virtual bool IsEqual(const PropValue* value) const = 0;
110
111 protected:
112 const PropType* type_; // weak pointer
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700113};
114
115// A helper template base class for implementing simple (non-Object) value
116// classes.
117template<typename Derived, typename T>
118class TypedValueBase : public PropValue {
119 public:
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700120 // To help refer to this base class from derived classes, define _Base to
121 // be this class.
122 using _Base = TypedValueBase<Derived, T>;
123 // Expose the non-default constructor of the base class.
124 using PropValue::PropValue;
125
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700126 // Overrides from PropValue base class.
127 virtual ValueType GetType() const override { return GetValueType<T>(); }
128 virtual std::shared_ptr<PropValue> Clone() const override {
129 return std::make_shared<Derived>(*static_cast<const Derived*>(this));
130 }
131
132 virtual std::unique_ptr<base::Value> ToJson(ErrorPtr* error) const override {
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700133 return TypedValueToJson(value_, error);
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700134 }
135
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700136 virtual bool FromJson(const base::Value* value,
137 ErrorPtr* error) override {
138 return TypedValueFromJson(value, GetPropType()->GetObjectSchemaPtr(),
139 &value_, error);
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700140 }
141
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700142 virtual bool IsEqual(const PropValue* value) const override {
143 if (GetType() != value->GetType())
144 return false;
145 const _Base* value_base = static_cast<const _Base*>(value);
146 return CompareValue(GetValue(), value_base->GetValue());
147 }
148
149 // Helper methods to get and set the C++ representation of the value.
150 virtual Any GetValueAsAny() const override { return value_; }
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700151 const T& GetValue() const { return value_; }
152 void SetValue(T value) { value_ = std::move(value); }
153
154 protected:
155 T value_{}; // The value of the parameter in C++ data representation.
156};
157
158// Value of type Integer.
159class IntValue final : public TypedValueBase<IntValue, int> {
160 public:
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700161 using _Base::_Base; // Expose the custom constructor of the base class.
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700162 virtual IntValue* GetInt() override { return this; }
163 virtual IntValue const* GetInt() const override { return this; }
164};
165
166// Value of type Number.
167class DoubleValue final : public TypedValueBase<DoubleValue, double> {
168 public:
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700169 using _Base::_Base; // Expose the custom constructor of the base class.
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700170 virtual DoubleValue* GetDouble() override { return this; }
171 virtual DoubleValue const* GetDouble() const override { return this; }
172};
173
174// Value of type String.
175class StringValue final : public TypedValueBase<StringValue, std::string> {
176 public:
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700177 using _Base::_Base; // Expose the custom constructor of the base class.
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700178 virtual StringValue* GetString() override { return this; }
179 virtual StringValue const* GetString() const override { return this; }
180};
181
182// Value of type Boolean.
183class BooleanValue final : public TypedValueBase<BooleanValue, bool> {
184 public:
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700185 using _Base::_Base; // Expose the custom constructor of the base class.
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700186 virtual BooleanValue* GetBoolean() override { return this; }
187 virtual BooleanValue const* GetBoolean() const override { return this; }
188};
189
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700190// Value of type Object.
191class ObjectValue final : public TypedValueBase<ObjectValue,
192 native_types::Object> {
193 public:
194 using _Base::_Base; // Expose the custom constructor of the base class.
195 virtual ObjectValue* GetObject() override { return this; }
196 virtual ObjectValue const* GetObject() const override { return this; }
197};
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700198} // namespace buffet
199
200#endif // BUFFET_COMMANDS_PROP_VALUES_H_