use std::collections::VecDeque;
use std::sync::Arc;
use crate::error::CaptureError;
use crate::frame::Frame;
use crate::source::FrameSource;
pub struct FakeSource {
script: VecDeque<Arc<Frame>>,
last: Option<Arc<Frame>>,
}
impl FakeSource {
pub fn new(frames: impl IntoIterator<Item = Frame>) -> Self {
Self {
script: frames.into_iter().map(Arc::new).collect(),
last: None,
}
}
}
#[async_trait::async_trait]
impl FrameSource for FakeSource {
async fn capture_frame(&mut self) -> Result<Arc<Frame>, CaptureError> {
if let Some(frame) = self.script.pop_front() {
self.last = Some(frame.clone());
return Ok(frame);
}
self.last.clone().ok_or(CaptureError::Exhausted)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn replays_script_then_repeats_last_frame() {
let mut src = FakeSource::new([
Frame::solid(2, 2, [1, 1, 1, 255]),
Frame::solid(2, 2, [2, 2, 2, 255]),
]);
assert_eq!(src.capture_frame().await.unwrap().data()[0], 1);
assert_eq!(src.capture_frame().await.unwrap().data()[0], 2);
assert_eq!(src.capture_frame().await.unwrap().data()[0], 2);
assert_eq!(src.capture_frame().await.unwrap().data()[0], 2);
}
#[tokio::test]
async fn empty_source_is_exhausted() {
let mut src = FakeSource::new([]);
assert!(matches!(
src.capture_frame().await,
Err(CaptureError::Exhausted)
));
}
}