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 
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 
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 ref : array)
140  {
141  CJsonScope scope("containerbase", index++);
142  Q_UNUSED(scope);
143  typename Derived::value_type val;
144  ref >> val;
145  derived().push_back(std::move(val));
146  }
147  }
148 
150  void convertFromJson(const QString &jsonString, bool acceptCacheFormat = false)
151  {
152  if (jsonString.isEmpty()) { return; }
153  const QJsonObject jsonObject = json::jsonObjectFromString(jsonString, acceptCacheFormat);
154  this->convertFromJson(jsonObject);
155  }
156 
158  static Derived fromJson(const QJsonObject &json)
159  {
160  Derived derived;
161  derived.convertFromJson(json);
162  return derived;
163  }
164 
166  static Derived fromJson(const QString &jsonString, bool acceptCacheJson = false)
167  {
168  Derived obj;
169  if (jsonString.isEmpty()) { return obj; }
170  const QJsonObject jsonObj =
171  acceptCacheJson ? json::swiftDataObjectValue(jsonString) : json::jsonObjectFromString(jsonString);
172  obj.convertFromJson(jsonObj);
173  return obj;
174  }
175 
177  static Derived fromJsonNoThrow(const QString &jsonString, bool acceptCacheJson, bool &success, QString &errMsg)
178  {
179  success = false;
180  Derived obj;
181  try
182  {
183  if (jsonString.isEmpty()) { return obj; }
184  const QJsonObject jsonObj =
185  acceptCacheJson ? json::swiftDataObjectValue(jsonString) : json::jsonObjectFromString(jsonString);
186  obj.convertFromJson(jsonObj);
187  success = true;
188  }
189  catch (const CJsonException &ex)
190  {
191  errMsg = ex.toString("JSON conversion");
192  }
193  return obj;
194  }
195 
197  CStatusMessage convertFromJsonNoThrow(const QJsonObject &json, const CLogCategoryList &categories,
198  const QString &prefix); // implemented in statusmessage.h
199 
201  CStatusMessage convertFromJsonNoThrow(const QString &jsonString, const CLogCategoryList &categories,
202  const QString &prefix); // implemented in statusmessage.h
203 
205  QString convertToQString(bool i18n = false) const
206  {
207  QString str;
208  for (const auto &value : derived())
209  {
210  str += (str.isEmpty() ? "{" : ", ") + CContainerHelper::stringify(value, i18n);
211  }
212  if (str.isEmpty()) { str = "{"; }
213  return str += "}";
214  }
215 
217  QStringList toStringList(bool i18n = false) const
218  {
219  QStringList sl;
220  for (const auto &obj : this->derived()) { sl.append(obj.toQString(i18n)); }
221  return sl;
222  }
223 
224  protected:
226  int getMetaTypeId() const { return qMetaTypeId<Derived>(); }
227 
228  public:
230  void marshallToDbus(QDBusArgument &argument) const
231  {
232  argument.beginArray(qMetaTypeId<typename Derived::value_type>());
233  std::for_each(derived().cbegin(), derived().cend(), [&](const auto &value) { argument << value; });
234  argument.endArray();
235  }
236 
238  void unmarshallFromDbus(const QDBusArgument &argument)
239  {
240  derived().clear();
241  argument.beginArray();
242  while (!argument.atEnd())
243  {
244  typename Derived::value_type value;
245  argument >> value;
246  derived().push_back(value);
247  }
248  argument.endArray();
249  }
250 
251  private:
252  Derived &derived() { return static_cast<Derived &>(*this); }
253  const Derived &derived() const { return static_cast<const Derived &>(*this); }
254  };
255 } // namespace swift::misc
256 
257 #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:27
CRTP class template from which a derived class can inherit string streaming operations.
Definition: mixinstring.h:29
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.
bool atEnd() const const
void beginArray(QMetaType id)
QByteArray toJson(QJsonDocument::JsonFormat format) const const
QJsonObject::iterator insert(QLatin1StringView key, const QJsonValue &value)
QJsonValue value(QLatin1StringView key) const const
bool isUndefined() const const
QJsonArray toArray() const const
void append(QList< T > &&value)
QString toString(QDate date, QLocale::FormatType format) const const
bool isEmpty() const const
QString number(double n, char format, int precision)