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/. */ 6 7 #ifndef DOM_QUOTA_QMRESULTINLINES_H_ 8 #define DOM_QUOTA_QMRESULTINLINES_H_ 9 10 #include "nsError.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" 16 17 #ifdef QM_ERROR_STACKS_ENABLED 18 # include "mozilla/ResultVariant.h" 19 #endif 20 21 namespace mozilla { 22 23 #ifdef QM_ERROR_STACKS_ENABLED 24 // Allow QMResult errors to use existing stack id and to increase the frame id 25 // during error propagation. 26 template <> 27 class [[nodiscard]] GenericErrorResult<QMResult> { 28 QMResult mErrorValue; 29 30 template <typename V, typename E2> 31 friend class Result; 32 33 public: GenericErrorResult(const QMResult & aErrorValue)34 explicit GenericErrorResult(const QMResult& aErrorValue) 35 : mErrorValue(aErrorValue) { 36 MOZ_ASSERT(NS_FAILED(aErrorValue.NSResult())); 37 } 38 GenericErrorResult(QMResult && aErrorValue)39 explicit GenericErrorResult(QMResult&& aErrorValue) 40 : mErrorValue(std::move(aErrorValue)) { 41 MOZ_ASSERT(NS_FAILED(aErrorValue.NSResult())); 42 } 43 GenericErrorResult(const QMResult & aErrorValue,const ErrorPropagationTag &)44 explicit GenericErrorResult(const QMResult& aErrorValue, 45 const ErrorPropagationTag&) 46 : GenericErrorResult(aErrorValue.Propagate()) {} 47 GenericErrorResult(QMResult && aErrorValue,const ErrorPropagationTag &)48 explicit GenericErrorResult(QMResult&& aErrorValue, 49 const ErrorPropagationTag&) 50 : GenericErrorResult(aErrorValue.Propagate()) {} 51 QMResult()52 operator QMResult() const { return mErrorValue; } 53 nsresult()54 operator nsresult() const { return mErrorValue.NSResult(); } 55 }; 56 57 template <> 58 struct ResultTypeTraits<QMResult> { 59 static QMResult From(nsresult aValue) { return ToQMResult(aValue); } 60 61 static QMResult From(const QMResult& aValue) { return aValue; } 62 63 static QMResult From(QMResult&& aValue) { return std::move(aValue); } 64 }; 65 66 template <typename E> 67 inline Result<Ok, E> ToResult(const QMResult& aValue) { 68 if (NS_FAILED(aValue.NSResult())) { 69 return Err(ResultTypeTraits<E>::From(aValue)); 70 } 71 return Ok(); 72 } 73 74 template <typename E> 75 inline Result<Ok, E> ToResult(QMResult&& aValue) { 76 if (NS_FAILED(aValue.NSResult())) { 77 return Err(ResultTypeTraits<E>::From(aValue)); 78 } 79 return Ok(); 80 } 81 #endif 82 83 template <typename E = nsresult, typename V, typename E2> 84 inline Result<V, E> ToResultTransform(Result<V, E2>&& aValue) { 85 return std::forward<Result<V, E2>>(aValue).mapErr( 86 [](auto&& err) { return ResultTypeTraits<E>::From(err); }); 87 } 88 89 // TODO: Maybe move this to mfbt/ResultExtensions.h 90 template <typename R, typename Func, typename... Args> 91 Result<R, nsresult> ToResultGet(const Func& aFunc, Args&&... aArgs) { 92 nsresult rv; 93 R res = aFunc(std::forward<Args>(aArgs)..., &rv); 94 if (NS_FAILED(rv)) { 95 return Err(rv); 96 } 97 return res; 98 } 99 100 } // namespace mozilla 101 102 // TODO: Maybe move this to mfbt/ResultExtensions.h 103 #define MOZ_TO_RESULT(expr) ToResult(expr) 104 105 #define QM_TO_RESULT(expr) ToResult<QMResult>(expr) 106 107 #define QM_TO_RESULT_TRANSFORM(value) ToResultTransform<QMResult>(value) 108 109 #define MOZ_TO_RESULT_GET_TYPED(resultType, ...) \ 110 ::mozilla::ToResultGet<MOZ_REMOVE_PAREN(resultType)>(__VA_ARGS__) 111 112 #define MOZ_TO_RESULT_INVOKE_TYPED(resultType, ...) \ 113 ::mozilla::ToResultInvoke<MOZ_REMOVE_PAREN(resultType)>(__VA_ARGS__) 114 115 #define QM_TO_RESULT_INVOKE_MEMBER(obj, methodname, ...) \ 116 ::mozilla::ToResultInvokeMember<QMResult>( \ 117 (obj), &::mozilla::detail::DerefedType<decltype(obj)>::methodname, \ 118 ##__VA_ARGS__) 119 120 #define QM_TO_RESULT_INVOKE_MEMBER_TYPED(resultType, obj, methodname, ...) \ 121 (::mozilla::ToResultInvoke<resultType, QMResult>( \ 122 ::std::mem_fn( \ 123 &::mozilla::detail::DerefedType<decltype(obj)>::methodname), \ 124 (obj), ##__VA_ARGS__)) 125 126 #endif 127