6#include <Ultralight/CAPI/CAPI_DOMData.h>
25inline constexpr bool kNoValueConversion =
false;
105 bool IsEmpty()
const {
return state_ == State::kEmpty; }
110 explicit operator bool()
const {
return !
IsEmpty(); }
135 bool IsObject()
const {
return state_ == State::kObject; }
146 if (state_ == State::kObject && name) {
147 for (
const auto& member : members_) {
148 if (member.first == name)
149 return member.second;
161 if (state_ != State::kObject || !name)
163 for (
const auto& member : members_) {
164 if (member.first == name)
181 template <
typename T>
183 std::optional<T> value =
Maybe<T>();
185 return std::move(*value);
194 template <
typename T>
195 [[nodiscard]] std::optional<T>
Maybe()
const {
196 static_assert(!std::is_same_v<std::remove_cvref_t<T>, std::string_view>
197 && !std::is_same_v<std::remove_cvref_t<T>,
const char*>,
198 "a Value conversion must produce an OWNING type; read strings as "
199 "String or std::string");
200 using Plain = std::remove_cvref_t<T>;
201 if (state_ != State::kLeaf)
203 if constexpr (std::is_same_v<Plain, bool>) {
206 }
else if constexpr (std::is_integral_v<Plain>) {
208 return static_cast<Plain
>(int_);
209 }
else if constexpr (std::is_floating_point_v<Plain>) {
211 return static_cast<Plain
>(double_);
213 return static_cast<Plain
>(int_);
214 }
else if constexpr (std::is_same_v<Plain, ultralight::String>) {
217 }
else if constexpr (std::is_same_v<Plain, std::string>) {
220 return std::string(utf8.
data(), utf8.
length());
222#if ULTRALIGHT_REFLECTION
223 }
else if constexpr (std::is_enum_v<Plain>) {
226 const std::string_view name(utf8.
data(), utf8.
length());
227 for (
const auto& entry : detail::EnumInfo<Plain>::kEntries) {
228 if (entry.name == name)
229 return static_cast<Plain
>(entry.value);
234 static_assert(detail::kNoValueConversion<Plain>,
235 "unsupported Value conversion target: expected bool, an integral or "
236 "floating-point type, String, std::string, or a reflected enum");
248 template <
typename T>
249 [[nodiscard]] T
Or(T fallback)
const {
250 std::optional<T> value =
Maybe<T>();
251 return value ? std::move(*value) : std::move(fallback);
262 [[nodiscard]] std::string
Or(
const char* fallback)
const {
264 return value ? std::move(*value) : std::string(fallback ? fallback :
"");
282 switch (
static_cast<ValueKind>(value.kind)) {
284 result.state_ = State::kLeaf;
286 result.bool_ = value.bool_value;
289 result.state_ = State::kLeaf;
291 result.int_ = value.int64_value;
294 result.state_ = State::kLeaf;
296 result.double_ = value.double_value;
299 result.state_ = State::kLeaf;
301 result.string_ = value.string_value
329 if (!payload || payload_count == 0)
331 result.state_ = State::kObject;
332 result.members_.reserve(payload_count);
333 for (
size_t i = 0; i < payload_count; i++) {
334 if (!payload[i].name)
336 result.members_.emplace_back(payload[i].name,
FromLeaf(payload[i].value));
342 enum class State : uint8_t { kEmpty, kLeaf, kObject };
344 template <
typename T>
345 const char* MismatchMessage()
const {
347 return "cannot convert an empty Value";
348 if constexpr (std::is_same_v<std::remove_cvref_t<T>,
bool>)
349 return "expected a boolean Value";
350 else if constexpr (std::is_integral_v<std::remove_cvref_t<T>>)
351 return "expected an integer Value";
352 else if constexpr (std::is_floating_point_v<std::remove_cvref_t<T>>)
353 return "expected a numeric Value";
355 return "expected a string Value";
358 State state_ = State::kEmpty;
364 std::vector<std::pair<std::string, Value>> members_;
A null-terminated UTF-8 string container.
Definition String8.h:17
char * data()
Get raw UTF-8 data.
Definition String8.h:53
size_t length() const
Get length in bytes (not including null terminator).
Definition String8.h:59
Unicode string container with conversions for UTF-8, UTF-16, and UTF-32.
Definition String.h:31
static Error Make(ErrorType type, std::string message)
Create a native error.
Definition Error.h:151
static Value FromLeaf(const ULDOMDataLeafValue &value)
Create a leaf Value from a C leaf value.
Definition Value.h:280
std::string Or(const char *fallback) const
Convert to a std::string like To() but with a string-literal fallback.
Definition Value.h:262
Value operator[](const char *name) const
Get a member of an object.
Definition Value.h:145
bool IsInt64() const
Whether or not this Value is an integer leaf.
Definition Value.h:120
bool IsDouble() const
Whether or not this Value is a floating-point leaf.
Definition Value.h:125
T Or(T fallback) const
Convert to a C++ type like To() but with a fallback.
Definition Value.h:249
bool Contains(const char *name) const
Whether or not this Value is an object with a member of the given name.
Definition Value.h:160
bool IsObject() const
Whether or not this Value is an object (the members of an action's payload struct).
Definition Value.h:135
bool IsString() const
Whether or not this Value is a string leaf.
Definition Value.h:130
size_t member_count() const
Get the number of members (0 unless this Value is an object).
Definition Value.h:173
bool IsEmpty() const
Whether or not this Value holds nothing.
Definition Value.h:105
Result< T > To() const
Convert to a C++ type (see "Converting Values" in the class description).
Definition Value.h:182
Value()=default
Create an empty Value.
bool IsBoolean() const
Whether or not this Value is a boolean leaf.
Definition Value.h:115
static Value FromPayload(const ULDOMDataPayloadEntry *payload, size_t payload_count)
Create an object Value from a C action payload.
Definition Value.h:327
std::optional< T > Maybe() const
Convert to a C++ type like To() but without the failure reason.
Definition Value.h:195
Data-binding API that connects native C++ data to HTML and CSS markup.
Definition ActionInfo.h:13
ValueKind
The kinds of value a schema entry holds.
Definition ValueTraits.h:27
@ String
UTF-8 text (from strings and enums).
Definition ValueTraits.h:31
@ Bool
A boolean.
Definition ValueTraits.h:28
@ Double
A double-precision float (from any floating-point type).
Definition ValueTraits.h:30
@ Int64
A signed 64-bit integer (from any integer type).
Definition ValueTraits.h:29
Direct C++ access to modify page elements and handle events.
T OrEmpty(Result< T > result)
Get a Result's value, or a default-constructed T if it holds an error.
Definition Error.h:320
@ TypeError
An argument has the wrong type (eg, a submitter passed to HTMLFormElement::requestSubmit() that isn't...
Definition Error.h:54
Expected< T, Error > Result
The result of a DOM operation that can fail (either a T or a dom::Error).
Definition Error.h:277
Root namespace for every public Ultralight type, function, and enumeration.