aboutsummaryrefslogtreecommitdiff
path: root/src/base/QXmppDataFormBase.h
blob: 0fe1b6aa40c0e5e08a76c0efce8d7b03c9fa8087 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// SPDX-FileCopyrightText: 2021 Linus Jahn <lnj@kaidan.im>
//
// SPDX-License-Identifier: LGPL-2.1-or-later

#ifndef QXMPPDATAFORMBASED_H
#define QXMPPDATAFORMBASED_H

#include "QXmppDataForm.h"

#include <optional>

class QXmppDataForm;

class QXMPP_EXPORT QXmppDataFormBase
{
public:
    virtual ~QXmppDataFormBase() = default;

    virtual QXmppDataForm toDataForm() const;

protected:
    static bool fromDataForm(const QXmppDataForm &form, QXmppDataFormBase &parent);

    virtual QString formType() const = 0;
    virtual void parseForm(const QXmppDataForm &) = 0;
    virtual void serializeForm(QXmppDataForm &) const = 0;

    std::optional<quint32> parseUInt(const QVariant &variant)
    {
        bool ok;
        if (const auto result = variant.toString().toUInt(&ok); ok) {
            return result;
        }
        return std::nullopt;
    }

    std::optional<quint64> parseULongLong(const QVariant &variant)
    {
        bool ok;
        if (const auto result = variant.toString().toULongLong(&ok); ok) {
            return result;
        }
        return std::nullopt;
    }

    std::optional<bool> parseBool(const QVariant &variant)
    {
        if (variant.type() == QVariant::Bool) {
            return variant.toBool();
        }
        return std::nullopt;
    }

    template<typename T>
    static void serializeValue(QXmppDataForm &form, QXmppDataForm::Field::Type type, const QString &name, const T &value)
    {
        form.fields() << QXmppDataForm::Field(type, name, value);
    }

    template<typename T>
    static void serializeNullable(QXmppDataForm &form, QXmppDataForm::Field::Type type, const QString &name, const T &value)
    {
        if (!value.isNull()) {
            serializeValue(form, type, name, value);
        }
    }

    template<typename T>
    static void serializeEmptyable(QXmppDataForm &form, QXmppDataForm::Field::Type type, const QString &name, const T &value)
    {
        if (!value.isEmpty()) {
            serializeValue(form, type, name, value);
        }
    }

    template<typename T, typename ValueConverter = T (*)(T)>
    static void serializeOptional(
        QXmppDataForm &form, QXmppDataForm::Field::Type type, const QString &name, const std::optional<T> &optional, ValueConverter convert = [](T a) { return a; })
    {
        if (optional.has_value()) {
            serializeValue(form, type, name, convert(*optional));
        }
    }

    template<typename T>
    static void serializeOptionalNumber(QXmppDataForm &form, QXmppDataForm::Field::Type type, const QString &name, std::optional<T> optional)
    {
        if (optional.has_value()) {
            serializeValue(form, type, name, QString::number(*optional));
        }
    }

    static void serializeDatetime(QXmppDataForm &form, const QString &name, const QDateTime &datetime, QXmppDataForm::Field::Type type = QXmppDataForm::Field::TextSingleField);
};

class QXmppExtensibleDataFormBasePrivate;

class QXMPP_EXPORT QXmppExtensibleDataFormBase : public QXmppDataFormBase
{
public:
    QXmppExtensibleDataFormBase();
    /// \cond
    QXmppExtensibleDataFormBase(const QXmppExtensibleDataFormBase &);
    QXmppExtensibleDataFormBase(QXmppExtensibleDataFormBase &&);
    virtual ~QXmppExtensibleDataFormBase();

    QXmppExtensibleDataFormBase &operator=(const QXmppExtensibleDataFormBase &);
    QXmppExtensibleDataFormBase &operator=(QXmppExtensibleDataFormBase &&);
    /// \endcond

    QList<QXmppDataForm::Field> unknownFields() const;
    void setUnknownFields(const QList<QXmppDataForm::Field> &unknownFields);

protected:
    void parseForm(const QXmppDataForm &) override;
    void serializeForm(QXmppDataForm &) const override;

    virtual bool parseField(const QXmppDataForm::Field &);

private:
    QSharedDataPointer<QXmppExtensibleDataFormBasePrivate> d;
};

#endif  // QXMPPDATAFORMBASED_H