use std::path::PathBuf;
use serde::{Deserialize, de::Deserializer};
#[derive(Deserialize)]
#[serde(untagged)]
enum StrOrU64 {
U64(u64),
Str(String)
}
#[allow(clippy::missing_errors_doc)]
pub fn count<'de, D>(deserializer: D) -> Result<Count, D::Error>
where
D: Deserializer<'de>
{
match StrOrU64::deserialize(deserializer)? {
StrOrU64::U64(v) => Ok(Count(v)),
StrOrU64::Str(v) => {
let cfg = parse_size::Config::new().with_decimal();
cfg
.parse_size(&v)
.map(Count)
.map_err(|_| serde::de::Error::custom("Can't parse count"))
}
}
}
impl<'de> Deserialize<'de> for Count {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>
{
count(deserializer)
}
}
#[allow(clippy::missing_errors_doc)]
pub fn binsize<'de, D>(deserializer: D) -> Result<BinSize, D::Error>
where
D: Deserializer<'de>
{
match StrOrU64::deserialize(deserializer)? {
StrOrU64::U64(v) => Ok(BinSize(v)),
StrOrU64::Str(v) => {
let cfg = parse_size::Config::new().with_binary();
cfg
.parse_size(&v)
.map(BinSize)
.map_err(|_| serde::de::Error::custom("Can't parse size"))
}
}
}
impl<'de> Deserialize<'de> for BinSize {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>
{
binsize(deserializer)
}
}
#[allow(clippy::missing_errors_doc)]
pub fn decsize<'de, D>(deserializer: D) -> Result<DecSize, D::Error>
where
D: Deserializer<'de>
{
match StrOrU64::deserialize(deserializer)? {
StrOrU64::U64(v) => Ok(DecSize(v)),
StrOrU64::Str(v) => {
let cfg = parse_size::Config::new().with_decimal();
cfg
.parse_size(&v)
.map(DecSize)
.map_err(|_| serde::de::Error::custom("Can't parse size"))
}
}
}
impl<'de> Deserialize<'de> for DecSize {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>
{
decsize(deserializer)
}
}
pub use crate::parsers::{BinSize, Count, DecSize, ExpandedPath};
#[allow(clippy::missing_errors_doc)]
pub fn expand_path<'de, D>(deserializer: D) -> Result<ExpandedPath, D::Error>
where
D: Deserializer<'de>
{
let s = String::deserialize(deserializer)?;
match shellexpand::full(&s) {
Ok(value) => Ok(ExpandedPath(PathBuf::from(value.into_owned()))),
Err(e) => {
let msg = format!("Unable to expand path; {e}");
Err(serde::de::Error::custom(msg))
}
}
}
impl<'de> Deserialize<'de> for ExpandedPath {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>
{
expand_path(deserializer)
}
}