blob: b045bcc32aee1373e2e033f19db242e6d203e58f [file] [log] [blame]
import 'package:meta/meta.dart';
import '../../context/context.dart';
import '../../context/result.dart';
import '../../core/parser.dart';
import '../combinator/delegate.dart';
extension PickParserExtension<R> on Parser<List<R>> {
/// Returns a parser that transforms a successful parse result by returning
/// the element at [index] of a list. A negative index can be used to access
/// the elements from the back of the list.
///
/// For example, the parser `letter().star().pick(-1)` returns the last
/// letter parsed. For the input `'abc'` it returns `'c'`.
@useResult
Parser<R> pick(int index) => PickParser<R>(this, index);
}
/// A parser that performs a transformation with a given function on the
/// successful parse result of the delegate.
class PickParser<R> extends DelegateParser<List<R>, R> {
PickParser(super.delegate, this.index);
/// Indicates which element to return from the parsed list.
final int index;
@override
Result<R> parseOn(Context context) {
final result = delegate.parseOn(context);
if (result.isSuccess) {
final value = result.value;
final picked = value[index < 0 ? value.length + index : index];
return result.success(picked);
} else {
return result.failure(result.message);
}
}
@override
int fastParseOn(String buffer, int position) =>
delegate.fastParseOn(buffer, position);
@override
PickParser<R> copy() => PickParser<R>(delegate, index);
@override
bool hasEqualProperties(PickParser<R> other) =>
super.hasEqualProperties(other) && index == other.index;
}