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    /// Open a local file as a byte source.
21    pub fn open(path: impl AsRef<Path>) -> Result<Self, CopcError> {
22        let file = std::fs::File::open(path)?;
23        let size = file.metadata()?.len();
24        Ok(Self {
25            file: Mutex::new(file),
26            size,
27        })
28    }
29}
30
31impl ByteSource for FileSource {
32    async fn read_range(&self, offset: u64, length: u64) -> Result<Vec<u8>, CopcError> {
33        let mut file = self.file.lock().unwrap();
34        file.seek(SeekFrom::Start(offset))?;
35        let mut buf = vec![0u8; length as usize];
36        file.read_exact(&mut buf)?;
37        Ok(buf)
38    }
39
40    async fn size(&self) -> Result<Option<u64>, CopcError> {
41        Ok(Some(self.size))
42    }
43}