/* * Copyright (c) 2021, Linus Groh * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include namespace Web::DOM { #define ENUMERATE_SIMPLE_WEBIDL_EXCEPTION_TYPES(E) \ E(EvalError) \ E(RangeError) \ E(ReferenceError) \ E(TypeError) \ E(URIError) #define E(x) x, enum class SimpleExceptionType { ENUMERATE_SIMPLE_WEBIDL_EXCEPTION_TYPES(E) }; #undef E struct SimpleException { SimpleExceptionType type; String message; }; template class ExceptionOr { public: ExceptionOr() requires(IsSame) = default; ExceptionOr(const ValueType& result) : m_result(result) { } ExceptionOr(ValueType&& result) : m_result(move(result)) { } ExceptionOr(NonnullRefPtr exception) : m_exception(move(exception)) { } ExceptionOr(SimpleException exception) : m_exception(move(exception)) { } ExceptionOr(Variant> exception) : m_exception(move(exception).template downcast>()) { } ExceptionOr(ExceptionOr&& other) = default; ExceptionOr(const ExceptionOr& other) = default; ~ExceptionOr() = default; ValueType& value() requires(!IsSame) { return m_result.value(); } ValueType release_value() requires(!IsSame) { return m_result.release_value(); } Variant> exception() const { return m_exception.template downcast>(); } auto materialized_exception(JS::GlobalObject& global_object) const { #define E(x) JS::x*, using ResultType = Variant>; #undef E return m_exception.visit( [&](SimpleException& exception) -> ResultType { switch (exception.type) { #define E(x) \ case SimpleExceptionType::x: \ return JS::x::create(global_object, exception.message); ENUMERATE_SIMPLE_WEBIDL_EXCEPTION_TYPES(E) #undef E default: VERIFY_NOT_REACHED(); } }, [&](NonnullRefPtr const& exception) -> ResultType { return exception; }, [](Empty) -> ResultType { VERIFY_NOT_REACHED(); }); } bool is_exception() const { return !m_exception.template has(); } private: Optional m_result; // https://heycam.github.io/webidl/#idl-exceptions Variant> m_exception {}; }; template<> class ExceptionOr : public ExceptionOr { public: using ExceptionOr::ExceptionOr; }; }