1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef DOM_QUOTA_QMRESULTINLINES_H_
8 #define DOM_QUOTA_QMRESULTINLINES_H_
11 #include "mozilla/Result.h"
12 #include "mozilla/ResultExtensions.h"
13 #include "mozilla/dom/QMResult.h"
14 #include "mozilla/dom/quota/Config.h"
15 #include "mozilla/dom/quota/RemoveParen.h"
17 #ifdef QM_ERROR_STACKS_ENABLED
18 # include "mozilla/ResultVariant.h"
23 // Allow bool errors to automatically convert to bool values, so MOZ_TRY/QM_TRY
24 // can be used in bool returning methods with Result<T, bool> results.
26 class [[nodiscard
]] GenericErrorResult
<bool> {
29 template <typename V
, typename E2
>
33 explicit GenericErrorResult(bool aErrorValue
) : mErrorValue(aErrorValue
) {
34 MOZ_ASSERT(!aErrorValue
);
37 GenericErrorResult(bool aErrorValue
, const ErrorPropagationTag
&)
38 : GenericErrorResult(aErrorValue
) {}
40 MOZ_IMPLICIT
operator bool() const { return mErrorValue
; }
43 // Allow MOZ_TRY/QM_TRY to handle `bool` values.
44 template <typename E
= nsresult
>
45 inline Result
<Ok
, E
> ToResult(bool aValue
) {
49 return Err(ResultTypeTraits
<E
>::From(NS_ERROR_FAILURE
));
52 constexpr nsresult
ToNSResult(nsresult aError
) { return aError
; }
54 #ifdef QM_ERROR_STACKS_ENABLED
56 inline nsresult
ToNSResult(const QMResult
& aError
) { return aError
.NSResult(); }
58 // Allow QMResult errors to use existing stack id and to increase the frame id
59 // during error propagation.
61 class [[nodiscard
]] GenericErrorResult
<QMResult
> {
64 template <typename V
, typename E2
>
68 explicit GenericErrorResult(const QMResult
& aErrorValue
)
69 : mErrorValue(aErrorValue
) {
70 MOZ_ASSERT(NS_FAILED(aErrorValue
.NSResult()));
73 explicit GenericErrorResult(QMResult
&& aErrorValue
)
74 : mErrorValue(std::move(aErrorValue
)) {
75 MOZ_ASSERT(NS_FAILED(aErrorValue
.NSResult()));
78 explicit GenericErrorResult(const QMResult
& aErrorValue
,
79 const ErrorPropagationTag
&)
80 : GenericErrorResult(aErrorValue
.Propagate()) {}
82 explicit GenericErrorResult(QMResult
&& aErrorValue
,
83 const ErrorPropagationTag
&)
84 : GenericErrorResult(aErrorValue
.Propagate()) {}
86 operator QMResult() const { return mErrorValue
; }
88 operator nsresult() const { return mErrorValue
.NSResult(); }
92 struct ResultTypeTraits
<QMResult
> {
93 static QMResult
From(nsresult aValue
) { return ToQMResult(aValue
); }
95 static QMResult
From(const QMResult
& aValue
) { return aValue
; }
97 static QMResult
From(QMResult
&& aValue
) { return std::move(aValue
); }
100 template <typename E
>
101 inline Result
<Ok
, E
> ToResult(const QMResult
& aValue
) {
102 if (NS_FAILED(aValue
.NSResult())) {
103 return Err(ResultTypeTraits
<E
>::From(aValue
));
108 template <typename E
>
109 inline Result
<Ok
, E
> ToResult(QMResult
&& aValue
) {
110 if (NS_FAILED(aValue
.NSResult())) {
111 return Err(ResultTypeTraits
<E
>::From(aValue
));
117 template <typename E
= nsresult
, typename V
, typename E2
>
118 inline Result
<V
, E
> ToResultTransform(Result
<V
, E2
>&& aValue
) {
119 return std::forward
<Result
<V
, E2
>>(aValue
).mapErr(
120 [](auto&& err
) { return ResultTypeTraits
<E
>::From(err
); });
123 // TODO: Maybe move this to mfbt/ResultExtensions.h
124 template <typename R
, typename Func
, typename
... Args
>
125 Result
<R
, nsresult
> ToResultGet(const Func
& aFunc
, Args
&&... aArgs
) {
127 R res
= aFunc(std::forward
<Args
>(aArgs
)..., &rv
);
134 } // namespace mozilla
136 // TODO: Maybe move this to mfbt/ResultExtensions.h
137 #define MOZ_TO_RESULT(expr) ToResult(expr)
139 #define QM_TO_RESULT(expr) ToResult<QMResult>(expr)
141 #define QM_TO_RESULT_TRANSFORM(value) ToResultTransform<QMResult>(value)
143 #define MOZ_TO_RESULT_GET_TYPED(resultType, ...) \
144 ::mozilla::ToResultGet<MOZ_REMOVE_PAREN(resultType)>(__VA_ARGS__)
146 #define MOZ_TO_RESULT_INVOKE_TYPED(resultType, ...) \
147 ::mozilla::ToResultInvoke<MOZ_REMOVE_PAREN(resultType)>(__VA_ARGS__)
149 #define QM_TO_RESULT_INVOKE_MEMBER(obj, methodname, ...) \
150 ::mozilla::ToResultInvokeMember<QMResult>( \
151 (obj), &::mozilla::detail::DerefedType<decltype(obj)>::methodname, \
154 #define QM_TO_RESULT_INVOKE_MEMBER_TYPED(resultType, obj, methodname, ...) \
155 (::mozilla::ToResultInvoke<resultType, QMResult>( \
157 &::mozilla::detail::DerefedType<decltype(obj)>::methodname), \
158 (obj), ##__VA_ARGS__))