Skip to main content

FrameStack

Struct FrameStack 

Source
pub struct FrameStack<R, K, P> { /* private fields */ }
Expand description

The generic frame-stack mechanics described in the module docs.

K must be Clone + Default (not Copy) — FrameStack::consume_value resets the top frame’s pending key to K::default(), and Frame::pending_key hands back a reference rather than forcing every driving crate’s key enum to be Copy.

Implementations§

Source§

impl<R, K, P> FrameStack<R, K, P>
where K: Clone + Default,

Source

pub const fn new() -> Self

Creates an empty stack.

Source

pub fn depth(&self) -> usize

Number of currently open frames — 0 at the document root before any MappingStart/SequenceStart has been pushed.

Source

pub fn top(&self) -> Option<&Frame<R, K, P>>

The innermost open frame, if any.

Source

pub fn top_mut(&mut self) -> Option<&mut Frame<R, K, P>>

Mutable access to the innermost open frame, if any.

Source

pub fn top_role_or(&self, default: R) -> R
where R: Copy,

The top frame’s role, or default if the stack is empty.

Convenience for self.top().map_or(default, |f| *f.role()) — a pattern every driving crate’s own child-role computation and key-scalar handling repeats at each call site, since a fresh role must always be read before deciding how to route a new key or child container.

§Examples
use deps_core::yaml_walk::{FrameKind, FrameStack};

#[derive(Clone, Copy, PartialEq, Eq, Debug)]
enum Role {
    Irrelevant,
    Root,
}

let mut stack: FrameStack<Role, (), ()> = FrameStack::new();
assert_eq!(stack.top_role_or(Role::Irrelevant), Role::Irrelevant);

stack.push(FrameKind::Mapping, Role::Root, ());
assert_eq!(stack.top_role_or(Role::Irrelevant), Role::Root);
Source

pub fn clear(&mut self)

Closes every open frame without running any FrameStack::pop transition — for a multi-document YAML stream, called on Event::DocumentStart/ Event::DocumentEnd so one document’s nesting never mis-scopes another’s.

Source

pub fn scalar_position(&self) -> ScalarPosition

Where the next scalar event sits: awaiting a key, awaiting a value, or outside any key/value-bearing context (an empty stack, or a Sequence top).

Source

pub fn is_complex_key_position(&self) -> bool

Whether a container about to be pushed would occupy a complex YAML key’s position (? <mapping> / ? <sequence>): the top frame is a Mapping still awaiting a key. Exposed so a driving crate’s own on_alias-replay path (which calls FrameStack::push/FrameStack::pop out of band, not from a live key position) can assert it is never mistaken for a complex key.

Source

pub fn observe_key(&mut self, key: K)
where K: PartialEq,

Records that a key scalar (or an alias resolving to one) was just read: the top frame transitions from awaiting a key to awaiting key’s value. A no-op if the stack is empty.

Source

pub fn consume_value(&mut self)

Records that a value was just consumed (a scalar, alias, or a just-closed container): the top frame transitions back to awaiting a key, and its pending key resets to K::default(). A no-op if the stack is empty.

Like FrameStack::push/FrameStack::pop, this mutates awaiting_key/ pending_key unconditionally, even when the top frame is a Sequence (which has no key/value structure of its own). This is harmless as long as every caller reads a frame’s key/value state only through FrameStack::scalar_position/FrameStack::is_complex_key_position — both already treat a Sequence top as ScalarPosition::Outside/never a complex key — rather than reading Frame::pending_key directly without first checking the frame’s FrameKind.

Source

pub fn push(&mut self, kind: FrameKind, role: R, payload: P)

Opens a new frame of kind kind, role role, and initial payload.

If the current top frame occupies a complex-key position (see the module docs), the parent is left untouched (still awaiting its key) and the new frame is marked so FrameStack::pop applies the matching transition instead of the ordinary one; otherwise this is exactly FrameStack::consume_value on the parent followed by pushing the new frame.

§Examples

Pushing a container onto a Mapping still awaiting its key (? <mapping>: value, a complex key’s own subtree) is recognized via FrameStack::is_complex_key_position before the push — that recognition is exactly what makes the matching FrameStack::pop transition possible once the subtree closes (see that method’s own example for the visible effect):

use deps_core::yaml_walk::{FrameKind, FrameStack, ScalarPosition};

let mut stack: FrameStack<(), (), ()> = FrameStack::new();
stack.push(FrameKind::Mapping, (), ()); // the enclosing mapping
assert_eq!(stack.scalar_position(), ScalarPosition::Key);

assert!(stack.is_complex_key_position());
stack.push(FrameKind::Mapping, (), ()); // `? <mapping>`'s own subtree
assert_eq!(stack.depth(), 2);
Source

pub fn pop(&mut self) -> Option<Frame<R, K, P>>

Closes the innermost open frame and returns it, or None if the stack was already empty.

If the closed frame was pushed at a complex-key position, the new top (the former parent) transitions directly to “awaiting this entry’s value” — the same transition a plain scalar key produces — rather than the ordinary FrameStack::consume_value reset, which would leave it stuck awaiting another key and desync the rest of the mapping’s key/value alternation.

§Examples

Closing a complex key’s subtree (? <mapping>: value) flips the parent straight to “awaiting a value”, exactly as a plain scalar key would — not back to “awaiting a key”, which is what would happen for an ordinary (non-complex-key) child:

use deps_core::yaml_walk::{FrameKind, FrameStack, ScalarPosition};

let mut stack: FrameStack<(), (), ()> = FrameStack::new();
stack.push(FrameKind::Mapping, (), ()); // the enclosing mapping
stack.push(FrameKind::Mapping, (), ()); // `? <mapping>`'s own subtree
stack.pop(); // closes the complex key

// The parent now awaits this entry's *value* — not another key.
assert_eq!(stack.scalar_position(), ScalarPosition::Value);

Trait Implementations§

Source§

impl<R, K, P> Default for FrameStack<R, K, P>
where K: Clone + Default,

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<R, K, P> Freeze for FrameStack<R, K, P>
where Vec<Frame<R, K, P>>: Freeze,

§

impl<R, K, P> RefUnwindSafe for FrameStack<R, K, P>
where Vec<Frame<R, K, P>>: RefUnwindSafe,

§

impl<R, K, P> Send for FrameStack<R, K, P>
where Vec<Frame<R, K, P>>: Send,

§

impl<R, K, P> Sync for FrameStack<R, K, P>
where Vec<Frame<R, K, P>>: Sync,

§

impl<R, K, P> Unpin for FrameStack<R, K, P>
where Vec<Frame<R, K, P>>: Unpin,

§

impl<R, K, P> UnsafeUnpin for FrameStack<R, K, P>
where Vec<Frame<R, K, P>>: UnsafeUnpin,

§

impl<R, K, P> UnwindSafe for FrameStack<R, K, P>
where Vec<Frame<R, K, P>>: 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> 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> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. 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