relay_config/
byte_size.rs1use std::fmt;
2use std::str::FromStr;
3
4pub use human_size::ParsingError as ByteSizeParseError;
5use human_size::{Any, Size, SpecificSize};
6use serde::ser::Serializer;
7use serde::{Serialize, de};
8
9pub struct ByteSize(Size);
39
40impl ByteSize {
41 fn multiple(value: u32, multiple: Any) -> Self {
42 Self(SpecificSize::new(value, multiple).unwrap())
45 }
46
47 fn try_multiple(value: u32, multiple: Any) -> Option<Self> {
48 let factor = match multiple {
49 Any::Mebibyte => 1024 * 1024,
50 Any::Megabyte => 1000 * 1000,
51 Any::Kibibyte => 1024,
52 Any::Kilobyte => 1000,
53 _ => 1,
54 };
55
56 match value % factor {
57 0 => Some(Self::multiple(value / factor, multiple)),
58 _ => None,
59 }
60 }
61
62 pub fn infer(value: u32) -> Self {
64 Self::try_multiple(value, Any::Mebibyte)
65 .or_else(|| Self::try_multiple(value, Any::Megabyte))
66 .or_else(|| Self::try_multiple(value, Any::Kibibyte))
67 .or_else(|| Self::try_multiple(value, Any::Kilobyte))
68 .unwrap_or_else(|| Self::bytes(value))
69 }
70
71 pub fn bytes(value: u32) -> Self {
73 Self::multiple(value, Any::Byte)
74 }
75
76 pub fn kibibytes(value: u32) -> Self {
78 Self::multiple(value, Any::Kibibyte)
79 }
80
81 pub fn mebibytes(value: u32) -> Self {
83 Self::multiple(value, Any::Mebibyte)
84 }
85
86 pub fn as_bytes(&self) -> usize {
88 let byte_size = self.0.into::<human_size::Byte>();
89 byte_size.value() as usize
90 }
91}
92
93impl From<u32> for ByteSize {
94 fn from(value: u32) -> ByteSize {
95 ByteSize::infer(value)
96 }
97}
98
99impl FromStr for ByteSize {
100 type Err = ByteSizeParseError;
101
102 fn from_str(value: &str) -> Result<Self, Self::Err> {
103 match value.parse::<u32>() {
104 Ok(bytes) => Ok(Self::bytes(bytes)),
105 Err(_) => value.parse().map(ByteSize),
106 }
107 }
108}
109
110impl fmt::Display for ByteSize {
111 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
112 write!(f, "{}{}", self.0.value(), self.0.multiple())
113 }
114}
115
116impl fmt::Debug for ByteSize {
117 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118 f.debug_tuple("ByteSize")
119 .field(&format_args!("{}", self.0))
120 .finish()
121 }
122}
123
124impl Serialize for ByteSize {
125 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
126 where
127 S: Serializer,
128 {
129 serializer.collect_str(self)
130 }
131}
132
133impl<'de> de::Deserialize<'de> for ByteSize {
134 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
135 where
136 D: de::Deserializer<'de>,
137 {
138 struct V;
139
140 impl de::Visitor<'_> for V {
141 type Value = ByteSize;
142
143 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
144 formatter.write_str("data size")
145 }
146
147 fn visit_u64<E>(self, value: u64) -> Result<ByteSize, E>
148 where
149 E: de::Error,
150 {
151 match value.try_into() {
152 Ok(value32) => Ok(ByteSize::infer(value32)),
153 Err(_) => Err(de::Error::invalid_value(
154 de::Unexpected::Unsigned(value),
155 &self,
156 )),
157 }
158 }
159
160 fn visit_str<E>(self, value: &str) -> Result<ByteSize, E>
161 where
162 E: de::Error,
163 {
164 value
165 .parse()
166 .map_err(|_| de::Error::invalid_value(de::Unexpected::Str(value), &self))
167 }
168 }
169
170 deserializer.deserialize_any(V)
171 }
172}
173
174#[cfg(test)]
175mod tests {
176 use super::*;
177
178 #[test]
179 fn test_infer() {
180 let size = ByteSize::infer(42);
181 assert_eq!(42, size.as_bytes());
182 assert_eq!("42B", size.to_string());
183
184 let size = ByteSize::infer(1000);
185 assert_eq!(1000, size.as_bytes());
186 assert_eq!("1kB", size.to_string());
187
188 let size = ByteSize::infer(1024);
189 assert_eq!(1024, size.as_bytes());
190 assert_eq!("1KiB", size.to_string());
191
192 let size = ByteSize::infer(1000 * 1000);
193 assert_eq!(1000 * 1000, size.as_bytes());
194 assert_eq!("1MB", size.to_string());
195
196 let size = ByteSize::infer(1024 * 1024);
197 assert_eq!(1024 * 1024, size.as_bytes());
198 assert_eq!("1MiB", size.to_string());
199 }
200
201 #[test]
202 fn test_parse() {
203 let size = ByteSize::from_str("4242").unwrap();
204 assert_eq!(4242, size.as_bytes());
205 assert_eq!("4242B", size.to_string());
206
207 let size = ByteSize::from_str("42B").unwrap();
208 assert_eq!(42, size.as_bytes());
209 assert_eq!("42B", size.to_string());
210
211 let size = ByteSize::from_str("1kB").unwrap();
213 assert_eq!(1000, size.as_bytes());
214 assert_eq!("1kB", size.to_string());
215
216 let size = ByteSize::from_str("1KB").unwrap();
218 assert_eq!(1024, size.as_bytes());
219 assert_eq!("1KiB", size.to_string());
220
221 let size = ByteSize::from_str("1KiB").unwrap();
222 assert_eq!(1024, size.as_bytes());
223 assert_eq!("1KiB", size.to_string());
224
225 let size = ByteSize::from_str("1MB").unwrap();
226 assert_eq!(1000 * 1000, size.as_bytes());
227 assert_eq!("1MB", size.to_string());
228
229 let size = ByteSize::from_str("1MiB").unwrap();
230 assert_eq!(1024 * 1024, size.as_bytes());
231 assert_eq!("1MiB", size.to_string());
232 }
233
234 #[test]
235 fn test_as_bytes() {
236 let size = ByteSize::bytes(42);
237 assert_eq!(42, size.as_bytes());
238
239 let size = ByteSize::kibibytes(42);
240 assert_eq!(42 * 1024, size.as_bytes());
241
242 let size = ByteSize::mebibytes(42);
243 assert_eq!(42 * 1024 * 1024, size.as_bytes());
244 }
245
246 #[test]
247 fn test_serde_number() {
248 let size = serde_json::from_str::<ByteSize>("1024").unwrap();
249 let json = serde_json::to_string(&size).unwrap();
250 assert_eq!(json, "\"1KiB\"");
251 }
252
253 #[test]
254 fn test_serde_string() {
255 let size = serde_json::from_str::<ByteSize>("\"1KiB\"").unwrap();
256 let json = serde_json::to_string(&size).unwrap();
257 assert_eq!(json, "\"1KiB\"");
258 }
259}