swift
containerbase.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (C) 2013 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #ifndef SWIFT_MISC_CONTAINERBASE_H
7 #define SWIFT_MISC_CONTAINERBASE_H
8 
9 #include <algorithm>
10 
11 #include <QStringList>
12 
13 #include "misc/json.h"
14 #include "misc/jsonexception.h"
15 #include "misc/mixin/mixindbus.h"
16 #include "misc/mixin/mixinjson.h"
18 #include "misc/mixin/mixinstring.h"
19 #include "misc/predicates.h"
20 #include "misc/range.h"
21 
22 namespace swift::misc
23 {
26  {
27  public:
29  template <class U>
30  static QString stringify(const U &obj, bool i18n)
31  {
32  return obj.toQString(i18n);
33  }
35  static QString stringify(int n, bool i18n) { return i18n ? QLocale().toString(n) : QString::number(n); }
37  static QString stringify(uint n, bool i18n) { return i18n ? QLocale().toString(n) : QString::number(n); }
39  static QString stringify(qlonglong n, bool i18n) { return i18n ? QLocale().toString(n) : QString::number(n); }
41  static QString stringify(qulonglong n, bool i18n) { return i18n ? QLocale().toString(n) : QString::number(n); }
43  static QString stringify(double n, bool i18n) { return i18n ? QLocale().toString(n) : QString::number(n); }
45  static QString stringify(QString str, bool /*i18n*/) { return str; }
47  template <class A, class B>
48  static QString stringify(const std::pair<A, B> &pair, bool i18n)
49  {
50  return stringify(pair.first, i18n) + ":" + stringify(pair.second, i18n);
51  }
52  };
53 
58  template <class Derived>
60  public CRangeBase<Derived>,
61  public mixin::MetaType<Derived>,
62  public mixin::DBusOperators<Derived>,
63  public mixin::JsonOperators<Derived>,
64  public mixin::String<Derived>
65  {
66  public:
68  friend int compare(const Derived &a, const Derived &b)
69  {
70  for (auto i = a.cbegin(), j = b.cbegin(); i != a.cend() && j != b.cend(); ++i, ++j)
71  {
72  if (*i < *j) { return -1; }
73  if (*j < *i) { return 1; }
74  }
75  if (a.size() < b.size()) { return -1; }
76  if (b.size() < a.size()) { return 1; }
77  return 0;
78  }
79 
82  template <template <class> class Other>
83  auto to() const
84  {
85  return to(Other<typename Derived::value_type>());
86  }
87 
92  template <template <class> class Other, class T>
93  Other<T> to(Other<T> other) const
94  {
95  for (auto it = derived().cbegin(); it != derived().cend(); ++it) { other.push_back(*it); }
96  return other;
97  }
98 
104  template <class K0, class V0, class... KeysValues>
105  int removeIf(K0 k0, V0 v0, KeysValues... keysValues)
106  {
107  return derived().removeIf(swift::misc::predicates::MemberEqual(k0, v0, keysValues...));
108  }
109 
111  friend size_t qHash(const Derived &) { return 0; } // clazy:exclude=qhash-namespace
112 
114  QJsonObject toJson() const
115  {
116  QJsonArray array;
117  QJsonObject json;
118  for (auto it = derived().cbegin(); it != derived().cend(); ++it) { array << (*it); }
119  json.insert("containerbase", array);
120  return json;
121  }
122 
124  QString toJsonString(QJsonDocument::JsonFormat format = QJsonDocument::Indented) const
125  {
126  QJsonDocument jsonDoc(toJson());
127  return jsonDoc.toJson(format);
128  }
129 
132  void convertFromJson(const QJsonObject &json)
133  {
134  derived().clear();
135  QJsonValue value = json.value("containerbase");
136  if (value.isUndefined()) { throw CJsonException("Missing 'containerbase'"); }
137  QJsonArray array = value.toArray();
138  int index = 0;
139  for (auto i = array.begin(); i != array.end(); ++i)
140  {
141  CJsonScope scope("containerbase", index++);
142  Q_UNUSED(scope);
143  QJsonValueRef ref = (*i);
144  typename Derived::value_type val;
145  ref >> val;
146  derived().push_back(std::move(val));
147  }
148  }
149 
151  void convertFromJson(const QString &jsonString, bool acceptCacheFormat = false)
152  {
153  if (jsonString.isEmpty()) { return; }
154  const QJsonObject jsonObject = json::jsonObjectFromString(jsonString, acceptCacheFormat);
155  this->convertFromJson(jsonObject);
156  }
157 
159  static Derived fromJson(const QJsonObject &json)
160  {
161  Derived derived;
162  derived.convertFromJson(json);
163  return derived;
164  }
165 
167  static Derived fromJson(const QString &jsonString, bool acceptCacheJson = false)
168  {
169  Derived obj;
170  if (jsonString.isEmpty()) { return obj; }
171  const QJsonObject jsonObj =
172  acceptCacheJson ? json::swiftDataObjectValue(jsonString) : json::jsonObjectFromString(jsonString);
173  obj.convertFromJson(jsonObj);
174  return obj;
175  }
176 
178  static Derived fromJsonNoThrow(const QString &jsonString, bool acceptCacheJson, bool &success, QString &errMsg)
179  {
180  success = false;
181  Derived obj;
182  try
183  {
184  if (jsonString.isEmpty()) { return obj; }
185  const QJsonObject jsonObj =
186  acceptCacheJson ? json::swiftDataObjectValue(jsonString) : json::jsonObjectFromString(jsonString);
187  obj.convertFromJson(jsonObj);
188  success = true;
189  }
190  catch (const CJsonException &ex)
191  {
192  errMsg = ex.toString("JSON conversion");
193  }
194  return obj;
195  }
196 
198  CStatusMessage convertFromJsonNoThrow(const QJsonObject &json, const CLogCategoryList &categories,
199  const QString &prefix); // implemented in statusmessage.h
200 
202  CStatusMessage convertFromJsonNoThrow(const QString &jsonString, const CLogCategoryList &categories,
203  const QString &prefix); // implemented in statusmessage.h
204 
206  QString convertToQString(bool i18n = false) const
207  {
208  QString str;
209  for (const auto &value : derived())
210  {
211  str += (str.isEmpty() ? "{" : ", ") + CContainerHelper::stringify(value, i18n);
212  }
213  if (str.isEmpty()) { str = "{"; }
214  return str += "}";
215  }
216 
218  QStringList toStringList(bool i18n = false) const
219  {
220  QStringList sl;
221  for (const auto &obj : this->derived()) { sl.append(obj.toQString(i18n)); }
222  return sl;
223  }
224 
225  protected:
227  int getMetaTypeId() const { return qMetaTypeId<Derived>(); }
228 
229  public:
231  void marshallToDbus(QDBusArgument &argument) const
232  {
233  argument.beginArray(qMetaTypeId<typename Derived::value_type>());
234  std::for_each(derived().cbegin(), derived().cend(), [&](const auto &value) { argument << value; });
235  argument.endArray();
236  }
237 
239  void unmarshallFromDbus(const QDBusArgument &argument)
240  {
241  derived().clear();
242  argument.beginArray();
243  while (!argument.atEnd())
244  {
245  typename Derived::value_type value;
246  argument >> value;
247  derived().push_back(value);
248  }
249  argument.endArray();
250  }
251 
252  private:
253  Derived &derived() { return static_cast<Derived &>(*this); }
254  const Derived &derived() const { return static_cast<const Derived &>(*this); }
255  };
256 } // namespace swift::misc
257 
258 #endif // SWIFT_MISC_CONTAINERBASE_H
Base class for CCollection and CSequence adding mutating operations and CValueObject facility on top ...
Definition: containerbase.h:65
QStringList toStringList(bool i18n=false) const
To string list.
QJsonObject toJson() const
Cast to JSON object.
static Derived fromJsonNoThrow(const QString &jsonString, bool acceptCacheJson, bool &success, QString &errMsg)
Static version of convertFromJson.
auto to() const
Return a new container of a different type, containing the same elements as this one.
Definition: containerbase.h:83
void convertFromJson(const QString &jsonString, bool acceptCacheFormat=false)
Assign from JSON object string.
QString convertToQString(bool i18n=false) const
Cast as QString.
Other< T > to(Other< T > other) const
Return a new container of a different type, containing the same elements as this one.
Definition: containerbase.h:93
QString toJsonString(QJsonDocument::JsonFormat format=QJsonDocument::Indented) const
Convenience function JSON as string.
static Derived fromJson(const QString &jsonString, bool acceptCacheJson=false)
Static version of convertFromJson.
void unmarshallFromDbus(const QDBusArgument &argument)
Unmarshall without begin/endStructure, for when composed within another object.
int removeIf(K0 k0, V0 v0, KeysValues... keysValues)
Remove elements matching some particular key/value pair(s).
void convertFromJson(const QJsonObject &json)
Assign from JSON object.
CStatusMessage convertFromJsonNoThrow(const QJsonObject &json, const CLogCategoryList &categories, const QString &prefix)
Call convertFromJson, catch any CJsonException that is thrown and return it as CStatusMessage.
static Derived fromJson(const QJsonObject &json)
Static version of convertFromJson.
friend size_t qHash(const Derived &)
Simplifies composition, returns 0 for performance.
friend int compare(const Derived &a, const Derived &b)
Return negative, zero, or positive if a is less than, equal to, or greater than b.
Definition: containerbase.h:68
void marshallToDbus(QDBusArgument &argument) const
Marshall without begin/endStructure, for when composed within another object.
int getMetaTypeId() const
Returns the Qt meta type ID of this object.
Class providing static helper methods for different containers.
Definition: containerbase.h:26
static QString stringify(const U &obj, bool i18n)
Stringify value object.
Definition: containerbase.h:30
static QString stringify(qlonglong n, bool i18n)
Stringify qlonglong.
Definition: containerbase.h:39
static QString stringify(const std::pair< A, B > &pair, bool i18n)
Stringify pair.
Definition: containerbase.h:48
static QString stringify(double n, bool i18n)
Stringify double.
Definition: containerbase.h:43
static QString stringify(QString str, bool)
Stringify QString.
Definition: containerbase.h:45
static QString stringify(uint n, bool i18n)
Stringify uint.
Definition: containerbase.h:37
static QString stringify(qulonglong n, bool i18n)
Stringify qulonglong.
Definition: containerbase.h:41
static QString stringify(int n, bool i18n)
Stringify int.
Definition: containerbase.h:35
Thrown when a convertFromJson method encounters an unrecoverable error in JSON data.
Definition: jsonexception.h:24
QString toString(const QString &prefix) const
As string info.
Pseudo-RAII pattern that tracks the current JSON value being converted.
Definition: jsonexception.h:50
A sequence of log categories.
Any container class with begin and end iterators can inherit from this CRTP class to gain some useful...
Definition: range.h:33
Streamable status message, e.g.
CRTP class template which will generate marshalling operators for a derived class with its own marsha...
Definition: mixindbus.h:39
CRTP class template which will generate marshalling operators for a derived class with its own marsha...
Definition: mixinjson.h:37
CRTP class template from which a derived class can inherit common methods dealing with the metatype o...
Definition: mixinmetatype.h:29
CRTP class template from which a derived class can inherit string streaming operations.
Definition: mixinstring.h:31
QJsonObject jsonObjectFromString(const QString &json, bool acceptCacheFormat)
JSON Object from string.
Definition: json.cpp:413
auto MemberEqual(Ts... vs)
Predicate which tests whether some member functions return some values.
Definition: predicates.h:26
Free functions in swift::misc.