diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:47:29 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:47:29 +0000 |
commit | 0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d (patch) | |
tree | a31f07c9bcca9d56ce61e9a1ffd30ef350d513aa /dom/quota/ResultExtensions.h | |
parent | Initial commit. (diff) | |
download | firefox-esr-upstream/115.8.0esr.tar.xz firefox-esr-upstream/115.8.0esr.zip |
Adding upstream version 115.8.0esr.upstream/115.8.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/quota/ResultExtensions.h')
-rw-r--r-- | dom/quota/ResultExtensions.h | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/dom/quota/ResultExtensions.h b/dom/quota/ResultExtensions.h new file mode 100644 index 0000000000..c19bf92661 --- /dev/null +++ b/dom/quota/ResultExtensions.h @@ -0,0 +1,160 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef DOM_QUOTA_QMRESULTINLINES_H_ +#define DOM_QUOTA_QMRESULTINLINES_H_ + +#include "nsError.h" +#include "mozilla/Result.h" +#include "mozilla/ResultExtensions.h" +#include "mozilla/dom/QMResult.h" +#include "mozilla/dom/quota/Config.h" +#include "mozilla/dom/quota/RemoveParen.h" + +#ifdef QM_ERROR_STACKS_ENABLED +# include "mozilla/ResultVariant.h" +#endif + +namespace mozilla { + +// Allow bool errors to automatically convert to bool values, so MOZ_TRY/QM_TRY +// can be used in bool returning methods with Result<T, bool> results. +template <> +class [[nodiscard]] GenericErrorResult<bool> { + bool mErrorValue; + + template <typename V, typename E2> + friend class Result; + + public: + explicit GenericErrorResult(bool aErrorValue) : mErrorValue(aErrorValue) { + MOZ_ASSERT(!aErrorValue); + } + + GenericErrorResult(bool aErrorValue, const ErrorPropagationTag&) + : GenericErrorResult(aErrorValue) {} + + MOZ_IMPLICIT operator bool() const { return mErrorValue; } +}; + +// Allow MOZ_TRY/QM_TRY to handle `bool` values. +template <typename E = nsresult> +inline Result<Ok, E> ToResult(bool aValue) { + if (aValue) { + return Ok(); + } + return Err(ResultTypeTraits<E>::From(NS_ERROR_FAILURE)); +} + +constexpr nsresult ToNSResult(nsresult aError) { return aError; } + +#ifdef QM_ERROR_STACKS_ENABLED + +inline nsresult ToNSResult(const QMResult& aError) { return aError.NSResult(); } + +// Allow QMResult errors to use existing stack id and to increase the frame id +// during error propagation. +template <> +class [[nodiscard]] GenericErrorResult<QMResult> { + QMResult mErrorValue; + + template <typename V, typename E2> + friend class Result; + + public: + explicit GenericErrorResult(const QMResult& aErrorValue) + : mErrorValue(aErrorValue) { + MOZ_ASSERT(NS_FAILED(aErrorValue.NSResult())); + } + + explicit GenericErrorResult(QMResult&& aErrorValue) + : mErrorValue(std::move(aErrorValue)) { + MOZ_ASSERT(NS_FAILED(aErrorValue.NSResult())); + } + + explicit GenericErrorResult(const QMResult& aErrorValue, + const ErrorPropagationTag&) + : GenericErrorResult(aErrorValue.Propagate()) {} + + explicit GenericErrorResult(QMResult&& aErrorValue, + const ErrorPropagationTag&) + : GenericErrorResult(aErrorValue.Propagate()) {} + + operator QMResult() const { return mErrorValue; } + + operator nsresult() const { return mErrorValue.NSResult(); } +}; + +template <> +struct ResultTypeTraits<QMResult> { + static QMResult From(nsresult aValue) { return ToQMResult(aValue); } + + static QMResult From(const QMResult& aValue) { return aValue; } + + static QMResult From(QMResult&& aValue) { return std::move(aValue); } +}; + +template <typename E> +inline Result<Ok, E> ToResult(const QMResult& aValue) { + if (NS_FAILED(aValue.NSResult())) { + return Err(ResultTypeTraits<E>::From(aValue)); + } + return Ok(); +} + +template <typename E> +inline Result<Ok, E> ToResult(QMResult&& aValue) { + if (NS_FAILED(aValue.NSResult())) { + return Err(ResultTypeTraits<E>::From(aValue)); + } + return Ok(); +} +#endif + +template <typename E = nsresult, typename V, typename E2> +inline Result<V, E> ToResultTransform(Result<V, E2>&& aValue) { + return std::forward<Result<V, E2>>(aValue).mapErr( + [](auto&& err) { return ResultTypeTraits<E>::From(err); }); +} + +// TODO: Maybe move this to mfbt/ResultExtensions.h +template <typename R, typename Func, typename... Args> +Result<R, nsresult> ToResultGet(const Func& aFunc, Args&&... aArgs) { + nsresult rv; + R res = aFunc(std::forward<Args>(aArgs)..., &rv); + if (NS_FAILED(rv)) { + return Err(rv); + } + return res; +} + +} // namespace mozilla + +// TODO: Maybe move this to mfbt/ResultExtensions.h +#define MOZ_TO_RESULT(expr) ToResult(expr) + +#define QM_TO_RESULT(expr) ToResult<QMResult>(expr) + +#define QM_TO_RESULT_TRANSFORM(value) ToResultTransform<QMResult>(value) + +#define MOZ_TO_RESULT_GET_TYPED(resultType, ...) \ + ::mozilla::ToResultGet<MOZ_REMOVE_PAREN(resultType)>(__VA_ARGS__) + +#define MOZ_TO_RESULT_INVOKE_TYPED(resultType, ...) \ + ::mozilla::ToResultInvoke<MOZ_REMOVE_PAREN(resultType)>(__VA_ARGS__) + +#define QM_TO_RESULT_INVOKE_MEMBER(obj, methodname, ...) \ + ::mozilla::ToResultInvokeMember<QMResult>( \ + (obj), &::mozilla::detail::DerefedType<decltype(obj)>::methodname, \ + ##__VA_ARGS__) + +#define QM_TO_RESULT_INVOKE_MEMBER_TYPED(resultType, obj, methodname, ...) \ + (::mozilla::ToResultInvoke<resultType, QMResult>( \ + ::std::mem_fn( \ + &::mozilla::detail::DerefedType<decltype(obj)>::methodname), \ + (obj), ##__VA_ARGS__)) + +#endif |