use zeroize::Zeroizing;
use super::{Broker, contains};
impl Broker {
pub(crate) fn value_in(&self, bytes: &[u8]) -> Option<&str> {
self.held
.iter()
.find(|h| contains(bytes, h.value.as_bytes()))
.map(|h| h.secret.id.as_str())
}
}
pub(crate) struct Holdback<'a> {
broker: &'a Broker,
keep: usize,
pending: Zeroizing<Vec<u8>>,
}
impl<'a> Holdback<'a> {
pub(crate) fn new(broker: &'a Broker) -> Self {
let keep = broker
.held
.iter()
.map(|h| h.value.len())
.max()
.unwrap_or(0)
.saturating_sub(1);
Self {
broker,
keep,
pending: Zeroizing::new(Vec::new()),
}
}
pub(crate) fn push(&mut self, data: &[u8]) -> Result<Zeroizing<Vec<u8>>, &'a str> {
self.pending.extend_from_slice(data);
if let Some(id) = self.broker.value_in(&self.pending) {
return Err(id);
}
let release = self.pending.len().saturating_sub(self.keep);
let rest = Zeroizing::new(self.pending[release..].to_vec());
self.pending.truncate(release);
Ok(std::mem::replace(&mut self.pending, rest))
}
pub(crate) fn finish(self) -> Zeroizing<Vec<u8>> {
self.pending
}
}