pub struct Machine<G = Group> { /* private fields */ }pointer only.Expand description
State machine for identifying JSON Pointer matches against a JSON pattern.
Evaluating a JSON Pointer is primarily a structural question. With the exception of object
member names, scalar values do not matter. Furthermore, once a “dead path” within the JSON text
has been reached where no possible JSON Pointer can match deeper within that path, the structure
underneath the “dead path” does not matter either (you have to return from the path before any
further matches are possible). Consequently, a Machine only consumes the structural pattern of
a JSON text that is needed for matching the JSON Pointers it knows about. Some examples of this
pattern-based interface are:
- The
arr_beginandobj_beginmethods can return aStructAction::Skipinstruction indicating that the interior values contained within the array or object do not matter and must not be sent to theMachine. - The
primitivemethod, which indicates a number token, literal token, or a string token that is not an object member name, does not accept a parameter for the actual token value. - The
Machinehas no methods for punctuation tokens or whitespace.
§Examples
Test the JSON pattern corresponding to a nested array like [[false, true]] or [[0, 1]]
against a JSON Pointer that matches the second element of the inner array.
use bufjson::pointer::{Group, Pointer, state::{Machine, StructAction}};
let pointer = Pointer::from_static("/0/1");
let group: Group = pointer.clone().into();
let mut mach = Machine::new(group, false); // Don't unescape object member names.
assert_eq!((StructAction::Enter, None), mach.arr_begin()); // Outer [
assert_eq!((StructAction::Enter, None), mach.arr_begin()); // Inner [
assert_eq!(None, mach.primitive()); // Inner array element #1
assert_eq!(Some(&pointer), mach.primitive()); // Inner array element #2 matches!
assert_eq!(None, mach.arr_end()); // Inner ]
assert_eq!(None, mach.arr_end()); // Outer ]Test the JSON pattern corresponding to a nested structure like {"foo":[],"bar":1} against a
group of JSON Pointers that will match the "foo" member but not the"bar" member.
use bufjson::{
lexical::fixed::Content,
pointer::{Group, Pointer, state::{Machine, StructAction}},
};
let group = Group::from_pointers([Pointer::from_static("/foo"), Pointer::from_static("/baz")]);
let mut mach = Machine::new(group, false); // Don't unescape object member names.
assert_eq!((StructAction::Enter, None), mach.obj_begin()); // {
mach.member_name(Content::from_static(r#""foo""#)); // "foo"
assert_eq!( // [ starts match!
(StructAction::Skip, Some(&Pointer::from_static("/foo"))),
mach.arr_begin()
);
assert_eq!(Some(&Pointer::from_static("/foo")), mach.arr_end()); // ] ends match
mach.member_name(Content::from_static(r#""bar""#)); // "bar"
assert_eq!(None, mach.primitive()); // 1
assert_eq!(None, mach.obj_end()); // }Unescape object member names, so that the JSON string literal "\u0066oo" matches “foo”, and
test the JSON pattern corresponding to {"\u0066oo":{"bar":1}} against the JSON Pointer
/foo/bar.
use bufjson::{
lexical::fixed::Content,
pointer::{Group, Pointer, state::{Machine, StructAction}},
};
let pointer = Pointer::from_static("/foo/bar");
let group: Group = pointer.clone().into();
let mut mach = Machine::new(group, true); // Expand escape sequences in object member names.
assert_eq!((StructAction::Enter, None), mach.obj_begin()); // Outer {
mach.member_name(Content::from_static(r#""\u0066oo""#)); // ~ "foo"
assert_eq!((StructAction::Enter, None), mach.obj_begin()); // Inner {
mach.member_name(Content::from_static(r#""bar""#)); // "bar"
assert_eq!(Some(&Pointer::from_static("/foo/bar")), mach.primitive()); // 1
assert_eq!(None, mach.obj_end()); // Inner }
assert_eq!(None, mach.obj_end()); // Outer }Implementations§
Source§impl<G: AsRef<Group>> Machine<G>
impl<G: AsRef<Group>> Machine<G>
Sourcepub fn new(group: G, unescape: bool) -> Self
pub fn new(group: G, unescape: bool) -> Self
Returns a new Machine for evaluating a group of JSON Pointers against a JSON pattern.
The group parameter may be an owned Group; or it can be any other owned value that can
provide a reference to a group, including &Group or a smart pointer like Arc<Group>.
This allows a single compiled JSON Pointer group to be shared across multiple machines.
The unescape parameter controls whether object member name strings are unescaped. If
false, escape sequences within member names are not expanded, so member names must match
the JSON Pointers literally. If true, escape sequences are expanded. For example, with
unescaping off, only the object member name "foo" will match /foo; but with unescaping
on, /foo can be matched by a string literal containing escape sequences that expand to
"foo", for example "\u0066oo" or "fo\u006f".
§Examples
Create a machine with an owned pointer group and unescaping enabled.
use bufjson::pointer::{Group, Pointer, state::Machine};
let mach = Machine::new(Group::from_pointer(Pointer::from_static("/foo")), true);Create a machine with a borrowed pointer group and unescaping disabled.
use bufjson::pointer::{Group, Pointer, state::Machine};
let group = Group::from_pointer(Pointer::from_static("/foo"));
let mach = Machine::new(&group, false);Sourcepub fn arr_begin(&mut self) -> (StructAction, Option<&Pointer>)
pub fn arr_begin(&mut self) -> (StructAction, Option<&Pointer>)
Starts an array value.
The return value is a pair consisting of:
- An action guiding the caller on how to handle the interior values contained by the array (whether to skip them or provide them).
- An optional value indicating if the array being started matches a JSON Pointer (
Some); or does not match any pointers (None).
Array elements, if any, can be provided using primitive for primitive values or by
starting sub-arrays or sub-objects using arr_begin or obj_begin.
The array must be ended with arr_end.
§Panics
Panics if a value is not allowed.
This can occur either because the last method called was obj_begin and an object member
name has not been provided yet; or because the containing object or array received a value
of StructAction::Skip when it was started by an earlier call to arr_begin or
obj_begin.
Sourcepub fn obj_begin(&mut self) -> (StructAction, Option<&Pointer>)
pub fn obj_begin(&mut self) -> (StructAction, Option<&Pointer>)
Starts an object value.
The return value is a pair consisting of:
- An action guiding the caller on how to handle the interior values contained by the object (whether to skip them or provide them).
- An optional value indicating if the object being started matches a JSON Pointer (
Some); or does not match any pointers (None).
Object members, if any, can be provided by starting each member with a call to
member_name and then providing the value using one of primitive for primitive
values; arr_begin for array values; or obj_begin for object values.
The object must be ended with obj_end.
§Panics
Panics if a value is not allowed.
This can occur either because the last method called was obj_begin and an object member
name has not been provided yet; or because the containing object or array received a value
of StructAction::Skip when it was started by an earlier call to arr_begin or
obj_begin.
Sourcepub fn member_name<C: Content>(&mut self, name: C)
pub fn member_name<C: Content>(&mut self, name: C)
Provides the next member name within an object.
Object members are name/value pairs. Within an object started with obj_begin, provide
each pair by first calling member_name and then providing the value using one of
arr_begin, obj_begin, or primitive.
§Panics
Panics if a member name is not allowed in the current state. This can occur if the current structured value is not an object, or if the current value is an object but a member name was just provided so a value is now needed.
Sourcepub fn primitive(&mut self) -> Option<&Pointer>
pub fn primitive(&mut self) -> Option<&Pointer>
Provides a primitive value.
The return value indicates whether the primitive matches a JSON Pointer (Some), or does
not match any pointers (None).
Primitive values include numbers, strings, and the three JSON literals, null, true, and
false.
This method does not accept an argument because the value of a primitive does not matter for the purposes of JSON Pointer evaluation. Whether or not a primitive matches a JSON Pointer is entirely dictated by the structure of the JSON before the value, i.e., the path of object member names and array indices that leads to the value.
§Panics
Panics if a value is not allowed.
This can occur either because the last method called was obj_begin and an object member
name has not been provided yet; or because the containing object or array received a value
of StructAction::Skip when it was started by an earlier call to arr_begin or
obj_begin.
Sourcepub fn into_inner(self) -> G
pub fn into_inner(self) -> G
Returns the contained JSON Pointer group, consuming the self value.
§Example
use bufjson::pointer::{Group, Pointer, state::Machine};
let group: Group = Pointer::from_static("/foo/bar").into();
let mut mach1 = Machine::new(group, false);
let _ = mach1.arr_begin();
let _ = mach1.arr_end();
let group = mach1.into_inner();
let mach2 = Machine::new(group, true);Trait Implementations§
Auto Trait Implementations§
impl<G> Freeze for Machine<G>where
G: Freeze,
impl<G> RefUnwindSafe for Machine<G>where
G: RefUnwindSafe,
impl<G> Send for Machine<G>where
G: Send,
impl<G> Sync for Machine<G>where
G: Sync,
impl<G> Unpin for Machine<G>where
G: Unpin,
impl<G> UnsafeUnpin for Machine<G>where
G: UnsafeUnpin,
impl<G> UnwindSafe for Machine<G>where
G: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.Source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.