The tree path resolves an alias by cloning an already-built Node. A streaming path has no nodes, so it must replay the events that built the anchored value instead. That difference is the whole reason this type exists, and the source of the sharpest edges in the rest of this epic.
Scope
crates/glaucus-serde/src/stream/tape.rs:
pub(crate) struct Tape<'a> { /* … */ }
impl<'a> Tape<'a> {
pub(crate) fn new(input: &'a str) -> Self;
pub(crate) fn next(&mut self) -> Option<Result<Event<'a>>>;
pub(crate) fn begin_anchor(&mut self, name: &str);
pub(crate) fn end_anchor(&mut self);
pub(crate) fn replay(&self, name: &str) -> Option<&[Event<'a>]>;
}
Tasks 3–7 read events only through this.
Two design decisions worth keeping
One flat buffer, anchors as (start, end) ranges — not a Vec per anchor. Nested anchors (&x {p: &y 1}) then cost nothing extra: y's range sits inside x's. With per-anchor vectors the inner events would be stored twice.
Recording is lazy. Most documents contain no anchors at all. Allocating a tape for them would make every ordinary parse pay for a feature it does not use. The buffer stays empty until the first anchor is seen, and recording stops only when the last open scope closes — an outer anchor still open must keep collecting.
Acceptance
- An anchor-free document ends with
buffered_events() == 0. This is a performance requirement, tested, not an aspiration.
- An anchor records its range and replays a non-empty slice.
- An undefined alias yields
None, not a panic.
- Coverage stays at 100%.
Part of #49.
The tree path resolves an alias by cloning an already-built
Node. A streaming path has no nodes, so it must replay the events that built the anchored value instead. That difference is the whole reason this type exists, and the source of the sharpest edges in the rest of this epic.Scope
crates/glaucus-serde/src/stream/tape.rs:Tasks 3–7 read events only through this.
Two design decisions worth keeping
One flat buffer, anchors as
(start, end)ranges — not aVecper anchor. Nested anchors (&x {p: &y 1}) then cost nothing extra:y's range sits insidex's. With per-anchor vectors the inner events would be stored twice.Recording is lazy. Most documents contain no anchors at all. Allocating a tape for them would make every ordinary parse pay for a feature it does not use. The buffer stays empty until the first anchor is seen, and recording stops only when the last open scope closes — an outer anchor still open must keep collecting.
Acceptance
buffered_events() == 0. This is a performance requirement, tested, not an aspiration.None, not a panic.Part of #49.