flix_fs/scanner/
library.rs1use std::ffi::OsStr;
5use std::path::Path;
6
7use async_stream::stream;
8use tokio::fs;
9use tokio_stream::Stream;
10use tokio_stream::wrappers::ReadDirStream;
11
12use crate::Error;
13use crate::scanner::generic;
14
15pub type Item = crate::Item<generic::Scanner>;
17
18pub enum Scanner {}
20
21impl Scanner {
22 pub fn scan_library(path: &Path) -> impl Stream<Item = Item> {
24 stream!({
25 let dirs = match fs::read_dir(path).await {
26 Ok(dirs) => dirs,
27 Err(err) => {
28 yield Item {
29 path: path.to_owned(),
30 event: Err(Error::ReadDir(err)),
31 };
32 return;
33 }
34 };
35
36 let mut subdirs_to_scan = Vec::new();
37
38 for await dir in ReadDirStream::new(dirs) {
39 match dir {
40 Ok(dir) => {
41 let filetype = match dir.file_type().await {
42 Ok(filetype) => filetype,
43 Err(err) => {
44 yield Item {
45 path: path.to_owned(),
46 event: Err(Error::FileType(err)),
47 };
48 continue;
49 }
50 };
51
52 let path = dir.path();
53 if filetype.is_dir() {
54 subdirs_to_scan.push(path);
55 continue;
56 }
57
58 match path.extension().and_then(OsStr::to_str) {
59 Some(_) | None => {
60 yield Item {
61 path: path.to_owned(),
62 event: Err(Error::UnexpectedFile),
63 };
64 }
65 }
66 }
67 Err(err) => {
68 yield Item {
69 path: path.to_owned(),
70 event: Err(Error::ReadDirEntry(err)),
71 }
72 }
73 }
74 }
75
76 for subdir in subdirs_to_scan {
77 for await event in generic::Scanner::scan_detect_folder(&subdir, None) {
78 yield event;
79 }
80 }
81 })
82 }
83}