1use serde::{Deserialize, Serialize};
2use std::cmp::Ordering;
3use std::fmt;
4use std::hash::{Hash, Hasher};
5
6#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy, Deserialize, Serialize)]
7#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
8pub enum DigitalUnit {
9 Byte,
10 Kilobyte,
11 Megabyte,
12 Gigabyte,
13}
14
15impl DigitalUnit {
16 fn to_bytes(&self) -> f64 {
17 match self {
18 DigitalUnit::Byte => 1.0,
19 DigitalUnit::Kilobyte => 1_000.0,
20 DigitalUnit::Megabyte => 1_000_000.0,
21 DigitalUnit::Gigabyte => 1_000_000_000.0,
22 }
23 }
24}
25
26impl fmt::Display for DigitalUnit {
27 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28 use DigitalUnit::*;
29 let s = match self {
30 Byte => "byte",
31 Kilobyte => "kilobyte",
32 Megabyte => "megabyte",
33 Gigabyte => "gigabyte",
34 };
35 write!(f, "{}", s)
36 }
37}
38
39#[derive(PartialEq, PartialOrd, Debug, Clone, Deserialize, Serialize)]
40pub struct DigitalValue {
41 pub value: f64,
42 unit: DigitalUnit,
43 #[serde(rename="__typename")]
44 type_name: Option<String>
45}
46
47impl DigitalValue {
48 pub fn to_bytes(self) -> DigitalValue {
49 self.convert_to(DigitalUnit::Byte)
50 }
51 pub fn to_kilobytes(self) -> DigitalValue {
52 self.convert_to(DigitalUnit::Kilobyte)
53 }
54 pub fn to_megabytes(self) -> DigitalValue {
55 self.convert_to(DigitalUnit::Megabyte)
56 }
57 pub fn to_gigabytes(self) -> DigitalValue {
58 self.convert_to(DigitalUnit::Gigabyte)
59 }
60
61 fn convert_to(self, target_unit: DigitalUnit) -> DigitalValue {
62 let bytes = self.value * self.unit.to_bytes();
63 let converted_value = bytes / target_unit.to_bytes();
64 DigitalValue {
65 value: converted_value,
66 unit: target_unit,
67 type_name: None,
68 }
69 }
70}
71
72impl Eq for DigitalValue {}
73
74impl Ord for DigitalValue {
75 fn cmp(&self, other: &Self) -> Ordering {
76 let self_bytes = self.value * self.unit.to_bytes();
77 let other_bytes = other.value * other.unit.to_bytes();
78
79 match self_bytes.total_cmp(&other_bytes) {
81 Ordering::Equal => self.unit.cmp(&other.unit),
82 other => other,
83 }
84 }
85}
86
87impl Hash for DigitalValue {
88 fn hash<H: Hasher>(&self, state: &mut H) {
89 self.value.to_bits().hash(state);
90 self.unit.hash(state);
91 }
92}
93
94impl fmt::Display for DigitalValue {
95 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
96 write!(f, "{} {}", self.value, self.unit)
97 }
98}
99
100#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Deserialize, Serialize)]
101#[serde(untagged)]
102pub enum Size {
103 Bytes(usize),
104 DigitalValue(DigitalValue),
105}
106
107impl fmt::Display for Size {
108 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
109 use Size::*;
110 match self {
111 Bytes(bytes) => {
112 write!(f, "{} byte", bytes)
113 }
114 DigitalValue(d) => {
115 write!(f, "{} {}", d.value, d.unit)
116 }
117 }
118 }
119}