#pragma once #include #include "handle_cast.h" namespace ivm { namespace detail { struct ParamRequired : std::exception {}; template inline auto ReadOptionImpl(v8::MaybeLocal maybe_options, Property&& property, Default default_fn) { HandleCastArguments arguments; auto property_handle = HandleCast>(std::forward(property), arguments); try { v8::Local options; if (maybe_options.ToLocal(&options)) { v8::Local value = Unmaybe(options->Get(arguments.context, property_handle)); if (value->IsNullOrUndefined()) { return default_fn(); } return HandleCast(value, arguments); } else { return default_fn(); } } catch (const ParamIncorrect& ex) { throw RuntimeTypeError{ std::string{"`"}+ *v8::String::Utf8Value{arguments.isolate, property_handle}+ "` must be "+ ex.type }; } catch (const ParamRequired&) { throw RuntimeTypeError( std::string{"`"}+ *v8::String::Utf8Value{arguments.isolate, property_handle}+ "` is required"); } } } // namespace detail template auto ReadOption(Options options, Property&& property) { return detail::ReadOptionImpl(options, std::forward(property), []() { throw detail::ParamRequired(); }); } template auto ReadOption(Options options, Property&& property, Type default_value) { return detail::ReadOptionImpl(options, std::forward(property), [&]() { return std::move(default_value); }); } }