use crate::model::{Middleware, ZFUri};
use crate::prelude::ErrorKind;
use crate::{bail, zferror, Result};
use serde::Deserializer;
use std::path::{Path, PathBuf};
use std::str::FromStr;
use url::Url;
pub(crate) fn parse_uri(url_str: &str) -> Result<ZFUri> {
let uri = Url::parse(url_str).map_err(|err| {
zferror!(
ErrorKind::ParsingError,
"Error while parsing URI: {} - {}",
url_str,
err
)
})?;
let uri_path = match uri.host_str() {
Some(h) => format!("{}{}", h, uri.path()),
None => uri.path().to_string(),
};
match uri.scheme() {
"file" => Ok(ZFUri::File(try_make_file_path(&uri_path)?)),
"builtin" => {
let mw = Middleware::from_str(&uri_path)?;
Ok(ZFUri::Builtin(mw))
}
_ => {
bail!(
ErrorKind::ParsingError,
"Scheme: {}:// is not supported. Supported ones are `file://` and `builtin://`",
uri.scheme()
);
}
}
}
pub(crate) fn try_make_file_path(file_path: &str) -> Result<PathBuf> {
let mut path = PathBuf::new();
#[cfg(test)]
{
path.push(env!("CARGO_MANIFEST_DIR"));
}
path.push(file_path);
let path = std::fs::canonicalize(&path)
.map_err(|e| zferror!(ErrorKind::IOError, "{}: {}", e, &path.to_string_lossy()))?;
Ok(path)
}
pub(crate) fn get_file_extension(file: &Path) -> Option<String> {
if let Some(ext) = file.extension() {
if let Some(ext) = ext.to_str() {
return Some(String::from(ext));
}
}
None
}
pub(crate) fn is_dynamic_library(ext: &str) -> bool {
if ext == std::env::consts::DLL_EXTENSION {
return true;
}
false
}
pub fn deserialize_size<'de, D>(deserializer: D) -> std::result::Result<Option<usize>, D::Error>
where
D: Deserializer<'de>,
{
match serde::de::Deserialize::deserialize(deserializer) {
Ok(buf) => Ok(Some(
bytesize::ByteSize::from_str(buf)
.map_err(|_| {
serde::de::Error::custom(format!("Unable to parse value as bytes {buf}"))
})?
.as_u64() as usize,
)),
Err(e) => {
log::warn!("failed to deserialize size: {:?}", e);
Ok(None)
}
}
}
pub fn deserialize_time<'de, D>(deserializer: D) -> std::result::Result<Option<u64>, D::Error>
where
D: Deserializer<'de>,
{
match serde::de::Deserialize::deserialize(deserializer) {
Ok::<&str, _>(buf) => {
let ht = (buf)
.parse::<humantime::Duration>()
.map_err(serde::de::Error::custom)?;
Ok(Some(ht.as_nanos() as u64))
}
Err(e) => {
log::warn!("failed to deserialize time: {:?}", e);
Ok(None)
}
}
}