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 | |