logo
  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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
//! Error conditions.

use std::str::Utf8Error;

/// An error encountered when trying to parse an invalid ID string.
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, thiserror::Error)]
#[non_exhaustive]
pub enum Error {
    /// The client secret is empty.
    #[error("client secret is empty")]
    EmptyClientSecret,

    /// The room name is empty.
    #[error("room name is empty")]
    EmptyRoomName,

    /// The room version ID is empty.
    #[error("room version ID is empty")]
    EmptyRoomVersionId,

    /// The ID's localpart contains invalid characters.
    ///
    /// Only relevant for user IDs.
    #[error("localpart contains invalid characters")]
    InvalidCharacters,

    /// The key algorithm is invalid (e.g. empty).
    #[error("invalid key algorithm specified")]
    InvalidKeyAlgorithm,

    /// The key version contains outside of [a-zA-Z0-9_].
    #[error("key ID version contains invalid characters")]
    InvalidKeyVersion,

    /// The string isn't a valid Matrix ID.
    #[error("invalid matrix ID: {0}")]
    InvalidMatrixId(#[from] MatrixIdError),

    /// The string isn't a valid Matrix.to URI.
    #[error("invalid matrix.to URI: {0}")]
    InvalidMatrixToRef(#[from] MatrixToError),

    /// The string isn't a valid Matrix URI.
    #[error("invalid matrix URI: {0}")]
    InvalidMatrixUri(#[from] MatrixUriError),

    /// The mxc:// isn't a valid Matrix Content URI.
    #[error("invalid Matrix Content URI: {0}")]
    InvalidMxcUri(#[from] MxcUriError),

    /// The server name part of the the ID string is not a valid server name.
    #[error("server name is not a valid IP address or domain name")]
    InvalidServerName,

    /// The string isn't a valid URI.
    #[error("invalid URI")]
    InvalidUri,

    /// The string isn't valid UTF-8.
    #[error("invalid UTF-8")]
    InvalidUtf8,

    /// The ID exceeds 255 bytes (or 32 codepoints for a room version ID).
    #[error("ID exceeds 255 bytes")]
    MaximumLengthExceeded,

    /// The ID is missing the colon delimiter between localpart and server name, or between key
    /// algorithm and key name / version.
    #[error("required colon is missing")]
    MissingDelimiter,

    /// The ID is missing the correct leading sigil.
    #[error("leading sigil is incorrect or missing")]
    MissingLeadingSigil,
}

impl From<Utf8Error> for Error {
    fn from(_: Utf8Error) -> Self {
        Self::InvalidUtf8
    }
}

impl From<url::ParseError> for Error {
    fn from(_: url::ParseError) -> Self {
        Self::InvalidUri
    }
}

/// An error occurred while validating an MXC URI.
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, thiserror::Error)]
#[non_exhaustive]
pub enum MxcUriError {
    /// MXC URI did not start with `mxc://`.
    #[error("MXC URI schema was not mxc://")]
    WrongSchema,

    /// MXC URI did not have first slash, required for `server.name/media_id`.
    #[error("MXC URI does not have first slash")]
    MissingSlash,

    /// Media identifier malformed due to invalid characters detected.
    ///
    /// Valid characters are (in regex notation) `[A-Za-z0-9_-]+`.
    /// See [here](https://spec.matrix.org/v1.2/client-server-api/#security-considerations-5) for more details.
    #[error("Media Identifier malformed, invalid characters")]
    MediaIdMalformed,

    /// Server identifier malformed: invalid IP or domain name.
    #[error("invalid Server Name")]
    ServerNameMalformed,
}

/// An error occurred while validating a `MatrixId`.
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, thiserror::Error)]
#[non_exhaustive]
pub enum MatrixIdError {
    /// The string contains an invalid number of parts.
    #[error("invalid number of parts")]
    InvalidPartsNumber,

    /// The string is missing a room ID or alias.
    #[error("missing room ID or alias")]
    MissingRoom,

    /// The string contains no identifier.
    #[error("no identifier")]
    NoIdentifier,

    /// The string contains too many identifiers.
    #[error("too many identifiers")]
    TooManyIdentifiers,

    /// The string contains an unknown identifier.
    #[error("unknown identifier")]
    UnknownIdentifier,

    /// The string contains two identifiers that cannot be paired.
    #[error("unknown identifier pair")]
    UnknownIdentifierPair,

    /// The string contains an unknown identifier type.
    #[error("unknown identifier type")]
    UnknownType,
}

/// An error occurred while validating a `matrix.to` URI.
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, thiserror::Error)]
#[non_exhaustive]
pub enum MatrixToError {
    /// String did not start with `https://matrix.to/#/`.
    #[error("base URL is not https://matrix.to/#/")]
    WrongBaseUrl,

    /// String has an unknown additional argument.
    #[error("unknown additional argument")]
    UnknownArgument,
}

/// An error occurred while validating a `MatrixURI`.
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, thiserror::Error)]
#[non_exhaustive]
pub enum MatrixUriError {
    /// The string does not start with `matrix:`.
    #[error("scheme is not 'matrix:'")]
    WrongScheme,

    /// The string contains too many actions.
    #[error("too many actions")]
    TooManyActions,

    /// The string contains an unknown query item.
    #[error("unknown query item")]
    UnknownQueryItem,
}