Skip to content

Commit 572add0

Browse files
committed
Add constant parser.
1 parent f180ebe commit 572add0

File tree

4 files changed

+51
-0
lines changed

4 files changed

+51
-0
lines changed

lib/parser.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ library;
44
export 'src/core/parser.dart';
55
export 'src/parser/action/cast.dart';
66
export 'src/parser/action/cast_list.dart';
7+
export 'src/parser/action/constant.dart';
78
export 'src/parser/action/continuation.dart';
89
export 'src/parser/action/flatten.dart';
910
export 'src/parser/action/map.dart';
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import 'package:meta/meta.dart';
2+
3+
import '../../core/context.dart';
4+
import '../../core/parser.dart';
5+
import '../../core/result.dart';
6+
import '../combinator/delegate.dart';
7+
8+
extension ConstantParserExtension<R> on Parser<R> {
9+
/// Returns a parser that returns a constant value.
10+
///
11+
/// For example, the parser `digit().star().constant(42)` returns the number
12+
/// `42` for whatever input digits it consumes.
13+
@useResult
14+
Parser<S> constant<S>(S value) => ConstantParser<R, S>(this, value);
15+
}
16+
17+
/// A parser that returns a constant value.
18+
class ConstantParser<R, S> extends DelegateParser<R, S> {
19+
ConstantParser(super.delegate, this.value);
20+
21+
final S value;
22+
23+
@override
24+
Result<S> parseOn(Context context) {
25+
final result = delegate.parseOn(context);
26+
if (result is Failure) return result;
27+
return result.success(value);
28+
}
29+
30+
@override
31+
int fastParseOn(String buffer, int position) =>
32+
delegate.fastParseOn(buffer, position);
33+
34+
@override
35+
bool hasEqualProperties(ConstantParser<R, S> other) =>
36+
super.hasEqualProperties(other) && value == other.value;
37+
38+
@override
39+
ConstantParser<R, S> copy() => ConstantParser<R, S>(delegate, value);
40+
}

lib/src/reflection/internal/linter_rules.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import '../../core/parser.dart';
22
import '../../parser/action/cast.dart';
33
import '../../parser/action/cast_list.dart';
4+
import '../../parser/action/constant.dart';
45
import '../../parser/action/flatten.dart';
56
import '../../parser/action/map.dart';
67
import '../../parser/action/permute.dart';
@@ -334,6 +335,7 @@ class UnusedResult extends LinterRule {
334335
bool isResultProducing(Parser parser) =>
335336
parser is CastParser ||
336337
parser is CastListParser ||
338+
parser is ConstantParser ||
337339
parser is FlattenParser ||
338340
(parser is MapParser && !parser.hasSideEffects) ||
339341
parser is PermuteParser ||

test/parser_action_test.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ void main() {
2424
);
2525
});
2626
});
27+
group('constant', () {
28+
final parser = digit().constant(42);
29+
expectParserInvariants(parser);
30+
test('default', () {
31+
expect(parser, isParseSuccess('1', result: 42));
32+
expect(parser, isParseFailure('a', message: 'digit expected'));
33+
});
34+
});
2735
group('continuation', () {
2836
expectParserInvariants(
2937
any().callCC<String>((continuation, context) => continuation(context)),

0 commit comments

Comments
 (0)