use alloc::vec::Vec; use crate::protocol::Packet; use super::{ rpc::OutgoingFrame, tree::{BlockChunk, ChildSummary}, }; /// Caller-side synchronization phase. /// /// This is the manual state machine a future macro should be able to derive from /// RPC declarations. Each awaiting state owns the partial stream it is collecting, /// making it clear which packets are legal at each step. #[derive(Debug, Clone, PartialEq, Eq)] pub(super) enum CallerPhase { NeedRoot, AwaitRoot { hook_id: u16, }, Ready, AwaitChildren { hook_id: u16, node_id: u32, entries: Vec, }, AwaitBlock { hook_id: u16, block_id: u32, chunks: Vec, }, Done, } /// Test-visible caller observations. /// /// The leaf itself lives behind `Box`, so the harness keeps a shared /// report handle for assertions without needing downcasts. #[derive(Debug, Default)] pub(super) struct CallerReport { pub(super) done: bool, pub(super) requested_procedures: Vec, pub(super) received_procedures: Vec, pub(super) synchronized_blocks: Vec, pub(super) applied_block_chunks: Vec<(u32, Vec>)>, pub(super) final_root_hash: Option, } /// Test-visible respondent observations. #[derive(Debug, Default)] pub(super) struct RespondentReport { pub(super) requests_seen: Vec, pub(super) streams_started: usize, pub(super) streams_completed: usize, pub(super) frames_sent: usize, } /// Respondent-owned response stream. /// /// It stores encoded frames and exposes packet construction one frame at a time. /// Since `next_packet` does not advance, a failed route can be retried by calling it /// again on the next loop. #[derive(Debug, Clone, PartialEq, Eq)] pub(super) struct ResponseStream { hook_id: u16, frames: Vec, next_index: usize, } impl ResponseStream { /// Creates a response stream for one request hook. pub(super) fn new(hook_id: u16, frames: Vec) -> Self { Self { hook_id, frames, next_index: 0, } } /// Builds the next packet without advancing the stream. pub(super) fn next_packet(&self) -> Option { let frame = self.frames.get(self.next_index)?; Some(frame.to_packet(self.hook_id, self.next_index + 1 == self.frames.len())) } /// Marks the current frame as successfully sent. pub(super) fn advance(&mut self) { self.next_index += 1; } /// Returns true once every frame has been sent. pub(super) fn is_complete(&self) -> bool { self.next_index >= self.frames.len() } /// Returns true when the request generated no frames. pub(super) fn is_empty(&self) -> bool { self.frames.is_empty() } }