dawn_node/interop: Return a Result instead of a bool
Provides a place to put error messages. Helps actually figure out when an overload doesn't match, a dictionary is missing a field, etc. Bug: dawn:1143 Change-Id: Ibca177f9f42676061511d27898a5c522d1e6cd8f Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/65721 Commit-Queue: Ben Clayton <bclayton@google.com> Reviewed-by: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
parent
bc6d30a2f8
commit
78632a644f
|
@ -16,136 +16,142 @@
|
||||||
|
|
||||||
namespace wgpu { namespace interop {
|
namespace wgpu { namespace interop {
|
||||||
|
|
||||||
bool Converter<bool>::FromJS(Napi::Env env, Napi::Value value, bool& out) {
|
Result Success;
|
||||||
|
|
||||||
|
Result Error(std::string msg) {
|
||||||
|
return {msg};
|
||||||
|
}
|
||||||
|
|
||||||
|
Result Converter<bool>::FromJS(Napi::Env env, Napi::Value value, bool& out) {
|
||||||
if (value.IsBoolean()) {
|
if (value.IsBoolean()) {
|
||||||
out = value.ToBoolean();
|
out = value.ToBoolean();
|
||||||
return true;
|
return Success;
|
||||||
}
|
}
|
||||||
return false;
|
return Error("value is not a boolean");
|
||||||
}
|
}
|
||||||
Napi::Value Converter<bool>::ToJS(Napi::Env env, bool value) {
|
Napi::Value Converter<bool>::ToJS(Napi::Env env, bool value) {
|
||||||
return Napi::Value::From(env, value);
|
return Napi::Value::From(env, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Converter<std::string>::FromJS(Napi::Env env, Napi::Value value, std::string& out) {
|
Result Converter<std::string>::FromJS(Napi::Env env, Napi::Value value, std::string& out) {
|
||||||
if (value.IsString()) {
|
if (value.IsString()) {
|
||||||
out = value.ToString();
|
out = value.ToString();
|
||||||
return true;
|
return Success;
|
||||||
}
|
}
|
||||||
return false;
|
return Error("value is not a string");
|
||||||
}
|
}
|
||||||
Napi::Value Converter<std::string>::ToJS(Napi::Env env, std::string value) {
|
Napi::Value Converter<std::string>::ToJS(Napi::Env env, std::string value) {
|
||||||
return Napi::Value::From(env, value);
|
return Napi::Value::From(env, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Converter<int8_t>::FromJS(Napi::Env env, Napi::Value value, int8_t& out) {
|
Result Converter<int8_t>::FromJS(Napi::Env env, Napi::Value value, int8_t& out) {
|
||||||
if (value.IsNumber()) {
|
if (value.IsNumber()) {
|
||||||
out = value.ToNumber().Int32Value();
|
out = value.ToNumber().Int32Value();
|
||||||
return true;
|
return Success;
|
||||||
}
|
}
|
||||||
return false;
|
return Error("value is not a number");
|
||||||
}
|
}
|
||||||
Napi::Value Converter<int8_t>::ToJS(Napi::Env env, int8_t value) {
|
Napi::Value Converter<int8_t>::ToJS(Napi::Env env, int8_t value) {
|
||||||
return Napi::Value::From(env, value);
|
return Napi::Value::From(env, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Converter<uint8_t>::FromJS(Napi::Env env, Napi::Value value, uint8_t& out) {
|
Result Converter<uint8_t>::FromJS(Napi::Env env, Napi::Value value, uint8_t& out) {
|
||||||
if (value.IsNumber()) {
|
if (value.IsNumber()) {
|
||||||
out = value.ToNumber().Uint32Value();
|
out = value.ToNumber().Uint32Value();
|
||||||
return true;
|
return Success;
|
||||||
}
|
}
|
||||||
return false;
|
return Error("value is not a number");
|
||||||
}
|
}
|
||||||
Napi::Value Converter<uint8_t>::ToJS(Napi::Env env, uint8_t value) {
|
Napi::Value Converter<uint8_t>::ToJS(Napi::Env env, uint8_t value) {
|
||||||
return Napi::Value::From(env, value);
|
return Napi::Value::From(env, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Converter<int16_t>::FromJS(Napi::Env env, Napi::Value value, int16_t& out) {
|
Result Converter<int16_t>::FromJS(Napi::Env env, Napi::Value value, int16_t& out) {
|
||||||
if (value.IsNumber()) {
|
if (value.IsNumber()) {
|
||||||
out = value.ToNumber().Int32Value();
|
out = value.ToNumber().Int32Value();
|
||||||
return true;
|
return Success;
|
||||||
}
|
}
|
||||||
return false;
|
return Error("value is not a number");
|
||||||
}
|
}
|
||||||
Napi::Value Converter<int16_t>::ToJS(Napi::Env env, int16_t value) {
|
Napi::Value Converter<int16_t>::ToJS(Napi::Env env, int16_t value) {
|
||||||
return Napi::Value::From(env, value);
|
return Napi::Value::From(env, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Converter<uint16_t>::FromJS(Napi::Env env, Napi::Value value, uint16_t& out) {
|
Result Converter<uint16_t>::FromJS(Napi::Env env, Napi::Value value, uint16_t& out) {
|
||||||
if (value.IsNumber()) {
|
if (value.IsNumber()) {
|
||||||
out = value.ToNumber().Uint32Value();
|
out = value.ToNumber().Uint32Value();
|
||||||
return true;
|
return Success;
|
||||||
}
|
}
|
||||||
return false;
|
return Error("value is not a number");
|
||||||
}
|
}
|
||||||
Napi::Value Converter<uint16_t>::ToJS(Napi::Env env, uint16_t value) {
|
Napi::Value Converter<uint16_t>::ToJS(Napi::Env env, uint16_t value) {
|
||||||
return Napi::Value::From(env, value);
|
return Napi::Value::From(env, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Converter<int32_t>::FromJS(Napi::Env env, Napi::Value value, int32_t& out) {
|
Result Converter<int32_t>::FromJS(Napi::Env env, Napi::Value value, int32_t& out) {
|
||||||
if (value.IsNumber()) {
|
if (value.IsNumber()) {
|
||||||
out = value.ToNumber().Int32Value();
|
out = value.ToNumber().Int32Value();
|
||||||
return true;
|
return Success;
|
||||||
}
|
}
|
||||||
return false;
|
return Error("value is not a number");
|
||||||
}
|
}
|
||||||
Napi::Value Converter<int32_t>::ToJS(Napi::Env env, int32_t value) {
|
Napi::Value Converter<int32_t>::ToJS(Napi::Env env, int32_t value) {
|
||||||
return Napi::Value::From(env, value);
|
return Napi::Value::From(env, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Converter<uint32_t>::FromJS(Napi::Env env, Napi::Value value, uint32_t& out) {
|
Result Converter<uint32_t>::FromJS(Napi::Env env, Napi::Value value, uint32_t& out) {
|
||||||
if (value.IsNumber()) {
|
if (value.IsNumber()) {
|
||||||
out = value.ToNumber().Uint32Value();
|
out = value.ToNumber().Uint32Value();
|
||||||
return true;
|
return Success;
|
||||||
}
|
}
|
||||||
return false;
|
return Error("value is not a number");
|
||||||
}
|
}
|
||||||
Napi::Value Converter<uint32_t>::ToJS(Napi::Env env, uint32_t value) {
|
Napi::Value Converter<uint32_t>::ToJS(Napi::Env env, uint32_t value) {
|
||||||
return Napi::Value::From(env, value);
|
return Napi::Value::From(env, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Converter<int64_t>::FromJS(Napi::Env env, Napi::Value value, int64_t& out) {
|
Result Converter<int64_t>::FromJS(Napi::Env env, Napi::Value value, int64_t& out) {
|
||||||
if (value.IsNumber()) {
|
if (value.IsNumber()) {
|
||||||
out = value.ToNumber().Int64Value();
|
out = value.ToNumber().Int64Value();
|
||||||
return true;
|
return Success;
|
||||||
}
|
}
|
||||||
return false;
|
return Error("value is not a number");
|
||||||
}
|
}
|
||||||
Napi::Value Converter<int64_t>::ToJS(Napi::Env env, int64_t value) {
|
Napi::Value Converter<int64_t>::ToJS(Napi::Env env, int64_t value) {
|
||||||
return Napi::Value::From(env, value);
|
return Napi::Value::From(env, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Converter<uint64_t>::FromJS(Napi::Env env, Napi::Value value, uint64_t& out) {
|
Result Converter<uint64_t>::FromJS(Napi::Env env, Napi::Value value, uint64_t& out) {
|
||||||
if (value.IsNumber()) {
|
if (value.IsNumber()) {
|
||||||
// Note that the JS Number type only stores doubles, so the max integer
|
// Note that the JS Number type only stores doubles, so the max integer
|
||||||
// range of values without precision loss is -2^53 to 2^53 (52 bit mantissa
|
// range of values without precision loss is -2^53 to 2^53 (52 bit mantissa
|
||||||
// with 1 implicit bit). This is why there's no UInt64Value() function.
|
// with 1 implicit bit). This is why there's no UInt64Value() function.
|
||||||
out = static_cast<uint64_t>(value.ToNumber().Int64Value());
|
out = static_cast<uint64_t>(value.ToNumber().Int64Value());
|
||||||
return true;
|
return Success;
|
||||||
}
|
}
|
||||||
return false;
|
return Error("value is not a number");
|
||||||
}
|
}
|
||||||
Napi::Value Converter<uint64_t>::ToJS(Napi::Env env, uint64_t value) {
|
Napi::Value Converter<uint64_t>::ToJS(Napi::Env env, uint64_t value) {
|
||||||
return Napi::Value::From(env, value);
|
return Napi::Value::From(env, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Converter<float>::FromJS(Napi::Env env, Napi::Value value, float& out) {
|
Result Converter<float>::FromJS(Napi::Env env, Napi::Value value, float& out) {
|
||||||
if (value.IsNumber()) {
|
if (value.IsNumber()) {
|
||||||
out = value.ToNumber().FloatValue();
|
out = value.ToNumber().FloatValue();
|
||||||
return true;
|
return Success;
|
||||||
}
|
}
|
||||||
return false;
|
return Error("value is not a number");
|
||||||
}
|
}
|
||||||
Napi::Value Converter<float>::ToJS(Napi::Env env, float value) {
|
Napi::Value Converter<float>::ToJS(Napi::Env env, float value) {
|
||||||
return Napi::Value::From(env, value);
|
return Napi::Value::From(env, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Converter<double>::FromJS(Napi::Env env, Napi::Value value, double& out) {
|
Result Converter<double>::FromJS(Napi::Env env, Napi::Value value, double& out) {
|
||||||
if (value.IsNumber()) {
|
if (value.IsNumber()) {
|
||||||
out = value.ToNumber().DoubleValue();
|
out = value.ToNumber().DoubleValue();
|
||||||
return true;
|
return Success;
|
||||||
}
|
}
|
||||||
return false;
|
return Error("value is not a number");
|
||||||
}
|
}
|
||||||
Napi::Value Converter<double>::ToJS(Napi::Env env, double value) {
|
Napi::Value Converter<double>::ToJS(Napi::Env env, double value) {
|
||||||
return Napi::Value::From(env, value);
|
return Napi::Value::From(env, value);
|
||||||
|
|
|
@ -58,6 +58,42 @@ namespace wgpu { namespace interop {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using FrozenArray = std::vector<T>;
|
using FrozenArray = std::vector<T>;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Result
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Result is used to hold an success / error state by functions that perform JS <-> C++
|
||||||
|
// conversion
|
||||||
|
struct [[nodiscard]] Result {
|
||||||
|
// Returns true if the operation succeeded, false if there was an error
|
||||||
|
inline operator bool() const {
|
||||||
|
return error.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If Result is an error, then a new Error is returned with the
|
||||||
|
// stringified values append to the error message.
|
||||||
|
// If Result is a success, then a success Result is returned.
|
||||||
|
template <typename... VALUES>
|
||||||
|
Result Append(VALUES && ... values) {
|
||||||
|
if (*this) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << error << "\n";
|
||||||
|
utils::Write(ss, std::forward<VALUES>(values)...);
|
||||||
|
return {ss.str()};
|
||||||
|
}
|
||||||
|
|
||||||
|
// The error message, if the operation failed.
|
||||||
|
std::string error;
|
||||||
|
};
|
||||||
|
|
||||||
|
// A successful result
|
||||||
|
extern Result Success;
|
||||||
|
|
||||||
|
// Returns a Result with the given error message
|
||||||
|
Result Error(std::string msg);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Interface<T>
|
// Interface<T>
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -200,8 +236,7 @@ namespace wgpu { namespace interop {
|
||||||
// with the signatures:
|
// with the signatures:
|
||||||
//
|
//
|
||||||
// // FromJS() converts the JavaScript value 'in' to the C++ value 'out'.
|
// // FromJS() converts the JavaScript value 'in' to the C++ value 'out'.
|
||||||
// // Returns true on success, false on failure.
|
// static Result FromJS(Napi::Env, Napi::Value in, T& out);
|
||||||
// static bool FromJS(Napi::Env, Napi::Value in, T& out);
|
|
||||||
//
|
//
|
||||||
// // ToJS() converts the C++ value 'in' to a JavaScript value, and returns
|
// // ToJS() converts the C++ value 'in' to a JavaScript value, and returns
|
||||||
// // this value.
|
// // this value.
|
||||||
|
@ -212,12 +247,12 @@ namespace wgpu { namespace interop {
|
||||||
template <>
|
template <>
|
||||||
class Converter<Napi::Object> {
|
class Converter<Napi::Object> {
|
||||||
public:
|
public:
|
||||||
static inline bool FromJS(Napi::Env, Napi::Value value, Napi::Object& out) {
|
static inline Result FromJS(Napi::Env, Napi::Value value, Napi::Object& out) {
|
||||||
if (value.IsObject()) {
|
if (value.IsObject()) {
|
||||||
out = value.ToObject();
|
out = value.ToObject();
|
||||||
return true;
|
return Success;
|
||||||
}
|
}
|
||||||
return false;
|
return Error("value is not an object");
|
||||||
}
|
}
|
||||||
static inline Napi::Value ToJS(Napi::Env, Napi::Object value) {
|
static inline Napi::Value ToJS(Napi::Env, Napi::Object value) {
|
||||||
return value;
|
return value;
|
||||||
|
@ -227,12 +262,12 @@ namespace wgpu { namespace interop {
|
||||||
template <>
|
template <>
|
||||||
class Converter<ArrayBuffer> {
|
class Converter<ArrayBuffer> {
|
||||||
public:
|
public:
|
||||||
static inline bool FromJS(Napi::Env, Napi::Value value, ArrayBuffer& out) {
|
static inline Result FromJS(Napi::Env, Napi::Value value, ArrayBuffer& out) {
|
||||||
if (value.IsArrayBuffer()) {
|
if (value.IsArrayBuffer()) {
|
||||||
out = value.As<ArrayBuffer>();
|
out = value.As<ArrayBuffer>();
|
||||||
return true;
|
return Success;
|
||||||
}
|
}
|
||||||
return false;
|
return Error("value is not a ArrayBuffer");
|
||||||
};
|
};
|
||||||
static inline Napi::Value ToJS(Napi::Env, ArrayBuffer value) {
|
static inline Napi::Value ToJS(Napi::Env, ArrayBuffer value) {
|
||||||
return value;
|
return value;
|
||||||
|
@ -242,12 +277,12 @@ namespace wgpu { namespace interop {
|
||||||
template <>
|
template <>
|
||||||
class Converter<Napi::TypedArray> {
|
class Converter<Napi::TypedArray> {
|
||||||
public:
|
public:
|
||||||
static inline bool FromJS(Napi::Env, Napi::Value value, Napi::TypedArray& out) {
|
static inline Result FromJS(Napi::Env, Napi::Value value, Napi::TypedArray& out) {
|
||||||
if (value.IsTypedArray()) {
|
if (value.IsTypedArray()) {
|
||||||
out = value.As<Napi::TypedArray>();
|
out = value.As<Napi::TypedArray>();
|
||||||
return true;
|
return Success;
|
||||||
}
|
}
|
||||||
return false;
|
return Error("value is not a TypedArray");
|
||||||
};
|
};
|
||||||
static inline Napi::Value ToJS(Napi::Env, ArrayBuffer value) {
|
static inline Napi::Value ToJS(Napi::Env, ArrayBuffer value) {
|
||||||
return value;
|
return value;
|
||||||
|
@ -274,15 +309,16 @@ namespace wgpu { namespace interop {
|
||||||
// clang-format on
|
// clang-format on
|
||||||
static_assert(static_cast<int>(element_type) >= 0,
|
static_assert(static_cast<int>(element_type) >= 0,
|
||||||
"unsupported T type for Napi::TypedArrayOf<T>");
|
"unsupported T type for Napi::TypedArrayOf<T>");
|
||||||
static inline bool FromJS(Napi::Env, Napi::Value value, Napi::TypedArrayOf<T>& out) {
|
static inline Result FromJS(Napi::Env, Napi::Value value, Napi::TypedArrayOf<T>& out) {
|
||||||
if (value.IsTypedArray()) {
|
if (value.IsTypedArray()) {
|
||||||
auto arr = value.As<Napi::TypedArrayOf<T>>();
|
auto arr = value.As<Napi::TypedArrayOf<T>>();
|
||||||
if (arr.TypedArrayType() == element_type) {
|
if (arr.TypedArrayType() == element_type) {
|
||||||
out = arr;
|
out = arr;
|
||||||
return true;
|
return Success;
|
||||||
}
|
}
|
||||||
|
return Error("value is not a TypedArray of the correct element type");
|
||||||
}
|
}
|
||||||
return false;
|
return Error("value is not a TypedArray");
|
||||||
};
|
};
|
||||||
static inline Napi::Value ToJS(Napi::Env, ArrayBuffer value) {
|
static inline Napi::Value ToJS(Napi::Env, ArrayBuffer value) {
|
||||||
return value;
|
return value;
|
||||||
|
@ -292,99 +328,100 @@ namespace wgpu { namespace interop {
|
||||||
template <>
|
template <>
|
||||||
class Converter<std::string> {
|
class Converter<std::string> {
|
||||||
public:
|
public:
|
||||||
static bool FromJS(Napi::Env, Napi::Value, std::string&);
|
static Result FromJS(Napi::Env, Napi::Value, std::string&);
|
||||||
static Napi::Value ToJS(Napi::Env, std::string);
|
static Napi::Value ToJS(Napi::Env, std::string);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class Converter<bool> {
|
class Converter<bool> {
|
||||||
public:
|
public:
|
||||||
static bool FromJS(Napi::Env, Napi::Value, bool&);
|
static Result FromJS(Napi::Env, Napi::Value, bool&);
|
||||||
static Napi::Value ToJS(Napi::Env, bool);
|
static Napi::Value ToJS(Napi::Env, bool);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class Converter<int8_t> {
|
class Converter<int8_t> {
|
||||||
public:
|
public:
|
||||||
static bool FromJS(Napi::Env, Napi::Value, int8_t&);
|
static Result FromJS(Napi::Env, Napi::Value, int8_t&);
|
||||||
static Napi::Value ToJS(Napi::Env, int8_t);
|
static Napi::Value ToJS(Napi::Env, int8_t);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class Converter<uint8_t> {
|
class Converter<uint8_t> {
|
||||||
public:
|
public:
|
||||||
static bool FromJS(Napi::Env, Napi::Value, uint8_t&);
|
static Result FromJS(Napi::Env, Napi::Value, uint8_t&);
|
||||||
static Napi::Value ToJS(Napi::Env, uint8_t);
|
static Napi::Value ToJS(Napi::Env, uint8_t);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class Converter<int16_t> {
|
class Converter<int16_t> {
|
||||||
public:
|
public:
|
||||||
static bool FromJS(Napi::Env, Napi::Value, int16_t&);
|
static Result FromJS(Napi::Env, Napi::Value, int16_t&);
|
||||||
static Napi::Value ToJS(Napi::Env, int16_t);
|
static Napi::Value ToJS(Napi::Env, int16_t);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class Converter<uint16_t> {
|
class Converter<uint16_t> {
|
||||||
public:
|
public:
|
||||||
static bool FromJS(Napi::Env, Napi::Value, uint16_t&);
|
static Result FromJS(Napi::Env, Napi::Value, uint16_t&);
|
||||||
static Napi::Value ToJS(Napi::Env, uint16_t);
|
static Napi::Value ToJS(Napi::Env, uint16_t);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class Converter<int32_t> {
|
class Converter<int32_t> {
|
||||||
public:
|
public:
|
||||||
static bool FromJS(Napi::Env, Napi::Value, int32_t&);
|
static Result FromJS(Napi::Env, Napi::Value, int32_t&);
|
||||||
static Napi::Value ToJS(Napi::Env, int32_t);
|
static Napi::Value ToJS(Napi::Env, int32_t);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class Converter<uint32_t> {
|
class Converter<uint32_t> {
|
||||||
public:
|
public:
|
||||||
static bool FromJS(Napi::Env, Napi::Value, uint32_t&);
|
static Result FromJS(Napi::Env, Napi::Value, uint32_t&);
|
||||||
static Napi::Value ToJS(Napi::Env, uint32_t);
|
static Napi::Value ToJS(Napi::Env, uint32_t);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class Converter<int64_t> {
|
class Converter<int64_t> {
|
||||||
public:
|
public:
|
||||||
static bool FromJS(Napi::Env, Napi::Value, int64_t&);
|
static Result FromJS(Napi::Env, Napi::Value, int64_t&);
|
||||||
static Napi::Value ToJS(Napi::Env, int64_t);
|
static Napi::Value ToJS(Napi::Env, int64_t);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class Converter<uint64_t> {
|
class Converter<uint64_t> {
|
||||||
public:
|
public:
|
||||||
static bool FromJS(Napi::Env, Napi::Value, uint64_t&);
|
static Result FromJS(Napi::Env, Napi::Value, uint64_t&);
|
||||||
static Napi::Value ToJS(Napi::Env, uint64_t);
|
static Napi::Value ToJS(Napi::Env, uint64_t);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class Converter<float> {
|
class Converter<float> {
|
||||||
public:
|
public:
|
||||||
static bool FromJS(Napi::Env, Napi::Value, float&);
|
static Result FromJS(Napi::Env, Napi::Value, float&);
|
||||||
static Napi::Value ToJS(Napi::Env, float);
|
static Napi::Value ToJS(Napi::Env, float);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class Converter<double> {
|
class Converter<double> {
|
||||||
public:
|
public:
|
||||||
static bool FromJS(Napi::Env, Napi::Value, double&);
|
static Result FromJS(Napi::Env, Napi::Value, double&);
|
||||||
static Napi::Value ToJS(Napi::Env, double);
|
static Napi::Value ToJS(Napi::Env, double);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class Converter<Interface<T>> {
|
class Converter<Interface<T>> {
|
||||||
public:
|
public:
|
||||||
static bool FromJS(Napi::Env env, Napi::Value value, Interface<T>& out) {
|
static Result FromJS(Napi::Env env, Napi::Value value, Interface<T>& out) {
|
||||||
if (value.IsObject()) {
|
if (!value.IsObject()) {
|
||||||
auto obj = value.As<Napi::Object>();
|
return Error("value is not object");
|
||||||
if (T::Unwrap(obj)) {
|
|
||||||
out = Interface<T>(obj);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
auto obj = value.As<Napi::Object>();
|
||||||
|
if (!T::Unwrap(obj)) {
|
||||||
|
return Error("object is not of the correct interface type");
|
||||||
|
}
|
||||||
|
out = Interface<T>(obj);
|
||||||
|
return Success;
|
||||||
}
|
}
|
||||||
static Napi::Value ToJS(Napi::Env env, const Interface<T>& value) {
|
static Napi::Value ToJS(Napi::Env env, const Interface<T>& value) {
|
||||||
return {env, value};
|
return {env, value};
|
||||||
|
@ -394,17 +431,18 @@ namespace wgpu { namespace interop {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class Converter<std::optional<T>> {
|
class Converter<std::optional<T>> {
|
||||||
public:
|
public:
|
||||||
static bool FromJS(Napi::Env env, Napi::Value value, std::optional<T>& out) {
|
static Result FromJS(Napi::Env env, Napi::Value value, std::optional<T>& out) {
|
||||||
if (value.IsNull() || value.IsUndefined()) {
|
if (value.IsNull() || value.IsUndefined()) {
|
||||||
out.reset();
|
out.reset();
|
||||||
return true;
|
return Success;
|
||||||
}
|
}
|
||||||
T v{};
|
T v{};
|
||||||
if (!Converter<T>::FromJS(env, value, v)) {
|
auto res = Converter<T>::FromJS(env, value, v);
|
||||||
return false;
|
if (!res) {
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
out = std::move(v);
|
out = std::move(v);
|
||||||
return true;
|
return Success;
|
||||||
}
|
}
|
||||||
static Napi::Value ToJS(Napi::Env env, std::optional<T> value) {
|
static Napi::Value ToJS(Napi::Env env, std::optional<T> value) {
|
||||||
if (value.has_value()) {
|
if (value.has_value()) {
|
||||||
|
@ -417,19 +455,20 @@ namespace wgpu { namespace interop {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class Converter<std::vector<T>> {
|
class Converter<std::vector<T>> {
|
||||||
public:
|
public:
|
||||||
static inline bool FromJS(Napi::Env env, Napi::Value value, std::vector<T>& out) {
|
static inline Result FromJS(Napi::Env env, Napi::Value value, std::vector<T>& out) {
|
||||||
if (!value.IsArray()) {
|
if (!value.IsArray()) {
|
||||||
return false;
|
return Error("value is not an array");
|
||||||
}
|
}
|
||||||
auto arr = value.As<Napi::Array>();
|
auto arr = value.As<Napi::Array>();
|
||||||
std::vector<T> vec(arr.Length());
|
std::vector<T> vec(arr.Length());
|
||||||
for (size_t i = 0; i < vec.size(); i++) {
|
for (size_t i = 0; i < vec.size(); i++) {
|
||||||
if (!Converter<T>::FromJS(env, arr[static_cast<uint32_t>(i)], vec[i])) {
|
auto res = Converter<T>::FromJS(env, arr[i], vec[i]);
|
||||||
return false;
|
if (!res) {
|
||||||
|
return res.Append("for array element ", i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out = std::move(vec);
|
out = std::move(vec);
|
||||||
return true;
|
return Success;
|
||||||
}
|
}
|
||||||
static inline Napi::Value ToJS(Napi::Env env, const std::vector<T>& vec) {
|
static inline Napi::Value ToJS(Napi::Env env, const std::vector<T>& vec) {
|
||||||
auto arr = Napi::Array::New(env, vec.size());
|
auto arr = Napi::Array::New(env, vec.size());
|
||||||
|
@ -443,9 +482,11 @@ namespace wgpu { namespace interop {
|
||||||
template <typename K, typename V>
|
template <typename K, typename V>
|
||||||
class Converter<std::unordered_map<K, V>> {
|
class Converter<std::unordered_map<K, V>> {
|
||||||
public:
|
public:
|
||||||
static inline bool FromJS(Napi::Env env, Napi::Value value, std::unordered_map<K, V>& out) {
|
static inline Result FromJS(Napi::Env env,
|
||||||
|
Napi::Value value,
|
||||||
|
std::unordered_map<K, V>& out) {
|
||||||
if (!value.IsObject()) {
|
if (!value.IsObject()) {
|
||||||
return false;
|
return Error("value is not an object");
|
||||||
}
|
}
|
||||||
auto obj = value.ToObject();
|
auto obj = value.ToObject();
|
||||||
auto keys = obj.GetPropertyNames();
|
auto keys = obj.GetPropertyNames();
|
||||||
|
@ -453,14 +494,18 @@ namespace wgpu { namespace interop {
|
||||||
for (uint32_t i = 0; i < static_cast<uint32_t>(map.size()); i++) {
|
for (uint32_t i = 0; i < static_cast<uint32_t>(map.size()); i++) {
|
||||||
K key{};
|
K key{};
|
||||||
V value{};
|
V value{};
|
||||||
if (!Converter<K>::FromJS(env, keys[i], key) ||
|
auto key_res = Converter<K>::FromJS(env, keys[i], key);
|
||||||
!Converter<V>::FromJS(env, obj.Get(keys[i]), value)) {
|
if (!key_res) {
|
||||||
return false;
|
return key_res.Append("for object key");
|
||||||
|
}
|
||||||
|
auto value_res = Converter<V>::FromJS(env, obj.Get(keys[i]), value);
|
||||||
|
if (!value_res) {
|
||||||
|
return value_res.Append("for object value of key: ", key);
|
||||||
}
|
}
|
||||||
map[key] = value;
|
map[key] = value;
|
||||||
}
|
}
|
||||||
out = std::move(map);
|
out = std::move(map);
|
||||||
return true;
|
return Success;
|
||||||
}
|
}
|
||||||
static inline Napi::Value ToJS(Napi::Env env, std::unordered_map<K, V> value) {
|
static inline Napi::Value ToJS(Napi::Env env, std::unordered_map<K, V> value) {
|
||||||
auto obj = Napi::Object::New(env);
|
auto obj = Napi::Object::New(env);
|
||||||
|
@ -474,29 +519,30 @@ namespace wgpu { namespace interop {
|
||||||
template <typename... TYPES>
|
template <typename... TYPES>
|
||||||
class Converter<std::variant<TYPES...>> {
|
class Converter<std::variant<TYPES...>> {
|
||||||
template <typename TY>
|
template <typename TY>
|
||||||
static inline bool TryFromJS(Napi::Env env,
|
static inline Result TryFromJS(Napi::Env env,
|
||||||
Napi::Value value,
|
Napi::Value value,
|
||||||
std::variant<TYPES...>& out) {
|
std::variant<TYPES...>& out) {
|
||||||
TY v{};
|
TY v{};
|
||||||
if (Converter<TY>::FromJS(env, value, v)) {
|
auto res = Converter<TY>::FromJS(env, value, v);
|
||||||
out = std::move(v);
|
if (!res) {
|
||||||
return true;
|
return Error("no possible types matched");
|
||||||
}
|
}
|
||||||
return false;
|
out = std::move(v);
|
||||||
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T0, typename T1, typename... TN>
|
template <typename T0, typename T1, typename... TN>
|
||||||
static inline bool TryFromJS(Napi::Env env,
|
static inline Result TryFromJS(Napi::Env env,
|
||||||
Napi::Value value,
|
Napi::Value value,
|
||||||
std::variant<TYPES...>& out) {
|
std::variant<TYPES...>& out) {
|
||||||
if (TryFromJS<T0>(env, value, out)) {
|
if (TryFromJS<T0>(env, value, out)) {
|
||||||
return true;
|
return Success;
|
||||||
}
|
}
|
||||||
return TryFromJS<T1, TN...>(env, value, out);
|
return TryFromJS<T1, TN...>(env, value, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static inline bool FromJS(Napi::Env env, Napi::Value value, std::variant<TYPES...>& out) {
|
static inline Result FromJS(Napi::Env env, Napi::Value value, std::variant<TYPES...>& out) {
|
||||||
return TryFromJS<TYPES...>(env, value, out);
|
return TryFromJS<TYPES...>(env, value, out);
|
||||||
}
|
}
|
||||||
static inline Napi::Value ToJS(Napi::Env env, std::variant<TYPES...> value) {
|
static inline Napi::Value ToJS(Napi::Env env, std::variant<TYPES...> value) {
|
||||||
|
@ -512,7 +558,7 @@ namespace wgpu { namespace interop {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class Converter<Promise<T>> {
|
class Converter<Promise<T>> {
|
||||||
public:
|
public:
|
||||||
static inline bool FromJS(Napi::Env, Napi::Value, Promise<T>&) {
|
static inline Result FromJS(Napi::Env, Napi::Value, Promise<T>&) {
|
||||||
UNIMPLEMENTED();
|
UNIMPLEMENTED();
|
||||||
}
|
}
|
||||||
static inline Napi::Value ToJS(Napi::Env, Promise<T> promise) {
|
static inline Napi::Value ToJS(Napi::Env, Promise<T> promise) {
|
||||||
|
@ -527,18 +573,16 @@ namespace wgpu { namespace interop {
|
||||||
// FromJS() is a helper function which delegates to
|
// FromJS() is a helper function which delegates to
|
||||||
// Converter<T>::FromJS()
|
// Converter<T>::FromJS()
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bool FromJS(Napi::Env env, Napi::Value value, T& out) {
|
inline Result FromJS(Napi::Env env, Napi::Value value, T& out) {
|
||||||
return Converter<T>::FromJS(env, value, out);
|
return Converter<T>::FromJS(env, value, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromJSOptional() is similar to FromJS(), but if 'value' is either null
|
// FromJSOptional() is similar to FromJS(), but if 'value' is either null
|
||||||
// or undefined then FromJSOptional() returns true and 'out' is left
|
// or undefined then 'out' is left unassigned.
|
||||||
// unassigned.
|
|
||||||
// Returns true on success, false on failure.
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bool FromJSOptional(Napi::Env env, Napi::Value value, T& out) {
|
inline Result FromJSOptional(Napi::Env env, Napi::Value value, T& out) {
|
||||||
if (value.IsNull() || value.IsUndefined()) {
|
if (value.IsNull() || value.IsUndefined()) {
|
||||||
return true;
|
return Success;
|
||||||
}
|
}
|
||||||
return Converter<T>::FromJS(env, value, out);
|
return Converter<T>::FromJS(env, value, out);
|
||||||
}
|
}
|
||||||
|
@ -580,9 +624,8 @@ namespace wgpu { namespace interop {
|
||||||
// PARAM_TYPES is a std::tuple<> describing the C++ function parameter types.
|
// PARAM_TYPES is a std::tuple<> describing the C++ function parameter types.
|
||||||
// Parameters may be of the templated DefaultedParameter type, in which case
|
// Parameters may be of the templated DefaultedParameter type, in which case
|
||||||
// the parameter will default to the default-value if omitted.
|
// the parameter will default to the default-value if omitted.
|
||||||
// Returns true on success, false on failure.
|
|
||||||
template <typename PARAM_TYPES, int BASE_INDEX = 0>
|
template <typename PARAM_TYPES, int BASE_INDEX = 0>
|
||||||
inline bool FromJS(const Napi::CallbackInfo& info, PARAM_TYPES& args) {
|
inline Result FromJS(const Napi::CallbackInfo& info, PARAM_TYPES& args) {
|
||||||
if constexpr (BASE_INDEX < std::tuple_size_v<PARAM_TYPES>) {
|
if constexpr (BASE_INDEX < std::tuple_size_v<PARAM_TYPES>) {
|
||||||
using T = std::tuple_element_t<BASE_INDEX, PARAM_TYPES>;
|
using T = std::tuple_element_t<BASE_INDEX, PARAM_TYPES>;
|
||||||
auto& value = info[BASE_INDEX];
|
auto& value = info[BASE_INDEX];
|
||||||
|
@ -593,20 +636,24 @@ namespace wgpu { namespace interop {
|
||||||
if (value.IsNull() || value.IsUndefined()) {
|
if (value.IsNull() || value.IsUndefined()) {
|
||||||
// Use default value for this parameter
|
// Use default value for this parameter
|
||||||
out.value = out.default_value;
|
out.value = out.default_value;
|
||||||
} else if (!FromJS(info.Env(), value, out.value)) {
|
} else {
|
||||||
// Argument was provided, but failed to convert.
|
// Argument was provided
|
||||||
return false;
|
auto res = FromJS(info.Env(), value, out.value);
|
||||||
|
if (!res) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Parameter does not have a default value.
|
// Parameter does not have a default value.
|
||||||
if (!FromJS(info.Env(), value, out)) {
|
auto res = FromJS(info.Env(), value, out);
|
||||||
return false;
|
if (!res) {
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Convert the rest of the arguments
|
// Convert the rest of the arguments
|
||||||
return FromJS<PARAM_TYPES, BASE_INDEX + 1>(info, args);
|
return FromJS<PARAM_TYPES, BASE_INDEX + 1>(info, args);
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return Success;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -164,10 +164,11 @@ Wrappers* Wrappers::instance = nullptr;
|
||||||
{{ if $s := SetlikeOf $}}
|
{{ if $s := SetlikeOf $}}
|
||||||
Napi::Value has(const Napi::CallbackInfo& info) {
|
Napi::Value has(const Napi::CallbackInfo& info) {
|
||||||
std::tuple<{{template "Type" $s.Elem}}> args;
|
std::tuple<{{template "Type" $s.Elem}}> args;
|
||||||
if (FromJS(info, args)) {
|
auto res = FromJS(info, args);
|
||||||
|
if (res) {
|
||||||
return ToJS(info.Env(), impl->has(info.Env(), std::get<0>(args)));
|
return ToJS(info.Env(), impl->has(info.Env(), std::get<0>(args)));
|
||||||
}
|
}
|
||||||
Napi::Error::New(info.Env(), "invalid arguments to has()").ThrowAsJavaScriptException();
|
Napi::Error::New(info.Env(), res.error).ThrowAsJavaScriptException();
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
Napi::Value keys(const Napi::CallbackInfo& info) {
|
Napi::Value keys(const Napi::CallbackInfo& info) {
|
||||||
|
@ -176,8 +177,10 @@ Wrappers* Wrappers::instance = nullptr;
|
||||||
{{- end}}
|
{{- end}}
|
||||||
{{- range $m := MethodsOf $}}
|
{{- range $m := MethodsOf $}}
|
||||||
Napi::Value {{$m.Name}}(const Napi::CallbackInfo& info) {
|
Napi::Value {{$m.Name}}(const Napi::CallbackInfo& info) {
|
||||||
|
std::string error;
|
||||||
{{- range $overload_idx, $o := $m.Overloads}}
|
{{- range $overload_idx, $o := $m.Overloads}}
|
||||||
{ // Overload {{$overload_idx}}
|
{{- $overloaded := gt (len $m.Overloads) 1}}
|
||||||
|
{ {{if $overloaded}}// Overload {{$overload_idx}}{{end}}
|
||||||
std::tuple<
|
std::tuple<
|
||||||
{{- range $i, $p := $o.Parameters}}
|
{{- range $i, $p := $o.Parameters}}
|
||||||
{{- if $i}}, {{end}}
|
{{- if $i}}, {{end}}
|
||||||
|
@ -193,7 +196,8 @@ Wrappers* Wrappers::instance = nullptr;
|
||||||
{{- end}}
|
{{- end}}
|
||||||
{{- end}}
|
{{- end}}
|
||||||
|
|
||||||
if (FromJS(info, args)) {
|
auto res = FromJS(info, args);
|
||||||
|
if (res) {
|
||||||
{{/* indent */}}INTEROP_LOG(
|
{{/* indent */}}INTEROP_LOG(
|
||||||
{{- range $i, $p := $o.Parameters}}
|
{{- range $i, $p := $o.Parameters}}
|
||||||
{{- if $i}}, ", {{$p.Name}}: "{{else}}"{{$p.Name}}: "{{end}}, std::get<{{$i}}>(args)
|
{{- if $i}}, ", {{$p.Name}}: "{{else}}"{{$p.Name}}: "{{end}}, std::get<{{$i}}>(args)
|
||||||
|
@ -206,9 +210,10 @@ Wrappers* Wrappers::instance = nullptr;
|
||||||
{{- else }}return ToJS(info.Env(), result);
|
{{- else }}return ToJS(info.Env(), result);
|
||||||
{{- end }}
|
{{- end }}
|
||||||
}
|
}
|
||||||
|
error = {{if $overloaded}}"\noverload {{$overload_idx}} failed to match:\n" + {{end}}res.error;
|
||||||
}
|
}
|
||||||
{{- end}}
|
{{- end}}
|
||||||
Napi::Error::New(info.Env(), "invalid arguments to {{$m.Name}}").ThrowAsJavaScriptException();
|
Napi::Error::New(info.Env(), "no overload matched for {{$m.Name}}:\n" + error).ThrowAsJavaScriptException();
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
{{- end}}
|
{{- end}}
|
||||||
|
@ -220,10 +225,12 @@ Wrappers* Wrappers::instance = nullptr;
|
||||||
{{- if not $a.Readonly}}
|
{{- if not $a.Readonly}}
|
||||||
void set{{Title $a.Name}}(const Napi::CallbackInfo& info, const Napi::Value& value) {
|
void set{{Title $a.Name}}(const Napi::CallbackInfo& info, const Napi::Value& value) {
|
||||||
{{template "Type" $a.Type}} v{};
|
{{template "Type" $a.Type}} v{};
|
||||||
if (FromJS(info.Env(), value, v)) {
|
auto res = FromJS(info.Env(), value, v);
|
||||||
|
if (res) {
|
||||||
impl->set{{Title $a.Name}}(info.Env(), std::move(v));
|
impl->set{{Title $a.Name}}(info.Env(), std::move(v));
|
||||||
} else {
|
} else {
|
||||||
Napi::Error::New(info.Env(), "invalid value to {{$a.Name}}").ThrowAsJavaScriptException();
|
res = res.Append("invalid value to {{$a.Name}}");
|
||||||
|
Napi::Error::New(info.Env(), res.error).ThrowAsJavaScriptException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
@ -239,9 +246,11 @@ Wrappers* Wrappers::instance = nullptr;
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
*/ -}}
|
*/ -}}
|
||||||
{{- define "Dictionary"}}
|
{{- define "Dictionary"}}
|
||||||
bool Converter<{{$.Name}}>::FromJS(Napi::Env env, Napi::Value value, {{$.Name}}& out) {
|
Result Converter<{{$.Name}}>::FromJS(Napi::Env env, Napi::Value value, {{$.Name}}& out) {
|
||||||
auto object = value.ToObject();
|
auto object = value.ToObject();
|
||||||
return true{{template "DictionaryMembersFromJS" $}};
|
Result res;
|
||||||
|
{{- template "DictionaryMembersFromJS" $}};
|
||||||
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
Napi::Value Converter<{{$.Name}}>::ToJS(Napi::Env env, {{$.Name}} value) {
|
Napi::Value Converter<{{$.Name}}>::ToJS(Napi::Env env, {{$.Name}} value) {
|
||||||
|
@ -265,18 +274,21 @@ std::ostream& operator<<(std::ostream& o, const {{$.Name}}& dict) {
|
||||||
{{- /*
|
{{- /*
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- DictionaryMembersFromJS emits the C++ logic to convert each of the
|
-- DictionaryMembersFromJS emits the C++ logic to convert each of the
|
||||||
-- dictionary ast.Member fields from JavaScript to C++. Each call to FromJS() is
|
-- dictionary ast.Member fields from JavaScript to C++. Each call to ToJS() is
|
||||||
-- prefixed with '&&' so that the combined expression is true iff all members
|
-- emitted as a separate statement, and requires a 'Result res' local to be
|
||||||
-- are converted succesfully
|
-- declared
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
*/ -}}
|
*/ -}}
|
||||||
{{- define "DictionaryMembersFromJS"}}
|
{{- define "DictionaryMembersFromJS"}}
|
||||||
{{- if $.Inherits}}{{template "DictionaryMembersFromJS" (Lookup $.Inherits)}}{{end}}
|
{{- if $.Inherits}}{{template "DictionaryMembersFromJS" (Lookup $.Inherits)}}{{end}}
|
||||||
{{- range $i, $m := $.Members}} &&
|
{{- range $i, $m := $.Members}}
|
||||||
{{/* indent */}}
|
{{/* indent */}}
|
||||||
{{- if $m.Init }}interop::FromJSOptional(env, object.Get("{{$m.Name}}"), out.{{$m.Name}})
|
{{- if $m.Init }}res = interop::FromJSOptional(env, object.Get("{{$m.Name}}"), out.{{$m.Name}});
|
||||||
{{- else }}interop::FromJS(env, object.Get("{{$m.Name}}"), out.{{$m.Name}})
|
{{- else }}res = interop::FromJS(env, object.Get("{{$m.Name}}"), out.{{$m.Name}});
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
if (!res) {
|
||||||
|
return res.Append("while converting member '{{$.Name}}'");
|
||||||
|
}
|
||||||
{{- end}}
|
{{- end}}
|
||||||
{{- end}}
|
{{- end}}
|
||||||
|
|
||||||
|
@ -353,8 +365,12 @@ const char* Converter<{{$.Name}}>::ToString({{$.Name}} value) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Converter<{{$.Name}}>::FromJS(Napi::Env env, Napi::Value value, {{$.Name}}& out) {
|
Result Converter<{{$.Name}}>::FromJS(Napi::Env env, Napi::Value value, {{$.Name}}& out) {
|
||||||
return FromString(value.ToString(), out);
|
std::string str = value.ToString();
|
||||||
|
if (FromString(str, out)) {
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
return Error(str + " is not a valid enum value of {{$.Name}}");
|
||||||
}
|
}
|
||||||
|
|
||||||
Napi::Value Converter<{{$.Name}}>::ToJS(Napi::Env env, {{$.Name}} value) {
|
Napi::Value Converter<{{$.Name}}>::ToJS(Napi::Env env, {{$.Name}} value) {
|
||||||
|
|
|
@ -76,7 +76,7 @@ public:
|
||||||
template<>
|
template<>
|
||||||
class Converter<{{$.Name}}> {
|
class Converter<{{$.Name}}> {
|
||||||
public:
|
public:
|
||||||
static bool FromJS(Napi::Env, Napi::Value, {{$.Name}}&);
|
static Result FromJS(Napi::Env, Napi::Value, {{$.Name}}&);
|
||||||
static Napi::Value ToJS(Napi::Env, {{$.Name}});
|
static Napi::Value ToJS(Napi::Env, {{$.Name}});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -166,7 +166,7 @@ enum class {{$.Name}} {
|
||||||
template<>
|
template<>
|
||||||
class Converter<{{$.Name}}> {
|
class Converter<{{$.Name}}> {
|
||||||
public:
|
public:
|
||||||
static bool FromJS(Napi::Env, Napi::Value, {{$.Name}}&);
|
static Result FromJS(Napi::Env, Napi::Value, {{$.Name}}&);
|
||||||
static Napi::Value ToJS(Napi::Env, {{$.Name}});
|
static Napi::Value ToJS(Napi::Env, {{$.Name}});
|
||||||
static bool FromString(std::string, {{$.Name}}&);
|
static bool FromString(std::string, {{$.Name}}&);
|
||||||
static const char* ToString({{$.Name}});
|
static const char* ToString({{$.Name}});
|
||||||
|
|
Loading…
Reference in New Issue