save_load_traits/
load_from_directory.rs

1// ---------------- [ File: save-load-traits/src/load_from_directory.rs ]
2crate::ix!();
3
4/// Trait for loading objects from a directory asynchronously.
5#[async_trait]
6pub trait LoadFromDirectory: Sized {
7    type Error;
8
9    async fn load_from_directory(
10        dir: impl AsRef<Path> + Send,
11    ) -> Result<Vec<Self>, Self::Error>;
12}
13
14/// Blanket implementation of `LoadFromDirectory` for any type implementing `LoadFromFile`
15/// where the error can be converted from `SaveLoadError`.
16#[async_trait]
17impl<T> LoadFromDirectory for T
18where
19    T: LoadFromFile + Send + Sized,
20    T::Error: Display + From<SaveLoadError> + From<io::Error> + Send + 'static,
21{
22    type Error = T::Error;
23
24    async fn load_from_directory(
25        dir: impl AsRef<Path> + Send,
26    ) -> Result<Vec<Self>, Self::Error> {
27
28        let dir = dir.as_ref();
29
30        if !dir.is_dir() {
31            return Err(SaveLoadError::InvalidDirectory {
32                dir: dir.to_path_buf()
33            }.into());
34        }
35
36        let mut results = Vec::new();
37        let mut entries = tokio::fs::read_dir(dir).await?;
38
39        while let Some(entry) = entries.next_entry().await? {
40            let path = entry.path();
41
42            if path.is_file() {
43                match Self::load_from_file(&path).await {
44                    Ok(item) => results.push(item),
45                    Err(e) => warn!("Failed to load from file {:?}: {}", path, e),
46                }
47            }
48        }
49
50        Ok(results)
51    }
52}