refactor: parseIdentifierIntoParts

This commit is contained in:
Lukas Lihotzki 2021-09-23 13:15:24 +02:00 committed by Krille Fear
parent 7fce5b6040
commit fb0ea2efc3
1 changed files with 39 additions and 49 deletions

View File

@ -58,18 +58,14 @@ extension MatrixIdExtension on String {
bool equals(String other) => toLowerCase() == other?.toLowerCase(); bool equals(String other) => toLowerCase() == other?.toLowerCase();
/// Separate a matrix identifier string into a primary indentifier, a secondary identifier, /// Parse a matrix identifier string into a Uri. Primary and secondary identifiers
/// a query string and already parsed `via` parameters. A matrix identifier string /// are stored in pathSegments. The query string is stored as such.
/// can be an mxid, a matrix.to-url or a matrix-uri. Uri _parseIdentifierIntoUri() {
MatrixIdentifierStringExtensionResults parseIdentifierIntoParts() {
const matrixUriPrefix = 'matrix:'; const matrixUriPrefix = 'matrix:';
const matrixToPrefix = 'https://matrix.to/#/';
// check if we have a "matrix:" uri
if (toLowerCase().startsWith(matrixUriPrefix)) { if (toLowerCase().startsWith(matrixUriPrefix)) {
final uri = Uri.tryParse(this); final uri = Uri.tryParse(this);
if (uri == null) { if (uri == null) return null;
return null;
}
final pathSegments = uri.pathSegments; final pathSegments = uri.pathSegments;
final identifiers = <String>[]; final identifiers = <String>[];
for (var i = 0; i < pathSegments.length - 1; i += 2) { for (var i = 0; i < pathSegments.length - 1; i += 2) {
@ -82,50 +78,44 @@ extension MatrixIdExtension on String {
if (thisSigil == null) { if (thisSigil == null) {
break; break;
} }
final identifier = thisSigil + pathSegments[i + 1]; identifiers.add(thisSigil + pathSegments[i + 1]);
if (!identifier.isValidMatrixId) {
return null;
} }
identifiers.add(identifier); return uri.replace(pathSegments: identifiers);
} else if (toLowerCase().startsWith(matrixToPrefix)) {
return Uri.tryParse('//' +
substring(matrixToPrefix.length - 1)
.replaceAllMapped(
RegExp(r'(?<=/)[#!@+][^:]*:|(\?.*$)'),
(m) => m.group(0).replaceAllMapped(
RegExp(m.group(1) != null ? '' : '[/?]'),
(m) => Uri.encodeComponent(m.group(0))))
.replaceAll('#', '%23'));
} else {
final match =
RegExp(r'^([#!@+][^:]*:[^\/?]*)(?:\/(\$[^?]*))?(?:\?(.*))?$')
.firstMatch(this);
if (match == null) return null;
return Uri(
pathSegments:
[match.group(1), match.group(2)].where((x) => x != null),
query: match.group(3));
} }
if (identifiers.isEmpty) {
return null;
}
return MatrixIdentifierStringExtensionResults(
primaryIdentifier: identifiers.first,
secondaryIdentifier: identifiers.length > 1 ? identifiers[1] : null,
queryString: uri.query.isNotEmpty ? uri.query : null,
via: (uri.queryParametersAll['via'] ?? []).toSet(),
action: uri.queryParameters['action'],
);
} }
const matrixToPrefix = 'https://matrix.to/#/'; /// Separate a matrix identifier string into a primary indentifier, a secondary identifier,
// matrix identifiers and matrix.to URLs are parsed similarly, so we do them here /// a query string and already parsed `via` parameters. A matrix identifier string
var s = this; /// can be an mxid, a matrix.to-url or a matrix-uri.
if (toLowerCase().startsWith(matrixToPrefix)) { MatrixIdentifierStringExtensionResults parseIdentifierIntoParts() {
// as we decode a component we may only call it on the url part *before* the "query" part final uri = _parseIdentifierIntoUri();
final parts = substring(matrixToPrefix.length).split('?'); if (uri == null) return null;
var ident = parts.removeAt(0); final primary = uri.pathSegments.isNotEmpty ? uri.pathSegments[0] : null;
try { if (primary == null || !primary.isValidMatrixId) return null;
ident = Uri.decodeComponent(ident); final secondary = uri.pathSegments.length > 1 ? uri.pathSegments[1] : null;
} catch (_) { if (secondary != null && !secondary.isValidMatrixId) return null;
// do nothing: the identifier wasn't url-encoded, and we already have the
// plaintext version in the `ident` variable
}
s = ident + '?' + parts.join('?');
}
final match = RegExp(r'^([#!@+][^:]*:[^\/?]*)(?:\/(\$[^?]*))?(?:\?(.*))?$')
.firstMatch(s);
if (match == null ||
!match.group(1).isValidMatrixId ||
!(match.group(2)?.isValidMatrixId ?? true)) {
return null;
}
final uri = Uri(query: match.group(3));
return MatrixIdentifierStringExtensionResults( return MatrixIdentifierStringExtensionResults(
primaryIdentifier: match.group(1), primaryIdentifier: primary,
secondaryIdentifier: match.group(2), secondaryIdentifier: secondary,
queryString: uri.query.isNotEmpty ? uri.query : null, queryString: uri.query.isNotEmpty ? uri.query : null,
via: (uri.queryParametersAll['via'] ?? []).toSet(), via: (uri.queryParametersAll['via'] ?? []).toSet(),
action: uri.queryParameters['action'], action: uri.queryParameters['action'],