read_url/cache/
asynchronous.rs

1use super::{
2    super::{errors::*, url::*},
3    cache::*,
4};
5
6use {
7    kutil::std::error::*,
8    std::sync::*,
9    tokio::{fs::*, io},
10    tracing::*,
11};
12
13impl UrlCache {
14    /// Get a cache file from a URL.
15    ///
16    /// If it already exists returns the path and true. Otherwise copies the URL to a generated path and
17    /// returns it and false.
18    pub async fn file_from_async(&self, url: &UrlRef, prefix: &str) -> Result<(PathBufRef, bool), UrlError> {
19        let key = url.to_string();
20
21        let mut files = self.files.lock()?;
22        match files.get(&key) {
23            Some(path) => {
24                info!("existing file: {}", path.clone().lock()?.display());
25                Ok((path.clone(), true))
26            }
27
28            None => {
29                let path = self.new_path(prefix)?;
30
31                info!("downloading to file (asynchronous): {}", path.display());
32                let mut reader = io::BufReader::new(url.open_async()?.await?);
33                let mut file = io::BufWriter::new(File::create_new(path.clone()).await.with_path(path.clone())?);
34                io::copy(&mut reader, &mut file).await?;
35
36                info!("new file: {}", path.display());
37                let path = Arc::new(Mutex::new(path));
38                files.insert(key, path.clone());
39                Ok((path, false))
40            }
41        }
42    }
43}