Skip to main content

Machine

Struct Machine 

Source
pub struct Machine<G = Group> { /* private fields */ }
Available on crate feature 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:

  1. The arr_begin and obj_begin methods can return a StructAction::Skip instruction indicating that the interior values contained within the array or object do not matter and must not be sent to the Machine.
  2. The primitive method, 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.
  3. The Machine has 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>

Source

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);
Source

pub fn arr_begin(&mut self) -> (StructAction, Option<&Pointer>)

Starts an array value.

The return value is a pair consisting of:

  1. An action guiding the caller on how to handle the interior values contained by the array (whether to skip them or provide them).
  2. 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.

Source

pub fn arr_end(&mut self) -> Option<&Pointer>

Ends an array value previously started with arr_begin.

The return value indicates whether the array being ended matches a JSON Pointer (Some), or does not match any pointers (None).

§Panics

Panics if the current structured value is not an array.

Source

pub fn obj_begin(&mut self) -> (StructAction, Option<&Pointer>)

Starts an object value.

The return value is a pair consisting of:

  1. An action guiding the caller on how to handle the interior values contained by the object (whether to skip them or provide them).
  2. 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.

Source

pub fn obj_end(&mut self) -> Option<&Pointer>

Ends an object value previously started with obj_begin.

The return value indicates whether the object being ended matches a JSON Pointer (Some) or does not match any pointers (None).

§Panics

Panics if the current structured value is not an object.

Source

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.

Source

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.

Source

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§

Source§

impl<G: Debug> Debug for Machine<G>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

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> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> Conv for T

Source§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
Source§

impl<T> FmtForward for T

Source§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
Source§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
Source§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
Source§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
Source§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
Source§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
Source§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
Source§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
Source§

fn fmt_list(self) -> FmtList<Self>
where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Pipe for T
where T: ?Sized,

Source§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
Source§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
Source§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
Source§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows 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
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows 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
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
Source§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
Source§

impl<T> Tap for T

Source§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
Source§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
Source§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
Source§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
Source§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
Source§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
Source§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
Source§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
Source§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
Source§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .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
where Self: BorrowMut<B>, B: ?Sized,

Calls .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
where Self: AsRef<R>, R: ?Sized,

Calls .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
where Self: AsMut<R>, R: ?Sized,

Calls .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
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
Source§

impl<T> TryConv for T

Source§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.