Skip to content

Commit

Permalink
Migrate to petitparser (#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
f3ath authored Jan 8, 2021
1 parent 4f4603a commit 79970d0
Show file tree
Hide file tree
Showing 52 changed files with 940 additions and 1,154 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/dart.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

jobs:
build:
Expand All @@ -16,6 +15,10 @@ jobs:

steps:
- uses: actions/checkout@v2
- name: Update submodules
run: git submodule update --init --recursive
- name: Print Dart version
run: dart --version
- name: Install dependencies
run: dart pub get
- name: Format
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "cts"]
path = cts
url = https://github.com/jsonpath-standard/jsonpath-compliance-test-suite.git
12 changes: 11 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
## [Unreleased]
### Added
- `JsonPathMatch.context` contains the matching context. It is intended to be used in named filters.
- `JsonPathMatch.parent` contains the parent match.
- `JsonPathMatch.pointer` contains the RFC 6901 JSON Pointer to the match.

### Changed
- Prepared for null safety
- Named filters argument renamed from `filter` to `filters`
- Named filters can now be passed to the `read()` method.
- Named filters callback now accepts the entire `JsonPathMatch` object, not just the value.

### Removed
- The `set()` method. The intention is to allow modifications via JSON Pointer in the future.

## [0.2.0] - 2020-09-07
### Added
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2020 The Конь
Copyright (c) 2020-2021 Alexey Karapetov

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
56 changes: 5 additions & 51 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,66 +58,20 @@ void main() {
/// $['store']['bicycle']['price']: 19.95
prices
.read(json)
.map((result) => '${result.path}:\t${result.value}')
.map((match) => '${match.path}:\t${match.value}')
.forEach(print);
print('\n');
final bikeColor = JsonPath(r'$.store.bicycle.color');
print('A copy of the store with repainted bike:');
print(bikeColor.set(json, 'blue'));
print('\n');
print('Note, that the bike in the original store is still red:');
bikeColor
.read(json)
.map((result) => '${result.path}:\t${result.value}')
.forEach(print);
print('\n');
print('It is also possible to modify json in place:');
final someBooks = JsonPath(r'$.store.book[::2]');
someBooks.read(json).forEach((match) {
result.value['title'] = 'Banana';
});
print(json);
}
```

## Features and limitations
Generally, this library tries to mimic the [reference implementations], except for the filtering.
Evaluated expressions are not supported, use named filters instead (see below).
### Fields and indices
Both dot-notation (`$.store.book[0].title`) and bracket-notation (`$['store']['book'][2]['title']`) are supported.

- The dot-notation only recognizes alphanumeric fields starting with a letter. Use bracket-notation for general cases.
- The bracket-notation supports only single quotes.

### Wildcards
Wildcards (`*`) can be used for objects (`$.store.*`) and arrays (`$.store.book[*]`);

### Recursion
Use `..` to iterate all elements recursively. E.g. `$.store..price` matches all prices in the store.

### Array slice
Use `[start:end:step]` to filter arrays. Any index can be omitted E.g. `$.store.book[3::2]` selects all even books
starting from the 4th. Negative `start` and `end` are also supported.

### Unions
Array (`book[0,1]`) and object (`book[author,title,price]`) unions are supported. Array unions are always sorted.
Object unions support the bracket-notation.

### Filtering
Due to the nature of Dart language, filtering expressions like `$..book[?(@.price<10)]` are NOT supported.
Evaluated filtering expressions like `$..book[?(@.price<10)]` are NOT yet supported.
Instead, use the callback-kind of filters.
```dart
/// Select all elements with price under 20
JsonPath(r'$.store..[?discounted]', filter: {
'discounted': (e) => e is Map && e['price'] is num && e['price'] < 20
final path = JsonPath(r'$.store..[?discounted]', filters: {
'discounted': (match) =>
match.value is Map && match.value['price'] is num && match.value['price'] < 20
});
```

Expand Down
1 change: 1 addition & 0 deletions cts
Submodule cts added at ab56e4
25 changes: 0 additions & 25 deletions example/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -57,29 +57,4 @@ void main() {
.read(json)
.map((match) => '${match.path}:\t${match.value}')
.forEach(print);

print('\n');

final bikeColor = JsonPath(r'$.store.bicycle.color');

print('A copy of the store with repainted bike:');
print(bikeColor.set(json, 'blue'));

print('\n');

print('Note, that the bike in the original store is still red:');
bikeColor
.read(json)
.map((result) => '${result.path}:\t${result.value}')
.forEach(print);

print('\n');

print('It is also possible to modify json in place '
'as long as the matching value is an object or a list:');
final someBooks = JsonPath(r'$.store.book[::2]');
someBooks.read(json).forEach((match) {
match.value['title'] = 'Banana';
});
print(json);
}
4 changes: 3 additions & 1 deletion lib/json_path.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/// JSONPath for Dart
library json_path;

export 'package:json_path/json_pointer.dart';
export 'package:json_path/src/filter_not_found.dart';
export 'package:json_path/src/json_path.dart';
export 'package:json_path/src/json_path_match.dart';
export 'package:json_path/src/predicate.dart';
export 'package:json_path/src/matching_context.dart';
18 changes: 18 additions & 0 deletions lib/json_pointer.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/// JSON Pointer (RFC 6901).
class JsonPointer {
/// Creates a pointer to the root element
const JsonPointer() : value = '';

JsonPointer._(this.value);

/// The string value of the pointer
final String value;

/// Returns a new instance of [JsonPointer]
/// with the [segment] appended at the end.
JsonPointer append(String segment) => JsonPointer._(
value + '/' + segment.replaceAll('~', '~0').replaceAll('/', '~1'));

@override
String toString() => value;
}
30 changes: 30 additions & 0 deletions lib/src/any_match.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import 'package:json_path/json_pointer.dart';
import 'package:json_path/src/json_path_match.dart';
import 'package:json_path/src/matching_context.dart';

class AnyMatch<T> implements JsonPathMatch<T> {
const AnyMatch(
{required this.value,
required this.path,
required this.pointer,
required this.context,
this.parent});

/// The value
@override
final T value;

/// JSONPath to this match
@override
final String path;

/// JSON Pointer (RFC 6901) to this match
@override
final JsonPointer pointer;

@override
final MatchingContext context;

@override
final JsonPathMatch? parent;
}
25 changes: 0 additions & 25 deletions lib/src/ast/ast.dart

This file was deleted.

19 changes: 0 additions & 19 deletions lib/src/ast/node.dart

This file was deleted.

17 changes: 0 additions & 17 deletions lib/src/ast/tokenize.dart

This file was deleted.

7 changes: 7 additions & 0 deletions lib/src/build_parser.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import 'package:json_path/src/grammar.dart';
import 'package:json_path/src/selector/selector.dart';
import 'package:petitparser/core.dart';

Parser<Selector> buildParser() {
return jsonPath;
}
8 changes: 8 additions & 0 deletions lib/src/filter_not_found.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class FilterNotFound implements Exception {
FilterNotFound(this.message);

final String message;

@override
String toString() => message;
}
Loading

0 comments on commit 79970d0

Please sign in to comment.