parseDeepLink function
SdkResult<DeepLinkCommand>
parseDeepLink(
- Uri uri,
- List<
DeepLinkRoute> routes, { - int maxLength = 2048,
Pure parser — no I/O, no singletons — matches uri against routes in
order, first match wins. Rejects (never throws) on: a URI longer than
maxLength (guards against an oversized query string), a scheme/host
not in any route, or a path that doesn't match any route's shape.
Implementation
SdkResult<DeepLinkCommand> parseDeepLink(
Uri uri,
List<DeepLinkRoute> routes, {
int maxLength = 2048,
}) {
if (uri.toString().length > maxLength) {
return const SdkFailure(
kind: SdkErrorKind.validation,
message: 'Deep link exceeds max length',
);
}
for (final route in routes) {
if (route.scheme != uri.scheme) continue;
if (route.host != null && route.host != uri.host) continue;
final segments = uri.pathSegments;
if (segments.length != route.pathSegments.length) continue;
final params = <String, String>{};
var matched = true;
for (var i = 0; i < segments.length; i++) {
final pattern = route.pathSegments[i];
if (pattern.startsWith(':')) {
params[pattern.substring(1)] = segments[i];
} else if (pattern != segments[i]) {
matched = false;
break;
}
}
if (!matched) continue;
// BUG-50: query params must never override a path param of the same
// name (see the class doc comment above) — `putIfAbsent`, not `addAll`.
uri.queryParameters.forEach((k, v) => params.putIfAbsent(k, () => v));
return SdkSuccess(
DeepLinkCommand(type: route.commandType, params: params, raw: uri),
);
}
return SdkFailure(
kind: SdkErrorKind.validation,
message: 'No route matches $uri',
);
}