findPossibleRoutes method
Rates all route handlers for given query and possible subroutes
More matches for query params -> bigger rate value
Implementation
Map<String, int> findPossibleRoutes(
Map<String, List<String>> query,
String fragment,
Map possibleSubroutes,
) {
final decisionSubroutes = <String, int>{};
if (query.isEmpty) {
return decisionSubroutes;
}
final suggestions = possibleSubroutes.keys.map((element) {
final subroute = element as String;
if (!subroute.contains('|')) {
for (final queryParam in query.entries) {
if (_checkSubroute(subroute, queryParam.key, queryParam.value)) {
return MapEntry(subroute, 1);
}
}
return MapEntry(subroute, 0);
}
var canBeSelectedQueryParams = 0;
final alreadyChecked = <String>[];
final rules = subroute.split('|');
for (final rule in rules) {
var queryCheckResult = 0;
if (rule.startsWith('#')) {
final ruleKey = rule.split('=')[0];
if (alreadyChecked.contains(ruleKey)) {
continue;
}
final requiredRules = rules.where(
(element) => element.contains('$ruleKey='),
);
var ruleIsSatisfied = false;
for (final requiredRule in requiredRules) {
if (requiredRule.substring(2) == fragment) {
ruleIsSatisfied = true;
break;
}
}
if (!ruleIsSatisfied) {
canBeSelectedQueryParams = 0;
break;
} else {
canBeSelectedQueryParams++;
alreadyChecked.add(ruleKey);
}
} else if (rule.contains('=')) {
final ruleKey = rule.split('=')[0];
if (alreadyChecked.contains(ruleKey)) {
continue;
}
final requiredRules = rules.where(
(element) => element.contains('$ruleKey='),
);
var ruleIsSatisfied = false;
for (final requiredRule in requiredRules) {
if (query.entries.where((element) {
final formattedQuery = element.value.length != 1
? '${element.key}=${element.value}'
: '${element.key}=${element.value[0]}';
return requiredRule == formattedQuery;
}).isNotEmpty) {
ruleIsSatisfied = true;
break;
}
}
if (!ruleIsSatisfied) {
canBeSelectedQueryParams = 0;
break;
} else {
canBeSelectedQueryParams++;
alreadyChecked.add(ruleKey);
}
} else {
for (final queryParam in query.entries) {
if (alreadyChecked.contains(queryParam.key)) {
continue;
}
final routeCheckResult = _checkSubroute(
rule,
queryParam.key,
queryParam.value,
);
if (routeCheckResult) {
queryCheckResult++;
canBeSelectedQueryParams++;
alreadyChecked.add(queryParam.key);
}
}
if (queryCheckResult == 0 && !rule.contains('?')) {
canBeSelectedQueryParams = 0;
break;
}
}
queryCheckResult = 0;
}
return MapEntry(subroute, canBeSelectedQueryParams);
});
for (final element in suggestions) {
decisionSubroutes[element.key] = element.value;
}
return decisionSubroutes;
}