From c630049c206866e4c017122bd543119e02a6f37b Mon Sep 17 00:00:00 2001 From: Abdulla Abdurakhmanov Date: Wed, 7 Sep 2022 21:35:46 +0200 Subject: [PATCH] Bugfixes and error handling updates --- examples/timestamp-serialize.rs | 29 +++++++ src/errors.rs | 28 ++++--- src/serde_deserializer.rs | 18 +++-- src/serde_serializer.rs | 8 +- src/serde_types_serializers.rs | 132 +++++++++++++++++++++----------- 5 files changed, 148 insertions(+), 67 deletions(-) diff --git a/examples/timestamp-serialize.rs b/examples/timestamp-serialize.rs index 7fd3b6f..9f6ec01 100644 --- a/examples/timestamp-serialize.rs +++ b/examples/timestamp-serialize.rs @@ -6,6 +6,15 @@ pub fn config_env_var(name: &str) -> Result { std::env::var(name).map_err(|e| format!("{}: {}", name, e)) } +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct Test1(u8); + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct Test2 { + some_id: String, + some_bool: Option, +} + // Example structure to play with #[derive(Debug, Clone, Deserialize, Serialize)] struct MyTestStructure { @@ -15,6 +24,10 @@ struct MyTestStructure { some_num: u64, #[serde(with = "firestore::serialize_as_timestamp")] created_at: DateTime, + test1: Test1, + test11: Option, + test2: Option, + test3: Vec, } #[tokio::main] @@ -36,6 +49,22 @@ async fn main() -> Result<(), Box> { one_more_string: "Test2".to_string(), some_num: 41, created_at: Utc::now(), + test1: Test1(1), + test11: Some(Test1(1)), + test2: Some(Test2 { + some_id: "test-1".to_string(), + some_bool: Some(true), + }), + test3: vec![ + Test2 { + some_id: "test-2".to_string(), + some_bool: Some(false), + }, + Test2 { + some_id: "test-2".to_string(), + some_bool: Some(true), + }, + ], }; // Remove if it already exist diff --git a/src/errors.rs b/src/errors.rs index f6b910a..b80340e 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -11,7 +11,8 @@ pub enum FirestoreError { DataConflictError(FirestoreDataConflictError), DataNotFoundError(FirestoreDataNotFoundError), InvalidParametersError(FirestoreInvalidParametersError), - SerializeError(FirestoreSerializeError), + SerializeError(FirestoreSerializationError), + DeserializeError(FirestoreSerializationError), NetworkError(FirestoreNetworkError), } @@ -24,6 +25,7 @@ impl Display for FirestoreError { FirestoreError::DataNotFoundError(ref err) => err.fmt(f), FirestoreError::InvalidParametersError(ref err) => err.fmt(f), FirestoreError::SerializeError(ref err) => err.fmt(f), + FirestoreError::DeserializeError(ref err) => err.fmt(f), FirestoreError::NetworkError(ref err) => err.fmt(f), } } @@ -38,6 +40,7 @@ impl Error for FirestoreError { FirestoreError::DataNotFoundError(ref err) => Some(err), FirestoreError::InvalidParametersError(ref err) => Some(err), FirestoreError::SerializeError(ref err) => Some(err), + FirestoreError::DeserializeError(ref err) => Some(err), FirestoreError::NetworkError(ref err) => Some(err), } } @@ -228,7 +231,7 @@ impl serde::ser::Error for FirestoreError { where T: Display, { - FirestoreSerializeError::from_message(msg.to_string()) + FirestoreError::SerializeError(FirestoreSerializationError::from_message(msg.to_string())) } } @@ -237,34 +240,35 @@ impl serde::de::Error for FirestoreError { where T: Display, { - FirestoreSerializeError::from_message(msg.to_string()) + FirestoreError::DeserializeError(FirestoreSerializationError::from_message(msg.to_string())) } } #[derive(Debug, Builder)] -pub struct FirestoreSerializeError { +pub struct FirestoreSerializationError { pub public: FirestoreErrorPublicGenericDetails, } -impl FirestoreSerializeError { - pub fn from_message>(message: S) -> FirestoreError { +impl FirestoreSerializationError { + pub fn from_message>(message: S) -> FirestoreSerializationError { let message_str = message.as_ref().to_string(); - FirestoreError::SerializeError(FirestoreSerializeError::new( - FirestoreErrorPublicGenericDetails::new(message_str), - )) + FirestoreSerializationError::new(FirestoreErrorPublicGenericDetails::new(message_str)) } } -impl Display for FirestoreSerializeError { +impl Display for FirestoreSerializationError { fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { write!(f, "Invalid serialization: {:?}", self.public) } } -impl std::error::Error for FirestoreSerializeError {} +impl std::error::Error for FirestoreSerializationError {} impl From for FirestoreError { fn from(parse_err: chrono::ParseError) -> Self { - FirestoreSerializeError::from_message(format!("Parse error: {}", parse_err)) + FirestoreError::DeserializeError(FirestoreSerializationError::from_message(format!( + "Parse error: {}", + parse_err + ))) } } diff --git a/src/serde_deserializer.rs b/src/serde_deserializer.rs index 521c048..c194645 100644 --- a/src/serde_deserializer.rs +++ b/src/serde_deserializer.rs @@ -1,4 +1,4 @@ -use crate::errors::FirestoreSerializeError; +use crate::errors::FirestoreSerializationError; use crate::{FirestoreError, FirestoreValue}; use chrono::{DateTime, Utc}; use gcloud_sdk::google::firestore::v1::value; @@ -257,8 +257,8 @@ impl<'de> serde::Deserializer<'de> for FirestoreValue { Some(value::ValueType::DoubleValue(v)) => visitor.visit_f64(v), Some(value::ValueType::BytesValue(ref v)) => visitor.visit_bytes(v), Some(value::ValueType::ReferenceValue(v)) => visitor.visit_string(v), - Some(value::ValueType::GeoPointValue(_)) => Err(FirestoreSerializeError::from_message( - "LatLng not supported yet", + Some(value::ValueType::GeoPointValue(_)) => Err(FirestoreError::DeserializeError( + FirestoreSerializationError::from_message("LatLng not supported yet"), )), Some(value::ValueType::TimestampValue(ts)) => { let dt = DateTime::::from_utc( @@ -387,7 +387,11 @@ impl<'de> serde::Deserializer<'de> for FirestoreValue { where V: Visitor<'de>, { - self.deserialize_any(visitor) + match self.value.value_type { + Some(value::ValueType::NullValue(_)) => visitor.visit_none(), + None => visitor.visit_none(), + _ => visitor.visit_some(self), + } } fn deserialize_unit(self, visitor: V) -> Result @@ -405,7 +409,7 @@ impl<'de> serde::Deserializer<'de> for FirestoreValue { where V: Visitor<'de>, { - self.deserialize_any(visitor) + self.deserialize_unit(visitor) } fn deserialize_newtype_struct( @@ -416,7 +420,7 @@ impl<'de> serde::Deserializer<'de> for FirestoreValue { where V: Visitor<'de>, { - self.deserialize_any(visitor) + visitor.visit_newtype_struct(self) } fn deserialize_seq(self, visitor: V) -> Result @@ -442,7 +446,7 @@ impl<'de> serde::Deserializer<'de> for FirestoreValue { where V: Visitor<'de>, { - self.deserialize_any(visitor) + self.deserialize_seq(visitor) } fn deserialize_map(self, visitor: V) -> Result diff --git a/src/serde_serializer.rs b/src/serde_serializer.rs index a5b6199..b45f675 100644 --- a/src/serde_serializer.rs +++ b/src/serde_serializer.rs @@ -387,8 +387,8 @@ impl serde::ser::SerializeMap for SerializeMap { self.next_key = Some(num.to_string()); Ok(()) } - _ => Err(FirestoreSerializeError::from_message( - "Map key should be a string format", + _ => Err(FirestoreError::SerializeError( + FirestoreSerializationError::from_message("Map key should be a string format"), )), } } @@ -403,8 +403,8 @@ impl serde::ser::SerializeMap for SerializeMap { self.fields.insert(key, value.serialize(serializer)?.value); Ok(()) } - None => Err(FirestoreSerializeError::from_message( - "Unexpected map value without key", + None => Err(FirestoreError::SerializeError( + FirestoreSerializationError::from_message("Unexpected map value without key"), )), } } diff --git a/src/serde_types_serializers.rs b/src/serde_types_serializers.rs index 876963e..bedccf3 100644 --- a/src/serde_types_serializers.rs +++ b/src/serde_types_serializers.rs @@ -39,74 +39,98 @@ pub mod serialize_as_timestamp { type SerializeStructVariant = crate::serde_serializer::SerializeStructVariant; fn serialize_bool(self, _v: bool) -> Result { - Err(FirestoreSerializeError::from_message( - "Timestamp serializer doesn't support this type", + Err(FirestoreError::DeserializeError( + FirestoreSerializationError::from_message( + "Timestamp serializer doesn't support this type", + ), )) } fn serialize_i8(self, _v: i8) -> Result { - Err(FirestoreSerializeError::from_message( - "Timestamp serializer doesn't support this type", + Err(FirestoreError::DeserializeError( + FirestoreSerializationError::from_message( + "Timestamp serializer doesn't support this type", + ), )) } fn serialize_i16(self, _v: i16) -> Result { - Err(FirestoreSerializeError::from_message( - "Timestamp serializer doesn't support this type", + Err(FirestoreError::DeserializeError( + FirestoreSerializationError::from_message( + "Timestamp serializer doesn't support this type", + ), )) } fn serialize_i32(self, _v: i32) -> Result { - Err(FirestoreSerializeError::from_message( - "Timestamp serializer doesn't support this type", + Err(FirestoreError::DeserializeError( + FirestoreSerializationError::from_message( + "Timestamp serializer doesn't support this type", + ), )) } fn serialize_i64(self, _v: i64) -> Result { - Err(FirestoreSerializeError::from_message( - "Timestamp serializer doesn't support this type", + Err(FirestoreError::DeserializeError( + FirestoreSerializationError::from_message( + "Timestamp serializer doesn't support this type", + ), )) } fn serialize_u8(self, _v: u8) -> Result { - Err(FirestoreSerializeError::from_message( - "Timestamp serializer doesn't support this type", + Err(FirestoreError::DeserializeError( + FirestoreSerializationError::from_message( + "Timestamp serializer doesn't support this type", + ), )) } fn serialize_u16(self, _v: u16) -> Result { - Err(FirestoreSerializeError::from_message( - "Timestamp serializer doesn't support this type", + Err(FirestoreError::DeserializeError( + FirestoreSerializationError::from_message( + "Timestamp serializer doesn't support this type", + ), )) } fn serialize_u32(self, _v: u32) -> Result { - Err(FirestoreSerializeError::from_message( - "Timestamp serializer doesn't support this type", + Err(FirestoreError::DeserializeError( + FirestoreSerializationError::from_message( + "Timestamp serializer doesn't support this type", + ), )) } fn serialize_u64(self, _v: u64) -> Result { - Err(FirestoreSerializeError::from_message( - "Timestamp serializer doesn't support this type", + Err(FirestoreError::DeserializeError( + FirestoreSerializationError::from_message( + "Timestamp serializer doesn't support this type", + ), )) } fn serialize_f32(self, _v: f32) -> Result { - Err(FirestoreSerializeError::from_message( - "Timestamp serializer doesn't support this type", + Err(FirestoreError::DeserializeError( + FirestoreSerializationError::from_message( + "Timestamp serializer doesn't support this type", + ), )) } fn serialize_f64(self, _v: f64) -> Result { - Err(FirestoreSerializeError::from_message( - "Timestamp serializer doesn't support this type", + Err(FirestoreError::DeserializeError( + FirestoreSerializationError::from_message( + "Timestamp serializer doesn't support this type", + ), )) } fn serialize_char(self, _v: char) -> Result { - Err(FirestoreSerializeError::from_message( - "Timestamp serializer doesn't support this type", + Err(FirestoreError::DeserializeError( + FirestoreSerializationError::from_message( + "Timestamp serializer doesn't support this type", + ), )) } @@ -125,14 +149,18 @@ pub mod serialize_as_timestamp { } fn serialize_bytes(self, _v: &[u8]) -> Result { - Err(FirestoreSerializeError::from_message( - "Timestamp serializer doesn't support this type", + Err(FirestoreError::DeserializeError( + FirestoreSerializationError::from_message( + "Timestamp serializer doesn't support this type", + ), )) } fn serialize_none(self) -> Result { - Err(FirestoreSerializeError::from_message( - "Timestamp serializer doesn't support this type", + Err(FirestoreError::DeserializeError( + FirestoreSerializationError::from_message( + "Timestamp serializer doesn't support this type", + ), )) } @@ -183,20 +211,26 @@ pub mod serialize_as_timestamp { where T: Serialize, { - Err(FirestoreSerializeError::from_message( - "Timestamp serializer doesn't support this type", + Err(FirestoreError::DeserializeError( + FirestoreSerializationError::from_message( + "Timestamp serializer doesn't support this type", + ), )) } fn serialize_seq(self, _len: Option) -> Result { - Err(FirestoreSerializeError::from_message( - "Timestamp serializer doesn't support this type", + Err(FirestoreError::DeserializeError( + FirestoreSerializationError::from_message( + "Timestamp serializer doesn't support this type", + ), )) } fn serialize_tuple(self, _len: usize) -> Result { - Err(FirestoreSerializeError::from_message( - "Timestamp serializer doesn't support this type", + Err(FirestoreError::DeserializeError( + FirestoreSerializationError::from_message( + "Timestamp serializer doesn't support this type", + ), )) } @@ -205,8 +239,10 @@ pub mod serialize_as_timestamp { _name: &'static str, _len: usize, ) -> Result { - Err(FirestoreSerializeError::from_message( - "Timestamp serializer doesn't support this type", + Err(FirestoreError::DeserializeError( + FirestoreSerializationError::from_message( + "Timestamp serializer doesn't support this type", + ), )) } @@ -217,14 +253,18 @@ pub mod serialize_as_timestamp { _variant: &'static str, _len: usize, ) -> Result { - Err(FirestoreSerializeError::from_message( - "Timestamp serializer doesn't support this type", + Err(FirestoreError::DeserializeError( + FirestoreSerializationError::from_message( + "Timestamp serializer doesn't support this type", + ), )) } fn serialize_map(self, _len: Option) -> Result { - Err(FirestoreSerializeError::from_message( - "Timestamp serializer doesn't support this type", + Err(FirestoreError::DeserializeError( + FirestoreSerializationError::from_message( + "Timestamp serializer doesn't support this type", + ), )) } @@ -233,8 +273,10 @@ pub mod serialize_as_timestamp { _name: &'static str, _len: usize, ) -> Result { - Err(FirestoreSerializeError::from_message( - "Timestamp serializer doesn't support this type", + Err(FirestoreError::DeserializeError( + FirestoreSerializationError::from_message( + "Timestamp serializer doesn't support this type", + ), )) } @@ -245,8 +287,10 @@ pub mod serialize_as_timestamp { _variant: &'static str, _len: usize, ) -> Result { - Err(FirestoreSerializeError::from_message( - "Timestamp serializer doesn't support this type", + Err(FirestoreError::DeserializeError( + FirestoreSerializationError::from_message( + "Timestamp serializer doesn't support this type", + ), )) } }