use std::fmt;
use serde::{
de::{self, Unexpected, Visitor},
ser::{Serialize, Serializer},
Deserialize, Deserializer,
};
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[allow(missing_docs)]
pub enum Time {
Days(u64),
Hours(u64),
Minutes(u64),
Seconds(u64),
Milliseconds(u64),
Microseconds(u64),
Nanoseconds(u64),
}
impl Serialize for Time {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
Self::Days(u) => format!("{u}d"),
Self::Hours(u) => format!("{u}h"),
Self::Minutes(u) => format!("{u}m"),
Self::Seconds(u) => format!("{u}s"),
Self::Milliseconds(u) => format!("{u}ms"),
Self::Microseconds(u) => format!("{u}micros"),
Self::Nanoseconds(u) => format!("{u}nanos"),
}
.serialize(serializer)
}
}
impl<'de> Deserialize<'de> for Time {
fn deserialize<D>(deserializer: D) -> Result<Time, D::Error>
where
D: Deserializer<'de>,
{
struct TimeVisitor;
impl<'de> Visitor<'de> for TimeVisitor {
type Value = Time;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a string representing a duration")
}
fn visit_str<E>(self, value: &str) -> Result<Time, E>
where
E: de::Error,
{
let len = value.len();
let number = &value[..len - 1];
let unit = &value[len - 1..];
let number = number.parse::<u64>().map_err(E::custom)?;
match unit {
"d" => Ok(Time::Days(number)),
"h" => Ok(Time::Hours(number)),
"m" => Ok(Time::Minutes(number)),
"s" => Ok(Time::Seconds(number)),
"ms" => Ok(Time::Milliseconds(number)),
"micros" => Ok(Time::Microseconds(number)),
"nanos" => Ok(Time::Nanoseconds(number)),
_ => Err(E::custom(format!("unknown time unit: {}", unit))),
}
}
}
deserializer.deserialize_str(TimeVisitor)
}
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum CalendarInterval {
Minute,
Hour,
Day,
Week,
Month,
Quarter,
Year,
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[allow(missing_docs)]
pub enum Byte {
Bytes(u64),
Kilobytes(u64),
Megabytes(u64),
Gigabytes(u64),
Terabytes(u64),
Petabytes(u64),
}
impl Serialize for Byte {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
Self::Bytes(u) => format!("{u}b"),
Self::Kilobytes(u) => format!("{u}kb"),
Self::Megabytes(u) => format!("{u}mb"),
Self::Gigabytes(u) => format!("{u}gb"),
Self::Terabytes(u) => format!("{u}tb"),
Self::Petabytes(u) => format!("{u}pb"),
}
.serialize(serializer)
}
}
impl<'de> Deserialize<'de> for Byte {
fn deserialize<D>(deserializer: D) -> Result<Byte, D::Error>
where
D: Deserializer<'de>,
{
struct ByteVisitor;
impl<'de> Visitor<'de> for ByteVisitor {
type Value = Byte;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a string representing a byte size")
}
fn visit_str<E>(self, value: &str) -> Result<Byte, E>
where
E: de::Error,
{
let len = value.len();
let number = &value[..len - 2];
let unit = &value[len - 2..];
let number = number.parse::<u64>().map_err(E::custom)?;
match unit {
"b" => Ok(Byte::Bytes(number)),
"kb" => Ok(Byte::Kilobytes(number)),
"mb" => Ok(Byte::Megabytes(number)),
"gb" => Ok(Byte::Gigabytes(number)),
"tb" => Ok(Byte::Terabytes(number)),
"pb" => Ok(Byte::Petabytes(number)),
_ => Err(E::custom(format!("unknown byte unit: {}", unit))),
}
}
}
deserializer.deserialize_str(ByteVisitor)
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[allow(missing_docs)]
pub enum Size {
Kilo(u64),
Mega(u64),
Giga(u64),
Tera(u64),
Peta(u64),
}
impl Serialize for Size {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
Self::Kilo(u) => format!("{u}k"),
Self::Mega(u) => format!("{u}m"),
Self::Giga(u) => format!("{u}g"),
Self::Tera(u) => format!("{u}t"),
Self::Peta(u) => format!("{u}p"),
}
.serialize(serializer)
}
}
impl<'de> Deserialize<'de> for Size {
fn deserialize<D>(deserializer: D) -> Result<Size, D::Error>
where
D: Deserializer<'de>,
{
struct SizeVisitor;
impl<'de> Visitor<'de> for SizeVisitor {
type Value = Size;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a string representing a size")
}
fn visit_str<E>(self, value: &str) -> Result<Size, E>
where
E: de::Error,
{
let len = value.len();
let number = &value[..len - 1];
let unit = &value[len - 1..];
let number = number.parse::<u64>().map_err(E::custom)?;
match unit {
"k" => Ok(Size::Kilo(number)),
"m" => Ok(Size::Mega(number)),
"g" => Ok(Size::Giga(number)),
"t" => Ok(Size::Tera(number)),
"p" => Ok(Size::Peta(number)),
_ => Err(E::custom(format!("unknown size unit: {}", unit))),
}
}
}
deserializer.deserialize_str(SizeVisitor)
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[allow(missing_docs)]
pub enum Distance {
Miles(u64),
Yards(u64),
Feet(u64),
Inches(u64),
Kilometers(u64),
Meters(u64),
Centimeter(u64),
Millimeters(u64),
NauticalMiles(u64),
}
impl Default for Distance {
fn default() -> Self {
Self::Meters(100)
}
}
impl Serialize for Distance {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
Self::Miles(u) => format!("{u}mi"),
Self::Yards(u) => format!("{u}yd"),
Self::Feet(u) => format!("{u}ft"),
Self::Inches(u) => format!("{u}in"),
Self::Kilometers(u) => format!("{u}km"),
Self::Meters(u) => format!("{u}m"),
Self::Centimeter(u) => format!("{u}cm"),
Self::Millimeters(u) => format!("{u}mm"),
Self::NauticalMiles(u) => format!("{u}nmi"),
}
.serialize(serializer)
}
}
impl<'de> Deserialize<'de> for Distance {
fn deserialize<D>(deserializer: D) -> Result<Distance, D::Error>
where
D: Deserializer<'de>,
{
struct DistanceVisitor;
impl<'de> Visitor<'de> for DistanceVisitor {
type Value = Distance;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a string representing a distance")
}
fn visit_str<E>(self, value: &str) -> Result<Distance, E>
where
E: de::Error,
{
let len = value.len();
let number = &value[..len - 2];
let unit = &value[len - 2..];
let number = number.parse::<u64>().map_err(E::custom)?;
match unit {
"mi" => Ok(Distance::Miles(number)),
"yd" => Ok(Distance::Yards(number)),
"ft" => Ok(Distance::Feet(number)),
"in" => Ok(Distance::Inches(number)),
"km" => Ok(Distance::Kilometers(number)),
"m" => Ok(Distance::Meters(number)),
"cm" => Ok(Distance::Centimeter(number)),
"mm" => Ok(Distance::Millimeters(number)),
"nmi" => Ok(Distance::NauticalMiles(number)),
_ => Err(E::custom(format!("unknown distance unit: {}", unit))),
}
}
}
deserializer.deserialize_str(DistanceVisitor)
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[allow(missing_docs)]
pub enum DistanceUnit {
Miles,
Yards,
Feet,
Inches,
Kilometers,
Meters,
Centimeter,
Millimeters,
NauticalMiles,
}
impl Serialize for DistanceUnit {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
Self::Miles => "mi",
Self::Yards => "yd",
Self::Feet => "ft",
Self::Inches => "in",
Self::Kilometers => "km",
Self::Meters => "m",
Self::Centimeter => "cm",
Self::Millimeters => "mm",
Self::NauticalMiles => "nmi",
}
.serialize(serializer)
}
}
impl<'de> Deserialize<'de> for DistanceUnit {
fn deserialize<D>(deserializer: D) -> Result<DistanceUnit, D::Error>
where
D: Deserializer<'de>,
{
struct DistanceUnitVisitor;
impl<'de> Visitor<'de> for DistanceUnitVisitor {
type Value = DistanceUnit;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a string representing a distance unit")
}
fn visit_str<E>(self, value: &str) -> Result<DistanceUnit, E>
where
E: de::Error,
{
match value {
"mi" => Ok(DistanceUnit::Miles),
"yd" => Ok(DistanceUnit::Yards),
"ft" => Ok(DistanceUnit::Feet),
"in" => Ok(DistanceUnit::Inches),
"km" => Ok(DistanceUnit::Kilometers),
"m" => Ok(DistanceUnit::Meters),
"cm" => Ok(DistanceUnit::Centimeter),
"mm" => Ok(DistanceUnit::Millimeters),
"nmi" => Ok(DistanceUnit::NauticalMiles),
_ => Err(E::invalid_value(Unexpected::Str(value), &self)),
}
}
}
deserializer.deserialize_str(DistanceUnitVisitor)
}
}