feat: Implement flexible args parsing

This commit is contained in:
NaiJi ✨ 2023-01-31 10:40:30 +04:00
parent d0291e90a1
commit dea3f1bd67
3 changed files with 137 additions and 5 deletions

View File

@ -2,15 +2,14 @@ import 'dart:core';
import 'package:funkblubber/funkblubber.dart' as funkblubber; import 'package:funkblubber/funkblubber.dart' as funkblubber;
import 'package:funkblubber/console.dart' as console; import 'package:funkblubber/console.dart' as console;
import 'package:funkblubber/funkentity.dart'; import 'package:funkblubber/parsing/parser.dart' as parser;
import 'package:funkblubber/parser.dart' as parser;
void main(final List<String> arguments) async { void main(final List<String> arguments) async {
final object = parser.extract(arguments); final result = parser.extract(arguments);
if (object.kind == FunkEntity.error) { if (!result.success) {
console.error("'funkblubber --help 'for more"); console.error("'funkblubber --help 'for more");
return; return;
} }
await funkblubber.download(object: object); await funkblubber.download(object: result.object!);
} }

125
lib/parsing/parser.dart Normal file
View File

@ -0,0 +1,125 @@
import 'package:funkblubber/funkentity.dart';
import 'package:funkblubber/console.dart' as console;
import 'package:funkblubber/parsing/parsing_stage.dart';
enum Action {
download,
upload,
}
class StageResult {
StageResult({required this.result, required this.stage});
final ParseResult result;
final ParsingStage stage;
}
class ParseResult {
ParseResult({
required this.success,
required this.action,
this.object,
this.localPath,
});
final FunkObject? object;
final String? localPath;
final Action action;
final bool success;
}
ParseResult extract(final List<String> args) {
ParseResult result = ParseResult(
success: false,
action: Action.download,
);
if (args.isEmpty) {
console.error('no arguments provided');
return result;
}
ParsingStage currentStage = ParsingStage.nothing;
for (final String arg in args) {
switch (currentStage) {
case ParsingStage.nothing:
final stageResult = _onNothingStage(arg, result, currentStage);
currentStage = stageResult.stage;
result = stageResult.result;
break;
default:
console.error('not implemented yet');
break;
}
}
return result;
}
StageResult _onNothingStage(
final String arg,
final ParseResult previousResult,
final ParsingStage previousStage,
) {
ParsingStage currentStage = previousStage;
ParseResult result = previousResult;
switch (arg) {
case '-A':
case '--artist':
currentStage = ParsingStage.artist;
break;
case '-a':
case '--album':
currentStage = ParsingStage.album;
break;
case '-u':
case '--upload':
currentStage = ParsingStage.upload;
break;
case '-p':
case '--path':
currentStage = ParsingStage.path;
break;
default:
try {
final Uri uri = Uri.parse(arg);
final segments = uri.pathSegments;
for (int i = 0; i < segments.length; ++i) {
switch (segments[i]) {
case 'artists':
result = ParseResult(
action: Action.download,
success: true,
object: FunkObject(
kind: FunkEntity.artist,
id: segments[i + 1],
domain: uri.host,
),
);
++i;
break;
case 'albums':
result = ParseResult(
action: Action.download,
success: true,
object: FunkObject(
kind: FunkEntity.album,
id: segments[i + 1],
domain: uri.host,
),
);
++i;
break;
}
}
} catch (e) {
console.error(e.toString());
currentStage = ParsingStage.nothing;
}
break;
}
return StageResult(result: result, stage: currentStage);
}

View File

@ -0,0 +1,8 @@
enum ParsingStage {
nothing,
album,
artist,
song,
path,
upload,
}