aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/converters.cpp14
-rw-r--r--lib/converters.h175
-rw-r--r--lib/events/encryptedevent.cpp10
-rw-r--r--lib/events/encryptionevent.cpp50
-rw-r--r--lib/events/encryptionevent.h35
-rw-r--r--lib/events/event.h4
-rw-r--r--lib/events/roomcanonicalaliasevent.h43
-rw-r--r--lib/events/roomcreateevent.cpp19
-rw-r--r--lib/events/roomevent.cpp6
-rw-r--r--lib/events/roommemberevent.cpp19
-rw-r--r--lib/events/stateevent.cpp2
-rw-r--r--lib/quotient_common.h12
-rw-r--r--lib/room.cpp4
13 files changed, 231 insertions, 162 deletions
diff --git a/lib/converters.cpp b/lib/converters.cpp
index 444ca4f6..b0e3a4b6 100644
--- a/lib/converters.cpp
+++ b/lib/converters.cpp
@@ -2,9 +2,23 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
#include "converters.h"
+#include "logging.h"
#include <QtCore/QVariant>
+void Quotient::_impl::warnUnknownEnumValue(const QString& stringValue,
+ const char* enumTypeName)
+{
+ qWarning(EVENTS).noquote()
+ << "Unknown" << enumTypeName << "value:" << stringValue;
+}
+
+void Quotient::_impl::reportEnumOutOfBounds(uint32_t v, const char* enumTypeName)
+{
+ qCritical(MAIN).noquote()
+ << "Value" << v << "is out of bounds for enumeration" << enumTypeName;
+}
+
QJsonValue Quotient::JsonConverter<QVariant>::dump(const QVariant& v)
{
return QJsonValue::fromVariant(v);
diff --git a/lib/converters.h b/lib/converters.h
index c445442c..bf456af9 100644
--- a/lib/converters.h
+++ b/lib/converters.h
@@ -28,23 +28,8 @@ struct JsonObjectConverter {
static void fillFrom(const QJsonObject&, T&) = delete;
};
-namespace _impl {
- template <typename T, typename = void>
- struct JsonExporter {
- static QJsonObject dump(const T& data)
- {
- QJsonObject jo;
- JsonObjectConverter<T>::dumpTo(jo, data);
- return jo;
- }
- };
-
- template <typename T>
- struct JsonExporter<
- T, std::enable_if_t<std::is_invocable_v<decltype(&T::toJson), T>>> {
- static auto dump(const T& data) { return data.toJson(); }
- };
-}
+template <typename PodT, typename JsonT>
+PodT fromJson(const JsonT&);
//! \brief The switchboard for extra conversion algorithms behind from/toJson
//!
@@ -62,13 +47,23 @@ namespace _impl {
//! that they are not supported and it's not feasible to support those by means
//! of overloading toJson() and specialising fromJson().
template <typename T>
-struct JsonConverter : _impl::JsonExporter<T> {
+struct JsonConverter {
// Unfortunately, if constexpr doesn't work with dump() and T::toJson
// because trying to check invocability of T::toJson hits a hard
// (non-SFINAE) compilation error if the member is not there. Hence a bit
// more verbose SFINAE construct in _impl::JsonExporter.
+ static auto dump(const T& data)
+ {
+ if constexpr (requires() { data.toJson(); })
+ return data.toJson();
+ else {
+ QJsonObject jo;
+ JsonObjectConverter<T>::dumpTo(jo, data);
+ return jo;
+ }
+ }
- static T doLoad(const QJsonObject& jo)
+ static T load(const QJsonObject& jo)
{
// 'else' below are required to suppress code generation for unused
// branches - 'return' is not enough
@@ -82,66 +77,150 @@ struct JsonConverter : _impl::JsonExporter<T> {
return pod;
}
}
- static T load(const QJsonValue& jv) { return doLoad(jv.toObject()); }
- static T load(const QJsonDocument& jd) { return doLoad(jd.object()); }
+ // By default, revert to fromJson() so that one could provide a single
+ // fromJson<T, QJsonObject> specialisation instead of specialising
+ // the entire JsonConverter; if a different type of JSON value is needed
+ // (e.g., an array), specialising JsonConverter is inevitable
+ static T load(QJsonValueRef jvr) { return fromJson<T>(QJsonValue(jvr)); }
+ static T load(const QJsonValue& jv) { return fromJson<T>(jv.toObject()); }
+ static T load(const QJsonDocument& jd) { return fromJson<T>(jd.object()); }
};
template <typename T>
- requires (!std::is_constructible_v<QJsonValue, T>)
inline auto toJson(const T& pod)
// -> can return anything from which QJsonValue or, in some cases, QJsonDocument
// is constructible
{
- return JsonConverter<T>::dump(pod);
+ if constexpr (std::is_constructible_v<QJsonValue, T>)
+ return pod; // No-op if QJsonValue can be directly constructed
+ else
+ return JsonConverter<T>::dump(pod);
}
-inline auto toJson(const QJsonObject& jo) { return jo; }
-inline auto toJson(const QJsonValue& jv) { return jv; }
-
template <typename T>
inline void fillJson(QJsonObject& json, const T& data)
{
JsonObjectConverter<T>::dumpTo(json, data);
}
-template <typename T>
-inline T fromJson(const QJsonValue& jv)
+template <typename PodT, typename JsonT>
+inline PodT fromJson(const JsonT& json)
{
- return JsonConverter<T>::load(jv);
+ // JsonT here can be whatever the respective JsonConverter specialisation
+ // accepts but by default it's QJsonValue, QJsonDocument, or QJsonObject
+ return JsonConverter<PodT>::load(json);
}
-template<>
-inline QJsonValue fromJson(const QJsonValue& jv) { return jv; }
+// Convenience fromJson() overload that deduces PodT instead of requiring
+// the coder to explicitly type it. It still enforces the
+// overwrite-everything semantics of fromJson(), unlike fillFromJson()
+
+template <typename JsonT, typename PodT>
+inline void fromJson(const JsonT& json, PodT& pod)
+{
+ pod = fromJson<PodT>(json);
+}
template <typename T>
-inline T fromJson(const QJsonDocument& jd)
+inline void fillFromJson(const QJsonValue& jv, T& pod)
{
- return JsonConverter<T>::load(jd);
+ if constexpr (requires() { JsonObjectConverter<T>::fillFrom({}, pod); }) {
+ JsonObjectConverter<T>::fillFrom(jv.toObject(), pod);
+ return;
+ } else if (!jv.isUndefined())
+ pod = fromJson<T>(jv);
}
-// Convenience fromJson() overloads that deduce T instead of requiring
-// the coder to explicitly type it. They still enforce the
-// overwrite-everything semantics of fromJson(), unlike fillFromJson()
+namespace _impl {
+ void warnUnknownEnumValue(const QString& stringValue,
+ const char* enumTypeName);
+ void reportEnumOutOfBounds(uint32_t v, const char* enumTypeName);
+}
-template <typename T>
-inline void fromJson(const QJsonValue& jv, T& pod)
+//! \brief Facility string-to-enum converter
+//!
+//! This is to simplify enum loading from JSON - just specialise
+//! Quotient::fromJson() and call this function from it, passing (aside from
+//! the JSON value for the enum - that must be a string, not an int) any
+//! iterable container of string'y values (const char*, QLatin1String, etc.)
+//! matching respective enum values, 0-based.
+//! \sa enumToJsonString
+template <typename EnumT, typename EnumStringValuesT>
+EnumT enumFromJsonString(const QString& s, const EnumStringValuesT& enumValues,
+ EnumT defaultValue)
{
- pod = jv.isUndefined() ? T() : fromJson<T>(jv);
+ static_assert(std::is_unsigned_v<std::underlying_type_t<EnumT>>);
+ if (const auto it = std::find(cbegin(enumValues), cend(enumValues), s);
+ it != cend(enumValues))
+ return EnumT(it - cbegin(enumValues));
+
+ if (!s.isEmpty())
+ _impl::warnUnknownEnumValue(s, qt_getEnumName(EnumT()));
+ return defaultValue;
}
-template <typename T>
-inline void fromJson(const QJsonDocument& jd, T& pod)
+//! \brief Facility enum-to-string converter
+//!
+//! This does the same as enumFromJsonString, the other way around.
+//! \note The source enumeration must not have gaps in values, or \p enumValues
+//! has to match those gaps (i.e., if the source enumeration is defined
+//! as <tt>{ Value1 = 1, Value2 = 3, Value3 = 5 }</tt> then \p enumValues
+//! should be defined as <tt>{ "", "Value1", "", "Value2", "", "Value3"
+//! }</tt> (mind the gap at value 0, in particular).
+//! \sa enumFromJsonString
+template <typename EnumT, typename EnumStringValuesT>
+QString enumToJsonString(EnumT v, const EnumStringValuesT& enumValues)
{
- pod = fromJson<T>(jd);
+ static_assert(std::is_unsigned_v<std::underlying_type_t<EnumT>>);
+ if (v < size(enumValues))
+ return enumValues[v];
+
+ _impl::reportEnumOutOfBounds(static_cast<uint32_t>(v),
+ qt_getEnumName(EnumT()));
+ Q_ASSERT(false);
+ return {};
}
-template <typename T>
-inline void fillFromJson(const QJsonValue& jv, T& pod)
+//! \brief Facility converter for flags
+//!
+//! This is very similar to enumFromJsonString, except that the target
+//! enumeration is assumed to be of a 'flag' kind - i.e. its values must be
+//! a power-of-two sequence starting from 1, without gaps, so exactly 1,2,4,8,16
+//! and so on.
+//! \note Unlike enumFromJsonString, the values start from 1 and not from 0,
+//! with 0 being used for an invalid value by default.
+//! \note This function does not support flag combinations.
+//! \sa QUO_DECLARE_FLAGS, QUO_DECLARE_FLAGS_NS
+template <typename FlagT, typename FlagStringValuesT>
+FlagT flagFromJsonString(const QString& s, const FlagStringValuesT& flagValues,
+ FlagT defaultValue = FlagT(0U))
{
- if (jv.isObject())
- JsonObjectConverter<T>::fillFrom(jv.toObject(), pod);
- else if (!jv.isUndefined())
- pod = fromJson<T>(jv);
+ // Enums based on signed integers don't make much sense for flag types
+ static_assert(std::is_unsigned_v<std::underlying_type_t<FlagT>>);
+ if (const auto it = std::find(cbegin(flagValues), cend(flagValues), s);
+ it != cend(flagValues))
+ return FlagT(1U << (it - cbegin(flagValues)));
+
+ if (!s.isEmpty())
+ _impl::warnUnknownEnumValue(s, qt_getEnumName(FlagT()));
+ return defaultValue;
+}
+
+template <typename FlagT, typename FlagStringValuesT>
+QString flagToJsonString(FlagT v, const FlagStringValuesT& flagValues)
+{
+ static_assert(std::is_unsigned_v<std::underlying_type_t<FlagT>>);
+ if (const auto offset =
+ qCountTrailingZeroBits(std::underlying_type_t<FlagT>(v));
+ offset < size(flagValues)) //
+ {
+ return flagValues[offset];
+ }
+
+ _impl::reportEnumOutOfBounds(static_cast<uint32_t>(v),
+ qt_getEnumName(FlagT()));
+ Q_ASSERT(false);
+ return {};
}
// JsonConverter<> specialisations
diff --git a/lib/events/encryptedevent.cpp b/lib/events/encryptedevent.cpp
index c97ccc16..ec00ad4c 100644
--- a/lib/events/encryptedevent.cpp
+++ b/lib/events/encryptedevent.cpp
@@ -49,14 +49,16 @@ RoomEventPtr EncryptedEvent::createDecrypted(const QString &decrypted) const
eventObject["event_id"] = id();
eventObject["sender"] = senderId();
eventObject["origin_server_ts"] = originTimestamp().toMSecsSinceEpoch();
- if (const auto relatesToJson = contentPart("m.relates_to"_ls); !relatesToJson.isUndefined()) {
+ if (const auto relatesToJson = contentPart<QJsonObject>("m.relates_to"_ls);
+ !relatesToJson.isEmpty()) {
auto content = eventObject["content"].toObject();
- content["m.relates_to"] = relatesToJson.toObject();
+ content["m.relates_to"] = relatesToJson;
eventObject["content"] = content;
}
- if (const auto redactsJson = unsignedPart("redacts"_ls); !redactsJson.isUndefined()) {
+ if (const auto redactsJson = unsignedPart<QString>("redacts"_ls);
+ !redactsJson.isEmpty()) {
auto unsign = eventObject["unsigned"].toObject();
- unsign["redacts"] = redactsJson.toString();
+ unsign["redacts"] = redactsJson;
eventObject["unsigned"] = unsign;
}
return loadEvent<RoomEvent>(eventObject);
diff --git a/lib/events/encryptionevent.cpp b/lib/events/encryptionevent.cpp
index 1654d6f3..8872447b 100644
--- a/lib/events/encryptionevent.cpp
+++ b/lib/events/encryptionevent.cpp
@@ -6,47 +6,45 @@
#include "e2ee/e2ee.h"
-namespace Quotient {
+using namespace Quotient;
+
static constexpr std::array encryptionStrings { MegolmV1AesSha2AlgoKey };
template <>
-struct JsonConverter<EncryptionType> {
- static EncryptionType load(const QJsonValue& jv)
- {
- const auto& encryptionString = jv.toString();
- for (auto it = encryptionStrings.begin(); it != encryptionStrings.end();
- ++it)
- if (encryptionString == *it)
- return EncryptionType(it - encryptionStrings.begin());
-
- if (!encryptionString.isEmpty())
- qCWarning(EVENTS) << "Unknown EncryptionType: " << encryptionString;
- return EncryptionType::Undefined;
- }
-};
-} // namespace Quotient
-
-using namespace Quotient;
+EncryptionType Quotient::fromJson(const QJsonValue& jv)
+{
+ const auto& encryptionString = jv.toString();
+ for (auto it = encryptionStrings.begin(); it != encryptionStrings.end();
+ ++it)
+ if (encryptionString == *it)
+ return EncryptionType(it - encryptionStrings.begin());
+
+ if (!encryptionString.isEmpty())
+ qCWarning(EVENTS) << "Unknown EncryptionType: " << encryptionString;
+ return EncryptionType::Undefined;
+}
EncryptionEventContent::EncryptionEventContent(const QJsonObject& json)
- : encryption(fromJson<EncryptionType>(json[AlgorithmKeyL]))
+ : encryption(fromJson<Quotient::EncryptionType>(json[AlgorithmKeyL]))
, algorithm(sanitized(json[AlgorithmKeyL].toString()))
- , rotationPeriodMs(json[RotationPeriodMsKeyL].toInt(604800000))
- , rotationPeriodMsgs(json[RotationPeriodMsgsKeyL].toInt(100))
-{}
+{
+ // NB: fillFromJson only fills the variable if the JSON key exists
+ fillFromJson<int>(json[RotationPeriodMsKeyL], rotationPeriodMs);
+ fillFromJson<int>(json[RotationPeriodMsgsKeyL], rotationPeriodMsgs);
+}
-EncryptionEventContent::EncryptionEventContent(EncryptionType et)
+EncryptionEventContent::EncryptionEventContent(Quotient::EncryptionType et)
: encryption(et)
{
- if(encryption != Undefined) {
- algorithm = encryptionStrings[encryption];
+ if(encryption != Quotient::EncryptionType::Undefined) {
+ algorithm = encryptionStrings[static_cast<size_t>(encryption)];
}
}
QJsonObject EncryptionEventContent::toJson() const
{
QJsonObject o;
- if (encryption != EncryptionType::Undefined)
+ if (encryption != Quotient::EncryptionType::Undefined)
o.insert(AlgorithmKey, algorithm);
o.insert(RotationPeriodMsKey, rotationPeriodMs);
o.insert(RotationPeriodMsgsKey, rotationPeriodMsgs);
diff --git a/lib/events/encryptionevent.h b/lib/events/encryptionevent.h
index 945b17e7..91452c3f 100644
--- a/lib/events/encryptionevent.h
+++ b/lib/events/encryptionevent.h
@@ -4,51 +4,44 @@
#pragma once
+#include "quotient_common.h"
#include "stateevent.h"
namespace Quotient {
class QUOTIENT_API EncryptionEventContent {
public:
- enum EncryptionType : size_t { MegolmV1AesSha2 = 0, Undefined };
+ using EncryptionType
+ [[deprecated("Use Quotient::EncryptionType instead")]] =
+ Quotient::EncryptionType;
- QUO_IMPLICIT EncryptionEventContent(EncryptionType et);
- [[deprecated("This constructor will require explicit EncryptionType soon")]] //
- explicit EncryptionEventContent()
- : EncryptionEventContent(Undefined)
- {}
+ // NOLINTNEXTLINE(google-explicit-constructor)
+ QUO_IMPLICIT EncryptionEventContent(Quotient::EncryptionType et);
explicit EncryptionEventContent(const QJsonObject& json);
QJsonObject toJson() const;
- EncryptionType encryption;
- QString algorithm;
- int rotationPeriodMs;
- int rotationPeriodMsgs;
+ Quotient::EncryptionType encryption;
+ QString algorithm {};
+ int rotationPeriodMs = 604'800'000;
+ int rotationPeriodMsgs = 100;
};
-using EncryptionType = EncryptionEventContent::EncryptionType;
-
class QUOTIENT_API EncryptionEvent : public StateEvent<EncryptionEventContent> {
- Q_GADGET
public:
DEFINE_EVENT_TYPEID("m.room.encryption", EncryptionEvent)
- using EncryptionType = EncryptionEventContent::EncryptionType;
- Q_ENUM(EncryptionType)
+ using EncryptionType
+ [[deprecated("Use Quotient::EncryptionType instead")]] =
+ Quotient::EncryptionType;
explicit EncryptionEvent(const QJsonObject& obj)
: StateEvent(typeId(), obj)
{}
- [[deprecated("This constructor will require an explicit parameter soon")]] //
-// explicit EncryptionEvent()
-// : EncryptionEvent(QJsonObject())
-// {}
explicit EncryptionEvent(EncryptionEventContent&& content)
: StateEvent(typeId(), matrixTypeId(), QString(), std::move(content))
{}
- EncryptionType encryption() const { return content().encryption; }
-
+ Quotient::EncryptionType encryption() const { return content().encryption; }
QString algorithm() const { return content().algorithm; }
int rotationPeriodMs() const { return content().rotationPeriodMs; }
int rotationPeriodMsgs() const { return content().rotationPeriodMsgs; }
diff --git a/lib/events/event.h b/lib/events/event.h
index 05eb51e9..da6cf3c7 100644
--- a/lib/events/event.h
+++ b/lib/events/event.h
@@ -212,7 +212,7 @@ public:
const QJsonObject contentJson() const;
- template <typename T = QJsonValue, typename KeyT>
+ template <typename T, typename KeyT>
const T contentPart(KeyT&& key) const
{
return fromJson<T>(contentJson()[std::forward<KeyT>(key)]);
@@ -227,7 +227,7 @@ public:
const QJsonObject unsignedJson() const;
- template <typename T = QJsonValue, typename KeyT>
+ template <typename T, typename KeyT>
const T unsignedPart(KeyT&& key) const
{
return fromJson<T>(unsignedJson()[std::forward<KeyT>(key)]);
diff --git a/lib/events/roomcanonicalaliasevent.h b/lib/events/roomcanonicalaliasevent.h
index bb8654e5..e599699d 100644
--- a/lib/events/roomcanonicalaliasevent.h
+++ b/lib/events/roomcanonicalaliasevent.h
@@ -7,35 +7,30 @@
#include "stateevent.h"
namespace Quotient {
-namespace EventContent{
- class AliasesEventContent {
-
- public:
-
- template<typename T1, typename T2>
- AliasesEventContent(T1&& canonicalAlias, T2&& altAliases)
- : canonicalAlias(std::forward<T1>(canonicalAlias))
- , altAliases(std::forward<T2>(altAliases))
- { }
-
- AliasesEventContent(const QJsonObject& json)
- : canonicalAlias(fromJson<QString>(json["alias"]))
- , altAliases(fromJson<QStringList>(json["alt_aliases"]))
- { }
-
- auto toJson() const
- {
- QJsonObject jo;
- addParam<IfNotEmpty>(jo, QStringLiteral("alias"), canonicalAlias);
- addParam<IfNotEmpty>(jo, QStringLiteral("alt_aliases"), altAliases);
- return jo;
- }
-
+namespace EventContent {
+ struct AliasesEventContent {
QString canonicalAlias;
QStringList altAliases;
};
} // namespace EventContent
+template<>
+inline EventContent::AliasesEventContent fromJson(const QJsonObject& jo)
+{
+ return EventContent::AliasesEventContent {
+ fromJson<QString>(jo["alias"_ls]),
+ fromJson<QStringList>(jo["alt_aliases"_ls])
+ };
+}
+template<>
+inline auto toJson(const EventContent::AliasesEventContent& c)
+{
+ QJsonObject jo;
+ addParam<IfNotEmpty>(jo, QStringLiteral("alias"), c.canonicalAlias);
+ addParam<IfNotEmpty>(jo, QStringLiteral("alt_aliases"), c.altAliases);
+ return jo;
+}
+
class RoomCanonicalAliasEvent
: public StateEvent<EventContent::AliasesEventContent> {
public:
diff --git a/lib/events/roomcreateevent.cpp b/lib/events/roomcreateevent.cpp
index bb6de648..3b5024d5 100644
--- a/lib/events/roomcreateevent.cpp
+++ b/lib/events/roomcreateevent.cpp
@@ -6,20 +6,11 @@
using namespace Quotient;
template <>
-struct Quotient::JsonConverter<RoomType> {
- static RoomType load(const QJsonValue& jv)
- {
- const auto& roomTypeString = jv.toString();
- for (auto it = RoomTypeStrings.begin(); it != RoomTypeStrings.end();
- ++it)
- if (roomTypeString == *it)
- return RoomType(it - RoomTypeStrings.begin());
-
- if (!roomTypeString.isEmpty())
- qCWarning(EVENTS) << "Unknown Room Type: " << roomTypeString;
- return RoomType::Undefined;
- }
-};
+RoomType Quotient::fromJson(const QJsonValue& jv)
+{
+ return enumFromJsonString(jv.toString(), RoomTypeStrings,
+ RoomType::Undefined);
+}
bool RoomCreateEvent::isFederated() const
{
diff --git a/lib/events/roomevent.cpp b/lib/events/roomevent.cpp
index 3ddf5ac4..e695e0ec 100644
--- a/lib/events/roomevent.cpp
+++ b/lib/events/roomevent.cpp
@@ -15,9 +15,9 @@ RoomEvent::RoomEvent(Type type, event_mtype_t matrixType,
RoomEvent::RoomEvent(Type type, const QJsonObject& json) : Event(type, json)
{
- if (const auto redaction = unsignedPart(RedactedCauseKeyL);
- redaction.isObject())
- _redactedBecause = makeEvent<RedactionEvent>(redaction.toObject());
+ if (const auto redaction = unsignedPart<QJsonObject>(RedactedCauseKeyL);
+ !redaction.isEmpty())
+ _redactedBecause = makeEvent<RedactionEvent>(redaction);
}
RoomEvent::~RoomEvent() = default; // Let the smart pointer do its job
diff --git a/lib/events/roommemberevent.cpp b/lib/events/roommemberevent.cpp
index c3be0e00..953ff8ae 100644
--- a/lib/events/roommemberevent.cpp
+++ b/lib/events/roommemberevent.cpp
@@ -11,18 +11,10 @@ template <>
struct JsonConverter<Membership> {
static Membership load(const QJsonValue& jv)
{
- const auto& ms = jv.toString();
- if (ms.isEmpty())
- {
- qCWarning(EVENTS) << "Empty membership state";
- return Membership::Invalid;
- }
- const auto it =
- std::find(MembershipStrings.begin(), MembershipStrings.end(), ms);
- if (it != MembershipStrings.end())
- return Membership(1U << (it - MembershipStrings.begin()));
-
- qCWarning(EVENTS) << "Unknown Membership value: " << ms;
+ if (const auto& ms = jv.toString(); !ms.isEmpty())
+ return flagFromJsonString<Membership>(ms, MembershipStrings);
+
+ qCWarning(EVENTS) << "Empty membership state";
return Membership::Invalid;
}
};
@@ -46,8 +38,7 @@ QJsonObject MemberEventContent::toJson() const
QJsonObject o;
if (membership != Membership::Invalid)
o.insert(QStringLiteral("membership"),
- MembershipStrings[qCountTrailingZeroBits(
- std::underlying_type_t<Membership>(membership))]);
+ flagToJsonString(membership, MembershipStrings));
if (displayName)
o.insert(QStringLiteral("displayname"), *displayName);
if (avatarUrl && avatarUrl->isValid())
diff --git a/lib/events/stateevent.cpp b/lib/events/stateevent.cpp
index c343e37f..43dfd6e8 100644
--- a/lib/events/stateevent.cpp
+++ b/lib/events/stateevent.cpp
@@ -21,7 +21,7 @@ StateEventBase::StateEventBase(Event::Type type, event_mtype_t matrixType,
bool StateEventBase::repeatsState() const
{
- const auto prevContentJson = unsignedPart(PrevContentKeyL);
+ const auto prevContentJson = unsignedPart<QJsonObject>(PrevContentKeyL);
return fullJson().value(ContentKeyL) == prevContentJson;
}
diff --git a/lib/quotient_common.h b/lib/quotient_common.h
index 233bcaa1..7fec9274 100644
--- a/lib/quotient_common.h
+++ b/lib/quotient_common.h
@@ -107,14 +107,20 @@ enum UriResolveResult : int8_t {
};
Q_ENUM_NS(UriResolveResult)
-enum RoomType {
- Space,
- Undefined,
+enum class RoomType : uint8_t {
+ Space = 0,
+ Undefined = 0xFF,
};
Q_ENUM_NS(RoomType)
[[maybe_unused]] constexpr std::array RoomTypeStrings { "m.space" };
+enum class EncryptionType : uint8_t {
+ MegolmV1AesSha2 = 0,
+ Undefined = 0xFF,
+};
+Q_ENUM_NS(EncryptionType)
+
} // namespace Quotient
Q_DECLARE_OPERATORS_FOR_FLAGS(Quotient::MembershipMask)
Q_DECLARE_OPERATORS_FOR_FLAGS(Quotient::JoinStates)
diff --git a/lib/room.cpp b/lib/room.cpp
index 2625105c..f67451ce 100644
--- a/lib/room.cpp
+++ b/lib/room.cpp
@@ -3062,7 +3062,7 @@ Room::Changes Room::processStateEvent(const RoomEvent& e)
return false;
}
if (oldEncEvt
- && oldEncEvt->encryption() != EncryptionEventContent::Undefined) {
+ && oldEncEvt->encryption() != EncryptionType::Undefined) {
qCWarning(STATE) << "The room is already encrypted but a new"
" room encryption event arrived - ignoring";
return false;
@@ -3508,5 +3508,5 @@ void Room::activateEncryption()
qCWarning(E2EE) << "Room" << objectName() << "is already encrypted";
return;
}
- setState<EncryptionEvent>(EncryptionEventContent::MegolmV1AesSha2);
+ setState<EncryptionEvent>(EncryptionType::MegolmV1AesSha2);
}