Skip to content

Commit

Permalink
Bugfixes and error handling updates
Browse files Browse the repository at this point in the history
  • Loading branch information
abdolence committed Sep 7, 2022
1 parent 2cf450b commit c630049
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 67 deletions.
29 changes: 29 additions & 0 deletions examples/timestamp-serialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ pub fn config_env_var(name: &str) -> Result<String, String> {
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<bool>,
}

// Example structure to play with
#[derive(Debug, Clone, Deserialize, Serialize)]
struct MyTestStructure {
Expand All @@ -15,6 +24,10 @@ struct MyTestStructure {
some_num: u64,
#[serde(with = "firestore::serialize_as_timestamp")]
created_at: DateTime<Utc>,
test1: Test1,
test11: Option<Test1>,
test2: Option<Test2>,
test3: Vec<Test2>,
}

#[tokio::main]
Expand All @@ -36,6 +49,22 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
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
Expand Down
28 changes: 16 additions & 12 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ pub enum FirestoreError {
DataConflictError(FirestoreDataConflictError),
DataNotFoundError(FirestoreDataNotFoundError),
InvalidParametersError(FirestoreInvalidParametersError),
SerializeError(FirestoreSerializeError),
SerializeError(FirestoreSerializationError),
DeserializeError(FirestoreSerializationError),
NetworkError(FirestoreNetworkError),
}

Expand All @@ -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),
}
}
Expand All @@ -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),
}
}
Expand Down Expand Up @@ -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()))
}
}

Expand All @@ -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<S: AsRef<str>>(message: S) -> FirestoreError {
impl FirestoreSerializationError {
pub fn from_message<S: AsRef<str>>(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<chrono::ParseError> 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
)))
}
}
18 changes: 11 additions & 7 deletions src/serde_deserializer.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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::<Utc>::from_utc(
Expand Down Expand Up @@ -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<V>(self, visitor: V) -> Result<V::Value, Self::Error>
Expand All @@ -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<V>(
Expand All @@ -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<V>(self, visitor: V) -> Result<V::Value, Self::Error>
Expand All @@ -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<V>(self, visitor: V) -> Result<V::Value, Self::Error>
Expand Down
8 changes: 4 additions & 4 deletions src/serde_serializer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
)),
}
}
Expand All @@ -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"),
)),
}
}
Expand Down
Loading

0 comments on commit c630049

Please sign in to comment.