From b079cb2f66bee2c7861507dccc136e3c999be7dd Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 9 Feb 2025 22:38:44 +0000 Subject: [PATCH] chore: move serde impls to module --- Cargo.toml | 2 +- src/lib.rs | 105 +-------------------------------------------------- src/serde.rs | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 105 deletions(-) create mode 100644 src/serde.rs diff --git a/Cargo.toml b/Cargo.toml index 1b8be9f2..fc54e5ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ version = "1.3.0" authors = ["Hyunsik Choi ", "MrCroxx "] keywords = ["byte", "byte-size", "utility", "human-readable", "format"] categories = ["development-tools", "filesystem"] -repository = "https://github.com/hyunsik/bytesize" +repository = "https://github.com/bytesize-rs/bytesize" license = "Apache-2.0" edition = "2021" rust-version = "1.65" diff --git a/src/lib.rs b/src/lib.rs index 268efe08..4395007f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,15 +28,8 @@ //! ``` mod parse; - -#[cfg(feature = "arbitrary")] -extern crate arbitrary; -#[cfg(feature = "serde")] -extern crate serde; -#[cfg(feature = "serde")] -use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; #[cfg(feature = "serde")] -use std::convert::TryFrom; +mod serde; use std::fmt::{self, Debug, Display, Formatter}; use std::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign}; @@ -342,70 +335,6 @@ where } } -#[cfg(feature = "serde")] -impl<'de> Deserialize<'de> for ByteSize { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - struct ByteSizeVisitor; - - impl de::Visitor<'_> for ByteSizeVisitor { - type Value = ByteSize; - - fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - formatter.write_str("an integer or string") - } - - fn visit_i64(self, value: i64) -> Result { - if let Ok(val) = u64::try_from(value) { - Ok(ByteSize(val)) - } else { - Err(E::invalid_value( - de::Unexpected::Signed(value), - &"integer overflow", - )) - } - } - - fn visit_u64(self, value: u64) -> Result { - Ok(ByteSize(value)) - } - - fn visit_str(self, value: &str) -> Result { - if let Ok(val) = value.parse() { - Ok(val) - } else { - Err(E::invalid_value( - de::Unexpected::Str(value), - &"parsable string", - )) - } - } - } - - if deserializer.is_human_readable() { - deserializer.deserialize_any(ByteSizeVisitor) - } else { - deserializer.deserialize_u64(ByteSizeVisitor) - } - } -} - -#[cfg(feature = "serde")] -impl Serialize for ByteSize { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - if serializer.is_human_readable() { - ::serialize(self.to_string().as_str(), serializer) - } else { - self.0.serialize(serializer) - } - } -} - #[cfg(test)] mod tests { use super::*; @@ -537,36 +466,4 @@ mod tests { fn test_to_string() { assert_to_string("609.0 PB", ByteSize::pb(609), false); } - - #[cfg(feature = "serde")] - #[test] - fn test_serde() { - #[derive(Serialize, Deserialize)] - struct S { - x: ByteSize, - } - - let s: S = serde_json::from_str(r#"{ "x": "5 B" }"#).unwrap(); - assert_eq!(s.x, ByteSize(5)); - - let s: S = serde_json::from_str(r#"{ "x": 1048576 }"#).unwrap(); - assert_eq!(s.x, "1 MiB".parse::().unwrap()); - - let s: S = toml::from_str(r#"x = "2.5 MiB""#).unwrap(); - assert_eq!(s.x, "2.5 MiB".parse::().unwrap()); - - // i64 MAX - let s: S = toml::from_str(r#"x = "9223372036854775807""#).unwrap(); - assert_eq!(s.x, "9223372036854775807".parse::().unwrap()); - } - - #[test] - #[cfg(feature = "serde")] - fn test_serde_json() { - let json = serde_json::to_string(&ByteSize::mib(1)).unwrap(); - assert_eq!(json, "\"1.0 MiB\""); - - let deserialized: ByteSize = serde_json::from_str(&json).unwrap(); - assert_eq!(deserialized.0, 1048576); - } } diff --git a/src/serde.rs b/src/serde.rs new file mode 100644 index 00000000..5cda0d38 --- /dev/null +++ b/src/serde.rs @@ -0,0 +1,103 @@ +use std::fmt; + +use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; + +use crate::ByteSize; + +impl<'de> Deserialize<'de> for ByteSize { + fn deserialize(de: D) -> Result + where + D: Deserializer<'de>, + { + struct ByteSizeVisitor; + + impl de::Visitor<'_> for ByteSizeVisitor { + type Value = ByteSize; + + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.write_str("an integer or string") + } + + fn visit_i64(self, value: i64) -> Result { + if let Ok(val) = u64::try_from(value) { + Ok(ByteSize(val)) + } else { + Err(E::invalid_value( + de::Unexpected::Signed(value), + &"integer overflow", + )) + } + } + + fn visit_u64(self, value: u64) -> Result { + Ok(ByteSize(value)) + } + + fn visit_str(self, value: &str) -> Result { + if let Ok(val) = value.parse() { + Ok(val) + } else { + Err(E::invalid_value( + de::Unexpected::Str(value), + &"parsable string", + )) + } + } + } + + if de.is_human_readable() { + de.deserialize_any(ByteSizeVisitor) + } else { + de.deserialize_u64(ByteSizeVisitor) + } + } +} + +impl Serialize for ByteSize { + fn serialize(&self, ser: S) -> Result + where + S: Serializer, + { + if ser.is_human_readable() { + ::serialize(self.to_string().as_str(), ser) + } else { + self.0.serialize(ser) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_serde() { + #[derive(Serialize, Deserialize)] + struct S { + x: ByteSize, + } + + let s = serde_json::from_str::(r#"{ "x": "5 B" }"#).unwrap(); + assert_eq!(s.x, ByteSize(5)); + + let s = serde_json::from_str::(r#"{ "x": 1048576 }"#).unwrap(); + assert_eq!(s.x, "1 MiB".parse::().unwrap()); + + let s = toml::from_str::(r#"x = "2.5 MiB""#).unwrap(); + assert_eq!(s.x, "2.5 MiB".parse::().unwrap()); + + // i64 MAX + let s = toml::from_str::(r#"x = "9223372036854775807""#).unwrap(); + assert_eq!(s.x, "9223372036854775807".parse::().unwrap()); + } + + #[test] + + fn test_serde_json() { + let json = serde_json::to_string(&ByteSize::mib(1)).unwrap(); + assert_eq!(json, "\"1.0 MiB\""); + + let deserialized = serde_json::from_str::(&json).unwrap(); + assert_eq!(deserialized.0, 1048576); + } +}