refactor: parseIdentifierIntoParts
This commit is contained in:
parent
7fce5b6040
commit
fb0ea2efc3
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
if (identifiers.isEmpty) {
|
return uri.replace(pathSegments: identifiers);
|
||||||
return null;
|
} else if (toLowerCase().startsWith(matrixToPrefix)) {
|
||||||
}
|
return Uri.tryParse('//' +
|
||||||
return MatrixIdentifierStringExtensionResults(
|
substring(matrixToPrefix.length - 1)
|
||||||
primaryIdentifier: identifiers.first,
|
.replaceAllMapped(
|
||||||
secondaryIdentifier: identifiers.length > 1 ? identifiers[1] : null,
|
RegExp(r'(?<=/)[#!@+][^:]*:|(\?.*$)'),
|
||||||
queryString: uri.query.isNotEmpty ? uri.query : null,
|
(m) => m.group(0).replaceAllMapped(
|
||||||
via: (uri.queryParametersAll['via'] ?? []).toSet(),
|
RegExp(m.group(1) != null ? '' : '[/?]'),
|
||||||
action: uri.queryParameters['action'],
|
(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));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Separate a matrix identifier string into a primary indentifier, a secondary identifier,
|
||||||
|
/// a query string and already parsed `via` parameters. A matrix identifier string
|
||||||
|
/// can be an mxid, a matrix.to-url or a matrix-uri.
|
||||||
|
MatrixIdentifierStringExtensionResults parseIdentifierIntoParts() {
|
||||||
|
final uri = _parseIdentifierIntoUri();
|
||||||
|
if (uri == null) return null;
|
||||||
|
final primary = uri.pathSegments.isNotEmpty ? uri.pathSegments[0] : null;
|
||||||
|
if (primary == null || !primary.isValidMatrixId) return null;
|
||||||
|
final secondary = uri.pathSegments.length > 1 ? uri.pathSegments[1] : null;
|
||||||
|
if (secondary != null && !secondary.isValidMatrixId) return null;
|
||||||
|
|
||||||
const matrixToPrefix = 'https://matrix.to/#/';
|
|
||||||
// matrix identifiers and matrix.to URLs are parsed similarly, so we do them here
|
|
||||||
var s = this;
|
|
||||||
if (toLowerCase().startsWith(matrixToPrefix)) {
|
|
||||||
// as we decode a component we may only call it on the url part *before* the "query" part
|
|
||||||
final parts = substring(matrixToPrefix.length).split('?');
|
|
||||||
var ident = parts.removeAt(0);
|
|
||||||
try {
|
|
||||||
ident = Uri.decodeComponent(ident);
|
|
||||||
} catch (_) {
|
|
||||||
// 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'],
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue