toSpecSelector method

Selector toSpecSelector()

Best-effort conversion to the official Selector vocabulary.

This is provided for backward compatibility with the legacy IPLDSelector API. Complex criteria and intersection semantics are approximated or dropped.

Implementation

Selector toSpecSelector() {
  switch (type) {
    case SelectorType.all:
      // Match every visited node while recursing across the whole DAG.
      return ExploreRecursive(
        limit: const RecursionLimitNone(),
        sequence: ExploreUnion(
          members: [
            const Matcher(),
            const ExploreAll(next: ExploreRecursiveEdge()),
          ],
        ),
      );
    case SelectorType.none:
      return ExploreFields(fields: <String, Selector>{});
    case SelectorType.matcher:
      return const Matcher();
    case SelectorType.recursive:
      final sub =
          subSelectors?.firstOrNull?.toSpecSelector() ?? const Matcher();
      return ExploreRecursive(
        limit: DepthRecursionLimit(maxDepth ?? defaultSelectorMaxDepth),
        sequence: ExploreUnion(
          members: [
            sub,
            const ExploreAll(next: ExploreRecursiveEdge()),
          ],
        ),
      );
    case SelectorType.union:
      return ExploreUnion(
        members:
            subSelectors?.map((s) => s.toSpecSelector()).toList() ?? const [],
      );
    case SelectorType.intersection:
      // Intersection is not part of the official vocabulary; approximate
      // with the first member.
      return subSelectors?.firstOrNull?.toSpecSelector() ?? const Matcher();
    case SelectorType.explore:
      final sub =
          subSelectors?.firstOrNull?.toSpecSelector() ?? const Matcher();
      final segments = (fieldPath ?? '')
          .split('/')
          .where((s) => s.isNotEmpty)
          .toList();
      if (segments.isEmpty) return sub;
      Selector current = sub;
      for (var i = segments.length - 1; i >= 0; i--) {
        final segment = segments[i];
        final index = int.tryParse(segment);
        if (index != null) {
          current = ExploreIndex(index: index, next: current);
        } else {
          current = ExploreFields(fields: {segment: current});
        }
      }
      return current;
  }
}