use std::{ io::{Read, Seek, SeekFrom}, sync::{Arc, Mutex}, }; use anyhow::Result; pub struct MultiReader { position: u64, inner: Arc>, } impl MultiReader { pub fn new(mut inner: T) -> Result { let position = inner.stream_position()?; Ok(Self { position, inner: Arc::new(Mutex::new((position, inner))), }) } } impl Clone for MultiReader { fn clone(&self) -> Self { Self { position: self.position, inner: self.inner.clone(), } } } impl Read for MultiReader { fn read(&mut self, buf: &mut [u8]) -> std::io::Result { let mut g = self.inner.lock().unwrap(); if g.0 != self.position { g.1.seek(SeekFrom::Start(self.position))?; } let size = g.1.read(buf)?; g.0 += size as u64; self.position += size as u64; Ok(size) } } impl Seek for MultiReader { fn seek(&mut self, pos: SeekFrom) -> std::io::Result { self.position = match pos { SeekFrom::Start(x) => x, SeekFrom::Current(x) => self.position.saturating_add_signed(x), SeekFrom::End(_) => unimplemented!(), }; Ok(self.position) } }