Skip to content

Commit

Permalink
fix parsing null email fields
Browse files Browse the repository at this point in the history
  • Loading branch information
AntoniosBarotsis committed Jul 11, 2024
1 parent 5c7af6d commit b674f84
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 5 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,17 @@ and this project adheres to

<!-- ## [Unreleased] -->

## [0.8.1] - 2024-07-11

### Changed

- `Email.text` is now optional

### Fixed

- The `cc`, `bcc` and `text` fields of the `Email` struct are nullable which broke deserialization.
It now works as expected.

## [0.8.0] - 2024-07-05

### Added
Expand Down Expand Up @@ -123,6 +134,7 @@ Disabled `reqwest`'s default features and enabled `rustls-tls`.

Initial release.

[0.8.1]: https://crates.io/crates/resend-rs/0.8.1
[0.8.0]: https://crates.io/crates/resend-rs/0.8.0
[0.7.0]: https://crates.io/crates/resend-rs/0.7.0
[0.6.0]: https://crates.io/crates/resend-rs/0.6.0
Expand Down
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[package]
name = "resend-rs"
version = "0.8.0"
version = "0.8.1"
edition = "2021"

license = "MIT"
Expand Down Expand Up @@ -34,4 +34,5 @@ governor = "0.6.3"
rand = "0.8.5"

[dev-dependencies]
serde_json = "1.0.120"
tokio = { version = "1.37.0", features = ["macros", "test-util", "rt-multi-thread"] }
73 changes: 69 additions & 4 deletions src/emails.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::sync::Arc;

use reqwest::Method;
use serde::{Deserialize, Deserializer};

use crate::types::{CreateEmailBaseOptions, CreateEmailResponse, Email};
use crate::{Config, Result};
Expand Down Expand Up @@ -33,8 +34,6 @@ impl EmailsSvc {

let request = self.0.build(Method::GET, &path);
let response = self.0.send(request).await?;
// dbg!(response.text().await);
// todo!();
let content = response.json::<Email>().await?;

Ok(content)
Expand All @@ -48,6 +47,8 @@ pub mod types {
use ecow::EcoString;
use serde::{Deserialize, Serialize};

use crate::emails::parse_nullable_vec;

/// Unique [`Email`] identifier.
#[derive(Debug, Clone, Deserialize)]
pub struct EmailId(EcoString);
Expand Down Expand Up @@ -350,11 +351,13 @@ pub mod types {
/// The HTML body of the email.
pub html: Option<String>,
/// The plain text body of the email.
pub text: String,
pub text: Option<String>,

/// The email addresses of the blind carbon copy recipients.
#[serde(deserialize_with = "parse_nullable_vec")]
pub bcc: Vec<String>,
/// The email addresses of the carbon copy recipients.
#[serde(deserialize_with = "parse_nullable_vec")]
pub cc: Vec<String>,
/// The email addresses to which replies should be sent.
pub reply_to: Option<Vec<String>>,
Expand All @@ -363,9 +366,20 @@ pub mod types {
}
}

/// Turns:
/// - `null` -> `[]`
/// - `["text"]` -> `["text"]`
fn parse_nullable_vec<'de, D>(deserializer: D) -> Result<Vec<String>, D::Error>
where
D: Deserializer<'de>,
{
let opt = Option::deserialize(deserializer)?;
Ok(opt.unwrap_or_else(Vec::new))
}

#[cfg(test)]
mod test {
use crate::types::{CreateEmailBaseOptions, Tag};
use crate::types::{CreateEmailBaseOptions, Email, Tag};
use crate::{tests::CLIENT, Resend, Result};

#[tokio::test]
Expand Down Expand Up @@ -393,6 +407,57 @@ mod test {
Ok(())
}

#[test]
fn deserialize_test() {
let email = r#"{
"object": "email",
"id": "6757a66c-3a5b-49ee-98cc-fca7a5f423c0",
"to": [
"[email protected]"
],
"from": "[email protected]>",
"created_at": "2024-07-11 07:49:53.682607+00",
"subject": "Subject",
"bcc": null,
"cc": null,
"reply_to": null,
"last_event": "delivered",
"html": "<div></div>",
"text": null
}"#;

let res = serde_json::from_str::<Email>(email);
assert!(res.is_ok());
let res = res.unwrap();
assert!(res.cc.is_empty());
assert!(res.bcc.is_empty());
assert!(res.text.is_none());

let email = r#"{
"object": "email",
"id": "6757a66c-3a5b-49ee-98cc-fca7a5f423c0",
"to": [
"[email protected]"
],
"from": "[email protected]>",
"created_at": "2024-07-11 07:49:53.682607+00",
"subject": "Subject",
"bcc": ["hello", "world"],
"cc": ["!"],
"reply_to": null,
"last_event": "delivered",
"html": "<div></div>",
"text": "Not null"
}"#;

let res = serde_json::from_str::<Email>(email);
assert!(res.is_ok());
let res = res.unwrap();
assert!(!res.cc.is_empty());
assert!(!res.bcc.is_empty());
assert!(res.text.is_some());
}

#[test]
#[cfg(feature = "blocking")]
fn all_blocking() -> Result<()> {
Expand Down

0 comments on commit b674f84

Please sign in to comment.