2023-03-25 17:06:01 +01:00
|
|
|
use std::{
|
|
|
|
|
fmt::Display,
|
|
|
|
|
path::{Path, PathBuf},
|
|
|
|
|
result::Result as StdResult,
|
|
|
|
|
};
|
2022-09-02 23:48:26 +02:00
|
|
|
use thiserror::Error;
|
2023-03-25 17:06:01 +01:00
|
|
|
use url::{ParseError, Url};
|
2022-09-02 23:48:26 +02:00
|
|
|
|
|
|
|
|
type Result<T> = StdResult<T, SourceError>;
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Error)]
|
|
|
|
|
pub enum SourceError {
|
|
|
|
|
#[error("can't create source from url: {0}")]
|
|
|
|
|
CantCreateSource(String),
|
|
|
|
|
#[error("can not parse source url: {0}")]
|
2023-03-25 17:06:01 +01:00
|
|
|
UrlParseError(#[from] ParseError),
|
2022-09-02 23:48:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[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<P: AsRef<Path>>(url_string: &str, local_base: P) -> Result<Source> {
|
|
|
|
|
let url = Url::parse(url_string)?;
|
|
|
|
|
let path = url.path().to_owned();
|
2023-03-25 17:06:01 +01:00
|
|
|
let path_vec: Vec<_> = path.split('/').collect();
|
2022-09-02 23:48:26 +02:00
|
|
|
match path_vec.last() {
|
2023-03-25 17:06:01 +01:00
|
|
|
Some(local_name) => Ok(Source {
|
|
|
|
|
url,
|
|
|
|
|
local_name: local_base.as_ref().join(local_name),
|
|
|
|
|
}),
|
|
|
|
|
None => Err(SourceError::CantCreateSource(url.into()))?,
|
2022-09-02 23:48:26 +02:00
|
|
|
}
|
|
|
|
|
}
|
2023-03-25 17:06:01 +01:00
|
|
|
}
|