QXmpp  Version: 1.5.2
QXmppError.h
1 // SPDX-FileCopyrightText: 2022 Linus Jahn <lnj@kaidan.im>
2 //
3 // SPDX-License-Identifier: LGPL-2.1-or-later
4 
5 #ifndef QXMPPERROR_H
6 #define QXMPPERROR_H
7 
8 #include "QXmppGlobal.h"
9 
10 #include <any>
11 #include <optional>
12 
13 class QFileDevice;
14 class QIODevice;
15 class QNetworkReply;
16 
17 struct QXMPP_EXPORT QXmppError
18 {
19  QString description;
20  std::any error;
21 
22  static QXmppError fromIoDevice(const QIODevice &device);
23  static QXmppError fromNetworkReply(const QNetworkReply &reply);
24  static QXmppError fromFileDevice(const QFileDevice &file);
25 
26  bool isFileError() const;
27  bool isNetworkError() const;
28  bool isStanzaError() const;
29 
30  template<typename T>
31  bool holdsType() const
32  {
33  return error.type().hash_code() == typeid(T).hash_code();
34  }
35  template<typename T>
36  std::optional<T> value() const
37  {
38  // any_cast always checks this, to avoid an additional check we use exceptions
39  try {
40  return std::any_cast<T>(error);
41  } catch (std::bad_any_cast) {
42  return {};
43  }
44  }
45  template<typename T>
46  std::optional<T> takeValue()
47  {
48  // we can't use unchecked any_cast with moving because we can't access the error after a
49  // failed any_cast
50  if (error.type().hash_code() == typeid(T).hash_code()) {
51  auto value = std::any_cast<T>(std::move(error));
52  error = std::any();
53  return value;
54  }
55  return {};
56  }
57 };
58 
59 #endif // QXMPPERROR_H
Definition: QXmppError.h:18
std::any error
Definition: QXmppError.h:20
QString description
Definition: QXmppError.h:19
std::optional< T > takeValue()
Definition: QXmppError.h:46
std::optional< T > value() const
Definition: QXmppError.h:36
bool holdsType() const
Definition: QXmppError.h:31