Skip to main content

copc_streaming/
file_source.rs

1//! File-based ByteSource for local file access.
2
3use std::io::{Read, Seek, SeekFrom};
4use std::path::Path;
5use std::sync::Mutex;
6
7use crate::byte_source::ByteSource;
8use crate::error::CopcError;
9
10/// A ByteSource backed by a local file.
11///
12/// Uses a Mutex for interior mutability since Read+Seek requires &mut self
13/// but ByteSource's read_range takes &self.
14pub struct FileSource {
15    file: Mutex<std::fs::File>,
16    size: u64,
17}
18
19impl FileSource {
20    pub fn open(path: impl AsRef<Path>) -> Result<Self, CopcError> {
21        let file = std::fs::File::open(path)?;
22        let size = file.metadata()?.len();
23        Ok(Self {
24            file: Mutex::new(file),
25            size,
26        })
27    }
28}
29
30impl ByteSource for FileSource {
31    async fn read_range(&self, offset: u64, length: u64) -> Result<Vec<u8>, CopcError> {
32        let mut file = self.file.lock().unwrap();
33        file.seek(SeekFrom::Start(offset))?;
34        let mut buf = vec![0u8; length as usize];
35        file.read_exact(&mut buf)?;
36        Ok(buf)
37    }
38
39    async fn size(&self) -> Result<Option<u64>, CopcError> {
40        Ok(Some(self.size))
41    }
42}