You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
105 lines
3.1 KiB
105 lines
3.1 KiB
import 'dart:convert'; |
|
import 'dart:io'; |
|
|
|
import 'package:args/args.dart'; |
|
import 'package:json_path/json_path.dart'; |
|
import 'package:rfc_6901/rfc_6901.dart'; |
|
|
|
import 'ppjson.dart'; |
|
|
|
void main(List<String> arguments) { |
|
final parser = ArgParser() |
|
..addOption('file', abbr: 'f', help: 'Read JSON from file instead of stdin', valueHelp: 'filename') |
|
..addOption('input', help: 'Read JSON as parameter instead of stdin', valueHelp: 'json input') |
|
..addOption('jsonpath', aliases: ['path'], help: 'Display only the matches of the JSON path', valueHelp: 'JSONPath query') |
|
..addOption('jsonpointer', aliases: ['pointer'], abbr: 'p', help: 'Display only the matches of the JSON pointer', valueHelp: 'JSON Pointer') |
|
..addOption('indent', abbr: 'i', help: 'Set space indentation level (prefix with t for tab indentation)', defaultsTo: '2') |
|
..addOption('max-depth', abbr: 'd', help: 'Specify maximum nesting before stopping printing'); |
|
// ..addFlag('force-color', help: "Output using colors even when the environment doesn't allow them", hide: true); |
|
final ArgResults parsedArgs; |
|
try { |
|
parsedArgs = parser.parse(arguments); |
|
} |
|
on ArgParserException catch(e) { |
|
print(e.message); |
|
print(''); |
|
print(parser.usage); |
|
exit(1); |
|
} |
|
|
|
// Get indent |
|
final indentArg = parsedArgs['indent'] as String; |
|
final indent = indentArg[0] == 't' ? '\t' * int.parse(indentArg.substring(1)) : ' ' * int.parse(indentArg); |
|
|
|
// Get max depth |
|
final maxDepthArg = parsedArgs['max-depth'] as String?; |
|
final maxDepth = int.tryParse(maxDepthArg ?? ''); |
|
|
|
// Get JSONPath |
|
final jsonPath = parsedArgs['jsonpath'] as String?; |
|
|
|
// Get JSON Pointer |
|
final jsonPointer = parsedArgs['jsonpointer'] as String?; |
|
|
|
// Read |
|
String jsonInput; |
|
if (parsedArgs['file'] != null) { |
|
jsonInput = File(parsedArgs['file']).readAsStringSync(); |
|
} |
|
else if (parsedArgs['input'] != null) { |
|
jsonInput = parsedArgs['input']; |
|
} |
|
else { |
|
jsonInput = ''; |
|
while (true) { |
|
final line = stdin.readLineSync(retainNewlines: true); |
|
if (line != null) { |
|
jsonInput += line; |
|
} |
|
else { |
|
break; |
|
} |
|
} |
|
} |
|
|
|
// Parse |
|
final decodedData; |
|
try { |
|
decodedData = jsonDecode(jsonInput); |
|
} |
|
catch(_) { |
|
stderr.writeln('Unable to parse JSON input.'); |
|
exit(1); |
|
} |
|
final List<dynamic> data; |
|
try { |
|
data = jsonPath != null ? followJsonPath(decodedData, jsonPath) : jsonPointer != null ? followJsonPointer(decodedData, jsonPointer) : [decodedData]; |
|
} |
|
catch (e) { |
|
stderr.writeln('JSONPath Error: $e'); |
|
exit(1); |
|
} |
|
|
|
// Print |
|
if (data.isEmpty) { |
|
stderr.writeln('No match'); |
|
} |
|
else if (data.length == 1) { |
|
stdout.write(prettyPrintJson(data[0], indent, maxDepth)); |
|
} |
|
else { |
|
for (final match in data) { |
|
print(prettyPrintJson(match, indent, maxDepth)); |
|
} |
|
} |
|
} |
|
|
|
List<dynamic> followJsonPath(dynamic object, String jsonPath) { |
|
final path = JsonPath(jsonPath); |
|
return path.read(object).map((e) => e.value).toList(growable: false); |
|
} |
|
|
|
List<dynamic> followJsonPointer(dynamic object, String jsonPointer) { |
|
final pointer = JsonPointer(jsonPointer); |
|
return [pointer.read(object)]; |
|
}
|
|
|