| 1 | // SPDX-FileCopyrightText: 2020 Kitsune Ral <kitsune-ral@users.sf.net> |
| 2 | // SPDX-License-Identifier: LGPL-2.1-or-later |
| 3 | |
| 4 | #pragma once |
| 5 | |
| 6 | #include "quotient_common.h" |
| 7 | |
| 8 | #include <QtCore/QUrl> |
| 9 | #include <QtCore/QUrlQuery> |
| 10 | |
| 11 | namespace Quotient { |
| 12 | |
| 13 | /*! \brief A wrapper around a Matrix URI or identifier |
| 14 | * |
| 15 | * This class encapsulates a Matrix resource identifier, passed in either of |
| 16 | * 3 forms: a plain Matrix identifier (sigil, localpart, serverpart or, for |
| 17 | * modern event ids, sigil and base64 hash); an MSC2312 URI (aka matrix: URI); |
| 18 | * or a matrix.to URL. The input can be either encoded (serverparts with |
| 19 | * punycode, the rest with percent-encoding) or unencoded (in this case it is |
| 20 | * the caller's responsibility to resolve all possible ambiguities). |
| 21 | * |
| 22 | * The class provides functions to check the validity of the identifier, |
| 23 | * its type, and obtain components, also in either unencoded (for displaying) |
| 24 | * or encoded (for APIs) form. |
| 25 | */ |
| 26 | class QUOTIENT_API Uri : private QUrl { |
| 27 | Q_GADGET |
| 28 | public: |
| 29 | enum Type : char { |
| 30 | Invalid = char(-1), |
| 31 | Empty = 0x0, |
| 32 | UserId = '@', |
| 33 | RoomId = '!', |
| 34 | RoomAlias = '#', |
| 35 | Group = '+', |
| 36 | BareEventId = '$', // https://github.com/matrix-org/matrix-doc/pull/2644 |
| 37 | NonMatrix = ':' |
| 38 | }; |
| 39 | Q_ENUM(Type) |
| 40 | enum SecondaryType : char { NoSecondaryId = 0x0, EventId = '$' }; |
| 41 | Q_ENUM(SecondaryType) |
| 42 | |
| 43 | enum UriForm : short { CanonicalUri, MatrixToUri }; |
| 44 | Q_ENUM(UriForm) |
| 45 | |
| 46 | /// Construct an empty Matrix URI |
| 47 | Uri() = default; |
| 48 | /*! \brief Decode a user input string to a Matrix identifier |
| 49 | * |
| 50 | * Accepts plain Matrix ids, MSC2312 URIs (aka matrix: URIs) and |
| 51 | * matrix.to URLs. In case of URIs/URLs, it uses QUrl's TolerantMode |
| 52 | * parser to decode common mistakes/irregularities (see QUrl documentation |
| 53 | * for more details). |
| 54 | */ |
| 55 | Uri(const QString& uriOrId); |
| 56 | |
| 57 | /// Construct a Matrix URI from components |
| 58 | explicit Uri(QByteArray primaryId, QByteArray secondaryId = {}, |
| 59 | QString query = {}); |
| 60 | /// Construct a Matrix URI from matrix.to or MSC2312 (matrix:) URI |
| 61 | explicit Uri(QUrl url); |
| 62 | |
| 63 | static Uri fromUserInput(const QString& uriOrId); |
| 64 | static Uri fromUrl(QUrl url); |
| 65 | |
| 66 | /// Get the primary type of the Matrix URI (user id, room id or alias) |
| 67 | /*! Note that this does not include an event as a separate type, since |
| 68 | * events can only be addressed inside of rooms, which, in turn, are |
| 69 | * addressed either by id or alias. If you need to check whether the URI |
| 70 | * is specifically an event URI, use secondaryType() instead. |
| 71 | */ |
| 72 | Q_INVOKABLE Type type() const; |
| 73 | Q_INVOKABLE SecondaryType secondaryType() const; |
| 74 | Q_INVOKABLE QUrl toUrl(UriForm form = CanonicalUri) const; |
| 75 | Q_INVOKABLE QString primaryId() const; |
| 76 | Q_INVOKABLE QString secondaryId() const; |
| 77 | Q_INVOKABLE QString action() const; |
| 78 | Q_INVOKABLE void setAction(const QString& newAction); |
| 79 | Q_INVOKABLE QStringList viaServers() const; |
| 80 | Q_INVOKABLE bool isValid() const; |
| 81 | using QUrl::path, QUrl::query, QUrl::fragment; |
| 82 | using QUrl::isEmpty, QUrl::toDisplayString; |
| 83 | |
| 84 | private: |
| 85 | Type primaryType_ = Empty; |
| 86 | }; |
| 87 | |
| 88 | } |
| 89 | |