tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ResultExtensions.h (5012B)


      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 "mozilla/Result.h"
     11 #include "mozilla/ResultExtensions.h"
     12 #include "mozilla/dom/QMResult.h"
     13 #include "mozilla/dom/quota/Config.h"
     14 #include "mozilla/dom/quota/RemoveParen.h"
     15 #include "nsError.h"
     16 
     17 #ifdef QM_ERROR_STACKS_ENABLED
     18 #  include "mozilla/ResultVariant.h"
     19 #endif
     20 
     21 namespace mozilla {
     22 
     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.
     25 template <>
     26 class [[nodiscard]] GenericErrorResult<bool> {
     27  bool mErrorValue;
     28 
     29  template <typename V, typename E2>
     30  friend class Result;
     31 
     32 public:
     33  explicit GenericErrorResult(bool aErrorValue) : mErrorValue(aErrorValue) {
     34    MOZ_ASSERT(!aErrorValue);
     35  }
     36 
     37  GenericErrorResult(bool aErrorValue, const ErrorPropagationTag&)
     38      : GenericErrorResult(aErrorValue) {}
     39 
     40  MOZ_IMPLICIT operator bool() const { return mErrorValue; }
     41 };
     42 
     43 // Allow MOZ_TRY/QM_TRY to handle `bool` values.
     44 template <typename E = nsresult>
     45 inline Result<Ok, E> ToResult(bool aValue) {
     46  if (aValue) {
     47    return Ok();
     48  }
     49  return Err(ResultTypeTraits<E>::From(NS_ERROR_FAILURE));
     50 }
     51 
     52 constexpr nsresult ToNSResult(nsresult aError) { return aError; }
     53 
     54 #ifdef QM_ERROR_STACKS_ENABLED
     55 
     56 inline nsresult ToNSResult(const QMResult& aError) { return aError.NSResult(); }
     57 
     58 // Allow QMResult errors to use existing stack id and to increase the frame id
     59 // during error propagation.
     60 template <>
     61 class [[nodiscard]] GenericErrorResult<QMResult> {
     62  QMResult mErrorValue;
     63 
     64  template <typename V, typename E2>
     65  friend class Result;
     66 
     67 public:
     68  explicit GenericErrorResult(const QMResult& aErrorValue)
     69      : mErrorValue(aErrorValue) {
     70    MOZ_ASSERT(NS_FAILED(aErrorValue.NSResult()));
     71  }
     72 
     73  explicit GenericErrorResult(QMResult&& aErrorValue)
     74      : mErrorValue(std::move(aErrorValue)) {
     75    MOZ_ASSERT(NS_FAILED(aErrorValue.NSResult()));
     76  }
     77 
     78  explicit GenericErrorResult(const QMResult& aErrorValue,
     79                              const ErrorPropagationTag&)
     80      : GenericErrorResult(aErrorValue.Propagate()) {}
     81 
     82  explicit GenericErrorResult(QMResult&& aErrorValue,
     83                              const ErrorPropagationTag&)
     84      : GenericErrorResult(aErrorValue.Propagate()) {}
     85 
     86  operator QMResult() const { return mErrorValue; }
     87 
     88  operator nsresult() const { return mErrorValue.NSResult(); }
     89 };
     90 
     91 template <>
     92 struct ResultTypeTraits<QMResult> {
     93  static QMResult From(nsresult aValue) { return ToQMResult(aValue); }
     94 
     95  static QMResult From(const QMResult& aValue) { return aValue; }
     96 
     97  static QMResult From(QMResult&& aValue) { return std::move(aValue); }
     98 };
     99 
    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));
    104  }
    105  return Ok();
    106 }
    107 
    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));
    112  }
    113  return Ok();
    114 }
    115 #endif
    116 
    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); });
    121 }
    122 
    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) {
    126  nsresult rv;
    127  R res = aFunc(std::forward<Args>(aArgs)..., &rv);
    128  if (NS_FAILED(rv)) {
    129    return Err(rv);
    130  }
    131  return res;
    132 }
    133 
    134 }  // namespace mozilla
    135 
    136 // TODO: Maybe move this to mfbt/ResultExtensions.h
    137 #define MOZ_TO_RESULT(expr) ToResult(expr)
    138 
    139 #define QM_TO_RESULT(expr) ToResult<QMResult>(expr)
    140 
    141 #define QM_TO_RESULT_TRANSFORM(value) ToResultTransform<QMResult>(value)
    142 
    143 #define MOZ_TO_RESULT_GET_TYPED(resultType, ...) \
    144  ::mozilla::ToResultGet<MOZ_REMOVE_PAREN(resultType)>(__VA_ARGS__)
    145 
    146 #define MOZ_TO_RESULT_INVOKE_TYPED(resultType, ...) \
    147  ::mozilla::ToResultInvoke<MOZ_REMOVE_PAREN(resultType)>(__VA_ARGS__)
    148 
    149 #define QM_TO_RESULT_INVOKE_MEMBER(obj, methodname, ...)                 \
    150  ::mozilla::ToResultInvokeMember<QMResult>(                             \
    151      (obj), &::mozilla::detail::DerefedType<decltype(obj)>::methodname, \
    152      ##__VA_ARGS__)
    153 
    154 #define QM_TO_RESULT_INVOKE_MEMBER_TYPED(resultType, obj, methodname, ...) \
    155  (::mozilla::ToResultInvoke<resultType, QMResult>(                        \
    156      ::std::mem_fn(                                                       \
    157          &::mozilla::detail::DerefedType<decltype(obj)>::methodname),     \
    158      (obj), ##__VA_ARGS__))
    159 
    160 #endif