use super::clone::string_to_owned;
use crate::url::is_url;
use std::borrow::Cow;
use strum_macros::IntoStaticStr;
#[derive(Serialize, Deserialize, IntoStaticStr, Debug, Hash, Clone, PartialEq, Eq)]
#[serde(rename_all = "kebab-case", tag = "type", content = "data")]
pub enum FileSource<'a> {
Url(Cow<'a, str>),
File1 { file: Cow<'a, str> },
File2 {
page: Cow<'a, str>,
file: Cow<'a, str>,
},
File3 {
site: Cow<'a, str>,
page: Cow<'a, str>,
file: Cow<'a, str>,
},
}
impl<'t> FileSource<'t> {
pub fn parse(source: &'t str) -> Option<FileSource<'t>> {
if is_url(source) {
return Some(FileSource::Url(cow!(source)));
}
let source = source.strip_prefix('/').unwrap_or(source);
let parts: Vec<&str> = source.split('/').collect();
let source = match parts.len() {
1 => FileSource::File1 {
file: cow!(parts[0]),
},
2 => FileSource::File2 {
page: cow!(parts[0]),
file: cow!(parts[1]),
},
3 => FileSource::File3 {
site: cow!(parts[0]),
page: cow!(parts[1]),
file: cow!(parts[2]),
},
_ => return None,
};
Some(source)
}
#[inline]
pub fn name(&self) -> &'static str {
self.into()
}
pub fn to_owned(&self) -> FileSource<'static> {
match self {
FileSource::Url(url) => FileSource::Url(string_to_owned(url)),
FileSource::File1 { file } => FileSource::File1 {
file: string_to_owned(file),
},
FileSource::File2 { page, file } => FileSource::File2 {
page: string_to_owned(page),
file: string_to_owned(file),
},
FileSource::File3 { site, page, file } => FileSource::File3 {
site: string_to_owned(site),
page: string_to_owned(page),
file: string_to_owned(file),
},
}
}
}