use url::{Url, ParseError}; use thiserror::Error; use std::{result::Result as StdResult, path::{Path, PathBuf}, fmt::Display}; type Result = StdResult; #[derive(Debug, Error)] pub enum SourceError { #[error("can't create source from url: {0}")] CantCreateSource(String), #[error("can not parse source url: {0}")] UrlParseError(#[from]ParseError) } #[derive(Debug, Clone)] pub struct Source { pub url: Url, pub local_name: PathBuf, } impl Display for Source { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.local_name.display()) } } impl Source { pub fn new>(url_string: &str, local_base: P) -> Result { let url = Url::parse(url_string)?; let path = url.path().to_owned(); let path_vec: Vec<_> = path.split("/").collect(); match path_vec.last() { Some(str) => { let local_name = str.clone(); Ok(Source { url, local_name: local_base.as_ref().join(local_name), }) } None => Err(SourceError::CantCreateSource(url.into()))? } } }