diff --git a/crates/core/src/util.rs b/crates/core/src/util.rs index 2e50951..a9e0842 100644 --- a/crates/core/src/util.rs +++ b/crates/core/src/util.rs @@ -3,11 +3,9 @@ extern crate alloc; use alloc::format; use alloc::string::String; -use serde::Deserialize; -use serde_json as json; - #[cfg(not(feature = "getrandom"))] use crate::sqlite; +use serde::de::Visitor; use uuid::Uuid; @@ -46,25 +44,56 @@ pub fn deserialize_string_to_i64<'de, D>(deserializer: D) -> Result, { - let value = json::Value::deserialize(deserializer)?; + struct ValueVisitor; + + impl<'de> Visitor<'de> for ValueVisitor { + type Value = i64; + + fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result { + formatter.write_str("a string representation of a number") + } - match value { - json::Value::String(s) => s.parse::().map_err(serde::de::Error::custom), - _ => Err(serde::de::Error::custom("Expected a string.")), + fn visit_str(self, v: &str) -> Result + where + E: serde::de::Error, + { + v.parse::().map_err(serde::de::Error::custom) + } } + + // Using a custom visitor here to avoid an intermediate string allocation + deserializer.deserialize_str(ValueVisitor) } pub fn deserialize_optional_string_to_i64<'de, D>(deserializer: D) -> Result, D::Error> where D: serde::Deserializer<'de>, { - let value = json::Value::deserialize(deserializer)?; - - match value { - json::Value::Null => Ok(None), - json::Value::String(s) => s.parse::().map(Some).map_err(serde::de::Error::custom), - _ => Err(serde::de::Error::custom("Expected a string or null.")), + struct ValueVisitor; + + impl<'de> Visitor<'de> for ValueVisitor { + type Value = Option; + + fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result { + formatter.write_str("a string or null") + } + + fn visit_none(self) -> Result + where + E: serde::de::Error, + { + Ok(None) + } + + fn visit_some(self, deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + Ok(Some(deserialize_string_to_i64(deserializer)?)) + } } + + deserializer.deserialize_option(ValueVisitor) } // Use getrandom crate to generate UUID.