blob: 5628aed3df7ea1f93479bea414c1c54f2185ba1b [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 FlattenParserExtension<R> on Parser<R> {
/// Returns a parser that discards the result of the receiver and answers
/// the sub-string its delegate consumes.
///
/// If a [message] is provided, the flatten parser can switch to a fast mode
/// where error tracking within the receiver is suppressed and in case of a
/// problem [message] is reported instead.
///
/// For example, the parser `letter().plus().flatten()` returns `'abc'`
/// for the input `'abc'`. In contrast, the parser `letter().plus()` would
/// return `['a', 'b', 'c']` for the same input instead.
@useResult
Parser<String> flatten([String? message]) => FlattenParser<R>(this, message);
}
/// A parser that discards the result of the delegate and answers the
/// sub-string its delegate consumes.
class FlattenParser<R> extends DelegateParser<R, String> {
FlattenParser(super.delegate, [this.message]);
/// Error message to indicate parse failures with.
final String? message;
@override
Result<String> parseOn(Context context) {
// If we have a message we can switch to fast mode.
if (message != null) {
final position = delegate.fastParseOn(context.buffer, context.position);
if (position < 0) {
return context.failure(message!);
}
final output = context.buffer.substring(context.position, position);
return context.success(output, position);
} else {
final result = delegate.parseOn(context);
if (result.isSuccess) {
final output =
context.buffer.substring(context.position, result.position);
return result.success(output);
}
return result.failure(result.message);
}
}
@override
int fastParseOn(String buffer, int position) =>
delegate.fastParseOn(buffer, position);
@override
bool hasEqualProperties(FlattenParser<R> other) =>
super.hasEqualProperties(other) && message == other.message;
@override
FlattenParser<R> copy() => FlattenParser<R>(delegate, message);
}