anni_provider_drive_token_storage/fs/
local.rs1use crate::{FileEntry, FileSystemProvider, ProviderError, Range, ResourceReader};
2use async_trait::async_trait;
3use std::io::SeekFrom;
4use std::path::PathBuf;
5use std::pin::Pin;
6use tokio::fs::read_dir;
7use tokio::io::{AsyncReadExt, AsyncSeekExt};
8use tokio_stream::{self as stream, Stream};
9
10pub struct LocalFileSystemProvider;
11
12#[async_trait]
13impl FileSystemProvider for LocalFileSystemProvider {
14 async fn children(
15 &self,
16 path: &PathBuf,
17 ) -> crate::Result<Pin<Box<dyn Stream<Item = FileEntry> + Send>>> {
18 Ok(Box::pin(stream::iter(std::fs::read_dir(path)?.filter_map(
19 |entry| {
20 let entry = entry.ok()?;
21 let path = entry.path();
22 let name = path.file_name()?.to_string_lossy().to_string();
23 if path.is_dir() {
24 Some(FileEntry { name, path })
25 } else {
26 None
27 }
28 },
29 ))))
30 }
31
32 async fn get_file_entry_by_prefix(
33 &self,
34 parent: &PathBuf,
35 prefix: &str,
36 ) -> crate::Result<FileEntry> {
37 let mut dir = read_dir(parent).await?;
38 loop {
39 match dir.next_entry().await? {
40 Some(entry) if entry.file_name().to_string_lossy().starts_with(prefix) => {
41 return Ok(FileEntry {
42 name: entry.file_name().to_string_lossy().to_string(),
43 path: entry.path(),
44 });
45 }
46 None => return Err(ProviderError::FileNotFound),
47 _ => {}
48 }
49 }
50 }
51
52 async fn get_file(&self, path: &PathBuf, range: Range) -> crate::Result<ResourceReader> {
53 let mut file = tokio::fs::File::open(path).await?;
54 let metadata = file.metadata().await?;
55 let file_size = metadata.len();
56
57 file.seek(SeekFrom::Start(range.start)).await?;
58 let file = file.take(range.length_limit(file_size));
59 Ok(Box::pin(file))
60 }
61
62 async fn get_audio_info(&self, path: &PathBuf) -> crate::Result<(String, usize)> {
63 let extension = path
64 .extension()
65 .map(|e| e.to_string_lossy().to_string())
66 .unwrap_or_default();
67 let size = tokio::fs::metadata(path).await.map(|m| m.len())?;
68 Ok((extension, size as usize))
69 }
70
71 async fn reload(&mut self) -> crate::Result<()> {
72 Ok(())
73 }
74}