pub struct S;Expand description
The S namespace — static factory methods for state transforms.
Implementations§
Source§impl S
impl S
Sourcepub fn pick(keys: &[&str]) -> StateTransform
pub fn pick(keys: &[&str]) -> StateTransform
Keep only the specified keys.
Sourcepub fn rename(mappings: &[(&str, &str)]) -> StateTransform
pub fn rename(mappings: &[(&str, &str)]) -> StateTransform
Rename keys according to the mappings.
Sourcepub fn merge(keys: &[&str], into: &str) -> StateTransform
pub fn merge(keys: &[&str], into: &str) -> StateTransform
Merge the specified keys into a single key as an object.
Sourcepub fn defaults(defaults: Value) -> StateTransform
pub fn defaults(defaults: Value) -> StateTransform
Set default values for missing keys.
Sourcepub fn map(f: impl Fn(&mut Value) + Send + Sync + 'static) -> StateTransform
pub fn map(f: impl Fn(&mut Value) + Send + Sync + 'static) -> StateTransform
Apply a custom transformation function.
Sourcepub fn flatten(key: &str) -> StateTransform
pub fn flatten(key: &str) -> StateTransform
Flatten a nested object key into the top level.
Sourcepub fn set(key: &str, value: Value) -> StateTransform
pub fn set(key: &str, value: Value) -> StateTransform
Set a key to a fixed value.
Sourcepub fn is_set(
key: &str,
) -> impl Fn(&State) -> bool + use<> + Send + Sync + 'static
pub fn is_set( key: &str, ) -> impl Fn(&State) -> bool + use<> + Send + Sync + 'static
Returns true if the given key exists with any non-null value.
Replaces the common pattern |s| s.get::<String>("key").is_some().
Live::builder().phase("greet").transition("next_phase", S::is_set("caller_name")).done();Sourcepub fn is_true(
key: &str,
) -> impl Fn(&State) -> bool + use<> + Send + Sync + 'static
pub fn is_true( key: &str, ) -> impl Fn(&State) -> bool + use<> + Send + Sync + 'static
Returns true if the given key holds a truthy boolean.
Live::builder().phase("disclose").transition("next_phase", S::is_true("disclosure_given")).done();Sourcepub fn eq(
key: &str,
expected: &str,
) -> impl Fn(&State) -> bool + use<> + Send + Sync + 'static
pub fn eq( key: &str, expected: &str, ) -> impl Fn(&State) -> bool + use<> + Send + Sync + 'static
Returns true if the given key equals the expected string value.
Live::builder().phase("triage").transition("tech:greet", S::eq("issue_type", "technical")).done();Sourcepub fn one_of(
key: &str,
values: &[&str],
) -> impl Fn(&State) -> bool + use<> + Send + Sync + 'static
pub fn one_of( key: &str, values: &[&str], ) -> impl Fn(&State) -> bool + use<> + Send + Sync + 'static
Returns true if the given key matches any of the provided string values.
Live::builder()
.phase("negotiate")
.transition("arrange_payment", S::one_of("negotiation_intent", &["full_pay", "partial_pay"]))
.done();Sourcepub fn transform(
key: &str,
f: impl Fn(Value) -> Value + Send + Sync + 'static,
) -> StateTransform
pub fn transform( key: &str, f: impl Fn(Value) -> Value + Send + Sync + 'static, ) -> StateTransform
Transform a single key’s value with a function.
Sourcepub fn guard(
predicate: impl Fn(&Value) -> bool + Send + Sync + 'static,
msg: &str,
) -> StateTransform
pub fn guard( predicate: impl Fn(&Value) -> bool + Send + Sync + 'static, msg: &str, ) -> StateTransform
Guard — assert a condition on state, panic with message if false.
Sourcepub fn compute(
key: &str,
f: impl Fn(&Value) -> Value + Send + Sync + 'static,
) -> StateTransform
pub fn compute( key: &str, f: impl Fn(&Value) -> Value + Send + Sync + 'static, ) -> StateTransform
Compute derived values from state.
Sourcepub fn accumulate(source_key: &str, into: &str) -> StateTransform
pub fn accumulate(source_key: &str, into: &str) -> StateTransform
Accumulate values into a list under a target key.
Sourcepub fn counter(key: &str, step: i64) -> StateTransform
pub fn counter(key: &str, step: i64) -> StateTransform
Increment a counter key by a step.
Sourcepub fn require(keys: &[&str]) -> StateTransform
pub fn require(keys: &[&str]) -> StateTransform
Require that specified keys exist.
Sourcepub fn identity() -> StateTransform
pub fn identity() -> StateTransform
Identity transform — no-op passthrough.
Sourcepub fn when(
predicate: impl Fn(&Value) -> bool + Send + Sync + 'static,
inner: StateTransform,
) -> StateTransform
pub fn when( predicate: impl Fn(&Value) -> bool + Send + Sync + 'static, inner: StateTransform, ) -> StateTransform
Conditional transform — applies inner transform only when predicate is true.
Sourcepub fn drop(keys: &[&str]) -> StateTransform
pub fn drop(keys: &[&str]) -> StateTransform
Drop the specified keys.
Sourcepub fn log(message: &str) -> StateTransform
pub fn log(message: &str) -> StateTransform
Log a message during state transform (side-effect marker).
Useful for debugging transform pipelines — prints the message to stderr each time the transform is applied.
let chain = S::pick(&["a"]) >> S::log("after pick") >> S::rename(&[("a", "x")]);Sourcepub fn unflatten(key: &str) -> StateTransform
pub fn unflatten(key: &str) -> StateTransform
Unflatten a dotted-key object into a nested structure (inverse of flatten).
Takes all top-level keys that start with key. and nests them under key as an object.
For example, {"addr.city": "NYC", "addr.zip": "10001"} with unflatten("addr")
becomes {"addr": {"city": "NYC", "zip": "10001"}}.
let t = S::unflatten("addr");Sourcepub fn zip(keys: &[&str], into: &str) -> StateTransform
pub fn zip(keys: &[&str], into: &str) -> StateTransform
Zip multiple array keys into an array of tuples (arrays).
Takes the arrays at each of keys and produces an array of arrays under into,
where element i contains [keys[0][i], keys[1][i], ...].
Arrays are zipped to the length of the shortest.
// {"names": ["a","b"], "scores": [1,2]} -> {"zipped": [["a",1], ["b",2]]}
let t = S::zip(&["names", "scores"], "zipped");Sourcepub fn group_by(source: &str, key: &str, into: &str) -> StateTransform
pub fn group_by(source: &str, key: &str, into: &str) -> StateTransform
Group array elements by a field value.
Takes the array at source, groups its elements by the string value of key,
and writes the resulting object (field value -> array of elements) to into.
// {"items": [{"type":"a","v":1}, {"type":"b","v":2}, {"type":"a","v":3}]}
// -> {"grouped": {"a": [{"type":"a","v":1}, {"type":"a","v":3}], "b": [{"type":"b","v":2}]}}
let t = S::group_by("items", "type", "grouped");Sourcepub fn history(key: &str, max: usize) -> StateTransform
pub fn history(key: &str, max: usize) -> StateTransform
Keep history of a key’s values (append to list, cap at max).
Each time this transform runs, the current value of key is appended to
{key}_history. The history array is capped at max entries (oldest dropped).
let t = S::history("score", 5); // keeps last 5 score values in "score_history"Sourcepub fn validate(schema: Value) -> StateTransform
pub fn validate(schema: Value) -> StateTransform
Validate state against a JSON schema value.
Panics with a descriptive message if any required key from the schema’s
required array is missing, or if a key’s type doesn’t match the schema’s
properties.{key}.type declaration.
let t = S::validate(json!({
"required": ["name", "age"],
"properties": {
"name": {"type": "string"},
"age": {"type": "number"}
}
}));Sourcepub fn branch(
predicate: impl Fn(&Value) -> bool + Send + Sync + 'static,
if_true: StateTransform,
if_false: StateTransform,
) -> StateTransform
pub fn branch( predicate: impl Fn(&Value) -> bool + Send + Sync + 'static, if_true: StateTransform, if_false: StateTransform, ) -> StateTransform
Conditional branching of state transforms.
Applies if_true when the predicate returns true, otherwise applies if_false.
let t = S::branch(
|s| s.get("premium").and_then(serde_json::Value::as_bool).unwrap_or(false),
S::set("tier", json!("gold")),
S::set("tier", json!("basic")),
);Auto Trait Implementations§
impl Freeze for S
impl RefUnwindSafe for S
impl Send for S
impl Sync for S
impl Unpin for S
impl UnsafeUnpin for S
impl UnwindSafe for S
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
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
§impl<T> Conv for T
impl<T> Conv for T
impl<S, T> Duplex<S> for Twhere
T: FromSample<S> + ToSample<S>,
§impl<T> FmtForward for T
impl<T> FmtForward for T
§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.§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.§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.§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.§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.§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.§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.§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.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<S> FromSample<S> for S
impl<S> FromSample<S> for S
fn from_sample_(s: S) -> S
§impl<T> FutureExt for T
impl<T> FutureExt for T
§fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
§fn with_current_context(self) -> WithContext<Self> ⓘ
fn with_current_context(self) -> WithContext<Self> ⓘ
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request§impl<L> LayerExt<L> for L
impl<L> LayerExt<L> for L
§fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
Layered].§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§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 more§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 more§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
§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
§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.§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.§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.§impl<T> Pointable for T
impl<T> Pointable for T
§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
§impl<T> Tap for T
impl<T> Tap for T
§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 more§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 more§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 more§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 more§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 more§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 more§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.§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.§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.§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.§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.§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.§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.