1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
use async_std::prelude::*; use graph_error::{GraphFailure, GraphResult}; use std::fs::OpenOptions; use std::io::copy; use std::path::{Path, PathBuf}; use std::sync::mpsc; use std::{fs, thread}; use tokio::prelude::*; pub struct IoTools; impl IoTools { pub fn create_dir<P: AsRef<Path>>(directory: P) -> GraphResult<()> { if !directory.as_ref().exists() { fs::create_dir_all(&directory)?; } Ok(()) } pub async fn create_dir_async<P: AsRef<Path>>(directory: P) -> GraphResult<()> { if !directory.as_ref().exists() { tokio::fs::create_dir_all(directory).await?; } Ok(()) } pub fn copy(path: PathBuf, mut response: reqwest::blocking::Response) -> GraphResult<PathBuf> { let (sender, receiver) = mpsc::channel(); let handle = thread::spawn(move || { let mut file_writer = OpenOptions::new() .create(true) .write(true) .read(true) .open(&path) .expect("Error creating file"); copy(&mut response, &mut file_writer).expect("Error copying file contents"); sender.send(Some(path)).unwrap(); }); handle.join().expect("Thread could not be joined"); match receiver.recv() { Ok(t) => { Ok(t.ok_or_else(|| GraphFailure::not_found("Unknown error downloading file"))?) }, Err(e) => Err(GraphFailure::from(e)), } } pub async fn copy_async(path: PathBuf, response: reqwest::Response) -> GraphResult<PathBuf> { let mut file = tokio::fs::OpenOptions::new() .create(true) .write(true) .read(true) .open(&path) .await?; let mut stream = response.bytes_stream(); while let Some(item) = stream.next().await { file.write_all(&item?).await?; } Ok(path) } }