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