pub struct Path<'a> { /* private fields */ }Expand description
A parsed path.
Parsing is separate from matching because a path arrives once and is matched against every document a command touches, and because a path that does not parse should be an error before any document is read rather than an empty answer after all of them.
Implementations§
Source§impl<'a> Path<'a>
impl<'a> Path<'a>
Sourcepub fn parse(path: &'a [u8]) -> Result<Path<'a>>
pub fn parse(path: &'a [u8]) -> Result<Path<'a>>
Parse path.
A path that starts with $ is a JSONPath and anything else is what
RedisJSON calls a legacy path, which is the older syntax that answers one
value. Both are matched the same way here and the difference is recorded
in Path::legacy, because what it changes is the shape of the reply
and that is the dispatch layer’s business rather than this one’s.
Sourcepub fn is_projection(&self) -> bool
pub fn is_projection(&self) -> bool
Whether this path is an expression rather than a way through the document.
A projection answers values that are nowhere in the document, so there
is nothing for a write to write to and nothing for JSON.TYPE to
describe. Only JSON.GET, JSON.MGET and JSON.RESP take one and the
rest refuse it, which is what this is for.
Sourcepub fn project<'d>(&'d self, root: &Value<'d>) -> Vec<Computed<'d>>
pub fn project<'d>(&'d self, root: &Value<'d>) -> Vec<Computed<'d>>
What this projection works out against root, and nothing at all when
the path is not one.
Sourcepub fn legacy(&self) -> bool
pub fn legacy(&self) -> bool
Whether this path was written in the older syntax, without a leading
$.
Sourcepub fn is_root(&self) -> bool
pub fn is_root(&self) -> bool
Whether this path is the root and nothing else.
$, a bare . and the empty path are all it. JSON.SET needs to know,
because the root is the only place a whole document can be written to a
key that is not there yet, and JSON.DEL needs to know because deleting
the root is deleting the key.
Sourcepub fn is_definite(&self) -> bool
pub fn is_definite(&self) -> bool
Whether this path names at most one place, whatever document it is matched against.
A path made only of names and indices does. Everything else can answer
more than one value on some document even if it answers one on this one,
and the difference decides what a command is allowed to do: JSON.SET
creating a field that is not there yet only makes sense when the path
says exactly where it goes.
Sourcepub fn select<'d>(&self, root: &Value<'d>, out: &mut Vec<Value<'d>>)
pub fn select<'d>(&self, root: &Value<'d>, out: &mut Vec<Value<'d>>)
Every value this path names in root, in document order, appended to
out.
Appended rather than assigned, so that a command matching one path against many documents keeps one buffer. Nothing here allocates except that buffer and the frontier the walk carries.
Sourcepub fn split_last(&self) -> Option<(Path<'a>, Step<'a>)>
pub fn split_last(&self) -> Option<(Path<'a>, Step<'a>)>
This path without its last selector, and that selector, when the last one names one place.
JSON.SET is what needs it. A path that matched nothing can still be a
place to write, as long as what would hold the new value is there and the
last step says exactly where in it the value goes, so $.a.b against a
document with an a and no b splits into the parent $.a and the step
b.
None for the root, which has no last selector, and for a last selector
that is a wildcard, a descent, a union or a slice, because none of those
names a place that is not already there.