use alloc::vec::Vec;
use crate::allocation::{
AllocationContext, AllocationError, RequestedCapacity, try_push, try_reserve_total_exact,
};
use crate::bytes::{Payload, RuntimeByte, RuntimeStateByteCount};
#[derive(Debug, PartialEq, Eq)]
pub(crate) struct RewriteScratch {
bytes: Vec<RuntimeByte>,
}
#[derive(Debug, PartialEq, Eq)]
pub(crate) struct PreparedRewrite {
bytes: Vec<RuntimeByte>,
}
impl PreparedRewrite {
pub(crate) fn into_runtime_bytes(self) -> Vec<RuntimeByte> {
self.bytes
}
}
impl RewriteScratch {
pub(crate) fn new() -> Self {
Self { bytes: Vec::new() }
}
pub(crate) fn take_prepared(&mut self) -> PreparedRewrite {
PreparedRewrite {
bytes: core::mem::take(&mut self.bytes),
}
}
pub(crate) fn store_previous_state(&mut self, bytes: Vec<RuntimeByte>) {
self.bytes = bytes;
}
pub(crate) fn clear_and_reserve(
&mut self,
capacity: RuntimeStateByteCount,
) -> Result<(), AllocationError> {
self.bytes.clear();
try_reserve_total_exact(
&mut self.bytes,
RequestedCapacity::from_runtime_state_count(capacity),
AllocationContext::RuntimeRewriteState,
)
}
pub(crate) fn push_existing(
&mut self,
source: impl IntoIterator<Item = RuntimeByte>,
) -> Result<(), AllocationError> {
for byte in source {
try_push(
&mut self.bytes,
byte,
AllocationContext::RuntimeRewriteState,
)?;
}
Ok(())
}
pub(crate) fn push_payload(&mut self, payload: &Payload) -> Result<(), AllocationError> {
self.push_existing(payload.runtime_bytes())
}
}