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>
impl<R, K, P> FrameStack<R, K, P>
Sourcepub fn depth(&self) -> usize
pub fn depth(&self) -> usize
Number of currently open frames — 0 at the document root before any
MappingStart/SequenceStart has been pushed.
Sourcepub fn top_mut(&mut self) -> Option<&mut Frame<R, K, P>>
pub fn top_mut(&mut self) -> Option<&mut Frame<R, K, P>>
Mutable access to the innermost open frame, if any.
Sourcepub fn top_role_or(&self, default: R) -> Rwhere
R: Copy,
pub fn top_role_or(&self, default: R) -> Rwhere
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);Sourcepub fn clear(&mut self)
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.
Sourcepub fn scalar_position(&self) -> ScalarPosition
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).
Sourcepub fn is_complex_key_position(&self) -> bool
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.
Sourcepub fn observe_key(&mut self, key: K)where
K: PartialEq,
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.
Sourcepub fn consume_value(&mut self)
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.
Sourcepub fn push(&mut self, kind: FrameKind, role: R, payload: P)
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);Sourcepub fn pop(&mut self) -> Option<Frame<R, K, P>>
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);