Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 28 additions & 7 deletions docs/corelang.dj
Original file line number Diff line number Diff line change
Expand Up @@ -437,17 +437,38 @@ For example:

### Compound paths

For each of the filters in this section,
you can employ any atomic filter instead of the leading `.` (identity).
For example, you can write `explode[]` as short form for `explode | .[]`.

You can also terminate any filter in this section with a `?`,
You can concatenate arbitrarily many path operators to an atomic filter.
Such a sequence of path operators is called a _compound path_.
For example, you can write
`explode.[]` as short form for `explode | .[]`.

If the leading atomic filter is `.` (identity), you can omit it.
For example, the following filters are all equivalent:

- `{a: [{b: 1}]} | . | .a | .[] | .b --> 1`
- `{a: [{b: 1}]} | . .a .[] .b --> 1`
- `{a: [{b: 1}]} | .a .[] .b --> 1`
- `{a: [{b: 1}]} .a .[] .b --> 1`

You can omit the leading `.` of path operators that have the shape `.[...]`,
unless the path operator is the head of the compound path and
the leading atomic filter `.` has been omitted.
For example, the following filters are all equivalent:

- `[[[1, 2, 3]]] | .[0] | .[] | .[:-1] --> [1, 2]`
- `[[[1, 2, 3]]] | .[0] .[] .[:-1] --> [1, 2]`
- `[[[1, 2, 3]]] | .[0] [] [:-1] --> [1, 2]`
- `[[[1, 2, 3]]] [0] [] [:-1] --> [1, 2]`

You can also terminate any path operator in this section with a `?`,
which silences errors from that operator.
For example, `.[]` yields an error if the input is neither an array nor an object,
but `.[]?` silences such errors, yielding no output instead.
Examples:

You can chain together an arbitrary number of these operators;
for example, `.[0][]?[:-1]` is the same as `.[0] | .[]? | .[:-1]`.
- `[1, {a: 2 }, {a: 3 }] | .[].a? --> 2 3`
- `[1, [2, 3 ], [4, 5 ]] | .[][]? --> 2 3 4 5`
- ` 1, {a: [2]}, {a: [3]} | .a?[] --> 2 3`

::: Advanced

Expand Down
13 changes: 8 additions & 5 deletions jaq-core/src/load/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -651,12 +651,15 @@ impl<'s, 't> Parser<'s, 't> {
fn path(&mut self) -> Result<'s, 't, Path<Term<&'s str>>> {
let mut path: Vec<_> = core::iter::from_fn(|| self.path_part_opt()).collect();
while let Some(key) = self.dot() {
let key = if key.is_empty() {
self.str_key()?
path.push(if key.is_empty() {
match self.path_part_opt() {
Some(part_opt) => part_opt,
None => (path::Part::Index(self.str_key()?), self.opt()),
}
} else {
Term::from_str(key)
};
path.push((path::Part::Index(key), self.opt()));
(path::Part::Index(Term::from_str(key)), self.opt())
});

path.extend(core::iter::from_fn(|| self.path_part_opt()));
}
Ok(Path(path))
Expand Down
Loading