use std::error::Error; use std::fmt::Display; use std::fs::File; use std::io::Read; use log::warn; use pkgfile::PKGFile; use crate::package::identifier::PackageIdentifier; use reqwest::blocking::get; #[derive(Debug)] pub enum FetchError { HTTPError(reqwest::Error), IOError(std::io::Error), ParseError, } impl Display for FetchError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { FetchError::HTTPError(e) => write!(f, "HTTP Error: {}", e), FetchError::IOError(e) => write!(f, "IO Error: {}", e), FetchError::ParseError => write!(f, "Parse Error"), } } } impl Error for FetchError {} pub fn fetch_package(package_identifier: PackageIdentifier) -> Result { match package_identifier { PackageIdentifier::Path(path) => { std::fs::read(path) .map_err(|e| FetchError::IOError(e)).and_then(|bytes| { PKGFile::try_from(bytes).map_err(|_| FetchError::ParseError) }) } PackageIdentifier::URI(uri) => { // get file contents as bytes let mut bytes = Vec::new(); match get(&uri) { Ok(mut response) => { match response.take(1024 * 1024).read_to_end(&mut bytes) { Ok(_) => (), Err(e) => return Err(FetchError::IOError(e)), }; } Err(e) => return Err(FetchError::HTTPError(e)), }; // parse bytes as PKGFile match PKGFile::try_from(bytes) { Ok(pkgfile) => Ok(pkgfile), Err(e) => Err(FetchError::ParseError), } } PackageIdentifier::PackageLocator(package_locator) => { Ok(PKGFile::default()) } } }