Skip to main content

StateExpectation

Struct StateExpectation 

Source
pub struct StateExpectation {
    pub case_id: CaseId,
    pub path: String,
    pub equals: Option<Value>,
    pub one_of: Vec<Value>,
    pub unchanged: bool,
    pub absent: bool,
    pub ignore_case: bool,
}
Expand description

What a case’s state must say after the turn.

The path is a JSON Pointer into the workflow’s own state, because the state is the workflow’s business and this crate cannot know its shape — so an item says /fields/address_street/value and the library compares what it finds there, with no opinion about what a field is.

Fields§

§case_id: CaseId

The case this is about.

§path: String

JSON Pointer into that case’s state, as the workflow serializes it.

§equals: Option<Value>

The value that path must hold afterwards.

§one_of: Vec<Value>

Values any one of which that path may hold afterwards: the user’s words read right in more than one form, such as with or without an article.

§unchanged: bool

The value that path must still hold, whatever it was.

§absent: bool

Nothing must be there: the path holds null, or does not resolve.

§Why this is not equals: null

Because that cannot be written. equals is an Option, so a JSON null deserializes as «no expectation given» and validate then refuses the whole entry for asserting nothing. The absence had no way to be said at all.

§What could not be measured without it

«I do not have one» is an answer, not a silence, and a collecting workflow often turns on it: a person who declines their loyalty number has answered the question, and the flow moves on. What the turn must do is record the refusal — a field that ends with no value and a status that moved — and every expectation this crate had asserts that a value IS somewhere. A suite measuring those flows could state the value case and not its opposite, which is the half that goes wrong: a turn that quietly writes something into a field the user declined reads, to every other assertion, exactly like a turn that respected them.

Resolving to nothing counts as absent on purpose. A workflow may drop the key instead of nulling it, and an assertion that told those two apart would be about the serializer rather than about the record.

§ignore_case: bool

Two strings differing only in case are the same value here.

Only meaningful beside equals, and only for a field whose case the application does not decide. That is a real category and not a loophole: a domain canonicalises what it owns, a booking reference to upper case or a loyalty number to its letters and digits, and stores a free-text field the way it was handed it, because nobody can guess how a person or a place writes its own name.

On those fields the case is the model’s typography, not the record’s content. A person types «lisbon», one turn stores «lisbon» and the next «Lisbon», and both are the same answer to the same question: an assertion that told them apart would report the lane as wrong for capitalising a city. Leave it off — the default — wherever the application does canonicalise, because there the case IS the content and a lower-case booking reference is one the airline does not find.

It never applies to unchanged or absent, which compare no text.

Implementations§

Source§

impl StateExpectation

Source

pub fn validate(&self) -> Result<(), CorpusError>

Checks the expectation asks exactly one thing.

§Errors

CorpusError::Invalid when it asks more than one thing, or none at all. None is the dangerous one: it would read as a strict assertion and check nothing.

Trait Implementations§

Source§

impl Clone for StateExpectation

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for StateExpectation

Source§

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

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for StateExpectation

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Eq for StateExpectation

Source§

impl PartialEq for StateExpectation

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl Serialize for StateExpectation

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for StateExpectation

Auto Trait Implementations§

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more