toSpecSelector method
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;
}
}