platform/packages/combinator/example/basic_auth.dart

56 lines
1.7 KiB
Dart
Raw Normal View History

2021-03-17 23:04:36 +00:00
// Run this with "Basic QWxhZGRpbjpPcGVuU2VzYW1l"
import 'dart:convert';
import 'dart:io';
import 'package:combinator/combinator.dart';
import 'package:string_scanner/string_scanner.dart';
/// Parse a part of a decoded Basic auth string.
///
/// Namely, the `username` or `password` in `{username}:{password}`.
final Parser<String> string =
match<String>(new RegExp(r'[^:$]+'), errorMessage: 'Expected a string.')
2021-03-18 00:00:56 +00:00
.value((r) => r.span!.text);
2021-03-17 23:04:36 +00:00
/// Transforms `{username}:{password}` to `{"username": username, "password": password}`.
final Parser<Map<String, String>> credentials = chain<String>([
string.opt(),
match<String>(':'),
string.opt(),
]).map<Map<String, String>>(
2021-03-18 00:00:56 +00:00
(r) => {'username': r.value![0], 'password': r.value![2]});
2021-03-17 23:04:36 +00:00
/// We can actually embed a parser within another parser.
///
/// This is used here to BASE64URL-decode a string, and then
/// parse the decoded string.
2021-03-18 00:00:56 +00:00
final Parser credentialString = match<Map<String, String>?>(
2021-03-17 23:04:36 +00:00
new RegExp(r'([^\n$]+)'),
errorMessage: 'Expected a credential string.')
.value((r) {
2021-03-18 00:00:56 +00:00
var decoded = utf8.decode(base64Url.decode(r.span!.text));
2021-03-17 23:04:36 +00:00
var scanner = new SpanScanner(decoded);
2021-03-18 00:00:56 +00:00
return credentials.parse(scanner)!.value;
2021-03-17 23:04:36 +00:00
});
final Parser basic = match<Null>('Basic').space();
final Parser basicAuth = basic.then(credentialString).index(1);
void main() {
while (true) {
stdout.write('Enter a basic auth value: ');
2021-03-18 00:00:56 +00:00
var line = stdin.readLineSync()!;
2021-03-17 23:04:36 +00:00
var scanner = new SpanScanner(line, sourceUrl: 'stdin');
2021-03-18 00:00:56 +00:00
var result = basicAuth.parse(scanner)!;
2021-03-17 23:04:36 +00:00
if (!result.successful) {
for (var error in result.errors) {
print(error.toolString);
2021-03-18 00:00:56 +00:00
print(error.span!.highlight(color: true));
2021-03-17 23:04:36 +00:00
}
} else
print(result.value);
}
}