载入中...
搜索中...
未找到
Value.cpp
浏览该文件的文档.
1#include "common/Value.h"
2
3#include "common/Json.h"
4
5#include <cmath>
6#include <cstdint>
7#include <cstdio>
8#include <string>
9#include <string_view>
10#include <utility>
11
12namespace eve {
13namespace {
14
15Result<Value> copyJsonValue(const json::Value& source) {
16 if (source.isNull()) return Result<Value>::success(Value());
17 if (source.isBool()) return Result<Value>::success(Value(source.asBool()));
18 if (source.isString()) return Result<Value>::success(Value(source.asString()));
19
20 if (source.isNumber()) {
21 if (source.isIntegerLiteral()) {
22 if (!source.isInt64()) {
24 Diagnostic::error(DiagnosticCode::ParseError, "JSON integer is outside the canonical Int64 range"));
25 }
26 return Result<Value>::success(Value(source.asInt64()));
27 }
28 return Result<Value>::success(Value(source.asDouble()));
29 }
30
31 if (source.isArray()) {
32 Value::Array result;
33 result.reserve(source.size());
34 for (std::size_t index = 0; index < source.size(); ++index) {
35 auto element = copyJsonValue(source.at(index));
36 if (!element.ok()) return Result<Value>::failure(element.status());
37 result.push_back(std::move(element).takeValue());
38 }
39 return Result<Value>::success(Value(std::move(result)));
40 }
41
42 if (source.isObject()) {
43 Value::Object result;
44 for (const std::string& key : source.keys()) {
45 auto member = copyJsonValue(source.get(key.c_str()));
46 if (!member.ok()) return Result<Value>::failure(member.status());
47 result.emplace(key, std::move(member).takeValue());
48 }
49 return Result<Value>::success(Value(std::move(result)));
50 }
51
52 return Result<Value>::failure(Diagnostic::error(DiagnosticCode::ParseError, "unsupported JSON value kind"));
53}
54
55} // namespace
56
57Result<Value> Value::fromJson(std::string_view jsonText) {
58 const std::string input(jsonText);
59 std::string error;
61 if (!document.valid()) {
63 }
64 return copyJsonValue(document.root());
65}
66
68
69std::int64_t Value::asInt() const {
70 const auto* value = getIf<std::int64_t>();
71 EV_ASSERT(value != nullptr, "Value::asInt requires an Int64 value");
72 return value ? *value : 0;
73}
74
75double Value::asDouble() const {
76 const auto* value = getIf<double>();
77 EV_ASSERT(value != nullptr, "Value::asDouble requires a Double value");
78 return value ? *value : 0.0;
79}
80
81bool Value::asBool() const {
82 const auto* value = getIf<bool>();
83 EV_ASSERT(value != nullptr, "Value::asBool requires a Bool value");
84 return value ? *value : false;
85}
86
87const std::string& Value::asString() const {
88 const auto* value = getIf<std::string>();
89 EV_ASSERT(value != nullptr, "Value::asString requires a String value");
90 static const std::string empty;
91 return value ? *value : empty;
92}
93
95 auto* array = getIf<Array>();
96 EV_ASSERT(array != nullptr, "Value::pushBack requires an Array value");
97 if (array) array->push_back(std::move(value));
98}
99
100std::size_t Value::arraySize() const {
101 const auto* array = getIf<Array>();
102 EV_ASSERT(array != nullptr, "Value::arraySize requires an Array value");
103 return array ? array->size() : 0;
104}
105
106Value& Value::at(std::size_t index) {
107 auto* array = getIf<Array>();
108 EV_ASSERT(array != nullptr, "Value::at requires an Array value");
109 return array->at(index);
110}
111
112const Value& Value::at(std::size_t index) const {
113 const auto* array = getIf<Array>();
114 EV_ASSERT(array != nullptr, "Value::at requires an Array value");
115 return array->at(index);
116}
117
118void Value::set(const std::string& key, Value value) {
119 auto* object = getIf<Object>();
120 EV_ASSERT(object != nullptr, "Value::set requires an Object value");
121 if (object) (*object)[key] = std::move(value);
122}
123
124Value* Value::find(const std::string& key) noexcept {
125 auto* object = getIf<Object>();
126 if (!object) return nullptr;
127 const auto it = object->find(key);
128 return it == object->end() ? nullptr : &it->second;
129}
130
131const Value* Value::find(const std::string& key) const noexcept {
132 const auto* object = getIf<Object>();
133 if (!object) return nullptr;
134 const auto it = object->find(key);
135 return it == object->end() ? nullptr : &it->second;
136}
137
138std::vector<std::string> Value::keys() const {
139 const auto* object = getIf<Object>();
140 if (!object) return {};
141 std::vector<std::string> result;
142 result.reserve(object->size());
143 for (const auto& [key, value] : *object) {
144 (void)value;
145 result.push_back(key);
146 }
147 return result;
148}
149
150std::string Value::typeName() const {
151 switch (type()) {
152 case Type::Null: return "null";
153 case Type::Bool: return "bool";
154 case Type::Int64: return "int";
155 case Type::Double: return "float";
156 case Type::String: return "string";
157 case Type::Array: return "array";
158 case Type::Object: return "object";
159 }
160 return "null";
161}
162
163std::string Value::toString() const {
164 if (isString()) return asString();
165 if (isInt64()) return std::to_string(asInt());
166 if (isDouble()) {
167 char buffer[64];
168 std::snprintf(buffer, sizeof(buffer), "%g", asDouble());
169 return buffer;
170 }
171 if (isBool()) return asBool() ? "true" : "false";
172 return {};
173}
174
175} // namespace eve
double value
#define EV_ASSERT(cond,...)
Assert an internal engine invariant (state that must always hold).
Definition Assert.h:37
EvpackChunkInput input
Definition Evpack.cpp:170
std::uint32_t key
std::unique_ptr< gpgpu::GpuBuffer > buffer
Definition OnnxGpgpu.cpp:26
std::string error
Definition Package.cpp:60
std::string element
Json object
float(ui::Theme::* member)[4]
uint32_t index
const UnitySourceAsset & source
Owning, renderer-independent dynamic values.
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
Move-only operation result carrying either a value or Status.
Definition Result.h:155
static Result success(T value)
Construct a successful result owning value.
Definition Result.h:164
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
The canonical owning dynamic value used by data-facing protocols.
Definition Value.h:31
Result< std::string > toJson() const
Serialize this value as deterministic compact JSON.
Definition Value.cpp:67
const std::string & asString() const
Return the string payload; the caller must have checked the kind.
Definition Value.cpp:87
bool isInt64() const noexcept
Return true when this value is an Int64.
Definition Value.h:91
static Result< Value > fromJson(std::string_view json)
Parse one strict JSON value into an owning Value.
Definition Value.cpp:57
std::string typeName() const
Return the compatibility type name used by dialogue scripts.
Definition Value.cpp:150
std::map< std::string, Value > Object
Definition Value.h:34
std::vector< std::string > keys() const
Return object member names in deterministic order.
Definition Value.cpp:138
double asDouble() const
Return the Double payload; the caller must have checked the kind.
Definition Value.cpp:75
void set(const std::string &key, Value value)
Insert or replace an object member.
Definition Value.cpp:118
bool isString() const noexcept
Return true when this value is a string.
Definition Value.h:95
std::int64_t asInt() const
Return the Int64 payload; the caller must have checked the kind.
Definition Value.cpp:69
static Value array(Array value)
Compatibility factory for an array value.
Definition Value.h:112
std::vector< Value > Array
Definition Value.h:33
std::string toString() const
Render a scalar using the former dialogue formatting rules.
Definition Value.cpp:163
void pushBack(Value value)
Append an element to an array value.
Definition Value.cpp:94
std::size_t arraySize() const
Return the number of array elements.
Definition Value.cpp:100
bool asBool() const
Return the boolean payload; the caller must have checked the kind.
Definition Value.cpp:81
bool isBool() const noexcept
Return true when this value is a boolean.
Definition Value.h:89
Value & at(std::size_t index)
Return a bounds-checked array element.
Definition Value.cpp:106
bool isDouble() const noexcept
Return true when this value is a Double.
Definition Value.h:93
Type type() const noexcept
Return the active value kind.
Definition Value.h:83
Value * find(const std::string &key) noexcept
Return an object member, or nullptr when absent.
Definition Value.cpp:124
EVENGINE_API_FOUNDATION public API.
Definition Json.h:136
bool valid() const
Valid.
Definition Json.h:157
static Document parse(const std::string &text, std::string *error=nullptr)
Parse.
Definition Json.cpp:581
Value root() const
Root.
Definition Json.h:159
std::variant< std::monostate, std::int64_t, double, std::string, bool > Value
Definition Database.h:26
Result< std::string > stringify(const eve::Value &value)
Serialize the canonical owning Value as deterministic compact JSON.
Definition Json.cpp:563
Build metadata (engine git commit, build time, third-party version).
Definition Build.cpp:16