use std::error::Error; use std::fmt::Display; use std::io::Read; use pkgfile::PKGFile; use reqwest::blocking::get; use crate::package::identifier::PackageLocator; #[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_by_path>(path: S) -> Result { std::fs::read(path.into()) .map_err(|e| FetchError::IOError(e)).and_then(|bytes| { PKGFile::try_from(bytes).map_err(|_| FetchError::ParseError) }) } pub fn fetch_by_uri>(uri: S) -> Result { // get file contents as bytes let mut bytes = Vec::new(); match get(uri.into()) { 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), } } pub fn fetch_by_package_locator(package_locator: PackageLocator) -> Result { // TODO: search index for package locator Ok(PKGFile::default()) }