1use crate::error::Result;
4use std::io::{Read, Seek, SeekFrom};
5
6#[derive(Debug, Clone, Copy)]
8pub struct ReadInterval {
9 pub start: u64,
10 pub end: u64,
11}
12
13pub struct LocalFileMedia {
15 path: String,
16 name: String,
17 length: u64,
18}
19
20impl LocalFileMedia {
21 pub fn new(path: &str) -> std::io::Result<Self> {
22 let metadata = std::fs::metadata(path)?;
23 let name = std::path::Path::new(path)
24 .file_name()
25 .and_then(|n| n.to_str())
26 .unwrap_or("unknown")
27 .to_string();
28
29 Ok(Self {
30 path: path.to_string(),
31 name,
32 length: metadata.len(),
33 })
34 }
35
36 pub fn length(&self) -> u64 {
37 self.length
38 }
39
40 pub fn name(&self) -> &str {
41 &self.name
42 }
43
44 pub fn read_range_sync(&self, interval: ReadInterval) -> Result<Vec<u8>> {
46 let mut file = std::fs::File::open(&self.path)?;
47 file.seek(SeekFrom::Start(interval.start))?;
48 let len = (interval.end - interval.start + 1) as usize;
49 let mut buffer = vec![0u8; len];
50 file.read_exact(&mut buffer)?;
51 Ok(buffer)
52 }
53}
54
55#[cfg(feature = "async")]
57use std::future::Future;
58#[cfg(feature = "async")]
59use std::pin::Pin;
60
61#[cfg(feature = "async")]
63pub trait FileMedia: Send + Sync {
64 fn length(&self) -> u64;
65 fn name(&self) -> &str;
66 fn read_range(
67 &self,
68 interval: ReadInterval,
69 ) -> Pin<Box<dyn Future<Output = Result<Vec<u8>>> + Send + '_>>;
70}
71
72#[cfg(feature = "async")]
73impl FileMedia for LocalFileMedia {
74 fn length(&self) -> u64 {
75 self.length
76 }
77
78 fn name(&self) -> &str {
79 &self.name
80 }
81
82 fn read_range(
83 &self,
84 interval: ReadInterval,
85 ) -> Pin<Box<dyn Future<Output = Result<Vec<u8>>> + Send + '_>> {
86 let path = self.path.clone();
87 Box::pin(async move {
88 use tokio::io::{AsyncReadExt, AsyncSeekExt};
89 let mut file = tokio::fs::File::open(&path).await?;
90 file.seek(std::io::SeekFrom::Start(interval.start)).await?;
91 let len = (interval.end - interval.start + 1) as usize;
92 let mut buffer = vec![0u8; len];
93 file.read_exact(&mut buffer).await?;
94 Ok(buffer)
95 })
96 }
97}