decodePathMap function

Map<String, String> decodePathMap({
  1. required String path,
  2. required String template,
})

Decode the path map values from the given path, based on the provided template.

For example, the path /devices/DEVICE123/equipment/EQUIP123 and the given template /devices/:deviceId/equipment/:equipId will be decode to the path map { deviceId: DEVICE123, equipId: EQUIP123}.

Throws a FormatException if the path and template do not match.

Implementation

Map<String, String> decodePathMap({
  required String path,
  required String template,
}) {
  Iterable<String> segmentsOf(String uri) {
    return Uri.parse(uri).pathSegments.where((segment) => segment.isNotEmpty);
  }

  final pathSegments = segmentsOf(path);
  final templateSegments = segmentsOf(template);

  if (pathSegments.length != templateSegments.length) {
    throw FormatException(
      'The path \'$path\' and template \'$template\' '
      'segments are different lengths',
    );
  }

  MapEntry<String, String> toPathMap(
    String pathSegment,
    String templateSegment,
  ) {
    if (pathSegment == templateSegment) {
      return const MapEntry('', '');
    } else {
      final match = _kMapPattern.firstMatch(templateSegment);
      if (match == null) {
        throw const FormatException(
          'The path and template segments do not match.',
        );
      }
      return MapEntry(match[1]!, pathSegment);
    }
  }

  return Map.fromIterables(pathSegments, templateSegments).map(toPathMap)
    ..removeWhere((key, value) => key.isEmpty || value.isEmpty);
}