1use std::borrow::Cow;
2
3use reqwest::header::CONTENT_TYPE;
4use serde::Serialize;
5
6use crate::{
7 CreatePostcardError, CreatePostcardResponse, WrapperApiError,
8 constants::{APPLICATION_JSON, IDEMPOTENCY_KEY},
9};
10
11pub struct CreatePostcardRequest<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, Merge> {
12 pub(crate) client: reqwest::Client,
13 pub(crate) api_key: &'a str,
14 pub(crate) url: Cow<'b, str>,
15 pub(crate) idempotency_key: &'c str,
16 pub(crate) json_request: JsonRequest<'d, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, Merge>,
17}
18
19pub struct CreatePostcardRequestNoMerge<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l> {
20 pub(crate) client: reqwest::Client,
21 pub(crate) api_key: &'a str,
22 pub(crate) url: Cow<'b, str>,
23 pub(crate) idempotency_key: &'c str,
24 pub(crate) json_request: JsonRequestNoMerge<'d, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l>,
25}
26
27#[derive(Serialize)]
28pub struct JsonRequest<'d, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, Merge> {
29 pub(crate) to: To<'d, 'e, 'f, 'g, 'h, 'i>,
30 pub(crate) front: &'j str,
31 pub(crate) back: &'k str,
32 pub(crate) size: Size,
33 pub(crate) mail_type: MailType,
34 pub(crate) merge_variables: Merge,
35 pub(crate) description: &'l str,
36 pub(crate) use_type: UseType,
37}
38
39#[derive(Serialize)]
40pub struct JsonRequestNoMerge<'d, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l> {
41 pub(crate) to: To<'d, 'e, 'f, 'g, 'h, 'i>,
42 pub(crate) front: &'j str,
43 pub(crate) back: &'k str,
44 pub(crate) size: Size,
45 pub(crate) mail_type: MailType,
46 pub(crate) description: &'l str,
47 pub(crate) use_type: UseType,
48}
49
50#[derive(Serialize)]
51pub struct To<'d, 'e, 'f, 'g, 'h, 'i> {
52 pub(crate) name: &'d str,
53 #[serde(rename = "address_line1")]
54 pub(crate) address_line_1: &'e str,
55 #[serde(rename = "address_line2")]
56 pub(crate) address_line_2: Option<&'f str>,
57 pub(crate) address_city: &'g str,
58 pub(crate) address_state: &'h str,
59 pub(crate) address_zip: &'i str,
60}
61
62#[derive(Serialize)]
63#[serde(rename_all = "lowercase")]
64pub enum UseType {
66 Marketing,
68
69 Operational,
71}
72
73#[derive(Serialize)]
74pub enum Size {
76 #[serde(rename = "4x6")]
77 FourBySix,
78 #[serde(rename = "6x9")]
79 SixByNine,
80 #[serde(rename = "6x11")]
81 SixByEleven,
82}
83
84#[derive(Serialize)]
86#[serde(rename_all = "snake_case")]
87pub enum MailType {
88 UspsFirstClass,
90 UspsStandard,
92}
93
94impl<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, Merge: Serialize>
95 CreatePostcardRequest<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, Merge>
96{
97 pub async fn send(self) -> Result<CreatePostcardResponse, CreatePostcardError> {
98 let request = serde_json::to_string(&self.json_request)?;
99
100 let src = self
101 .client
102 .post(self.url.as_ref())
103 .header(CONTENT_TYPE, APPLICATION_JSON)
104 .header(IDEMPOTENCY_KEY, self.idempotency_key)
105 .basic_auth::<_, &str>(self.api_key, None)
106 .body(request)
107 .send()
108 .await?
109 .text()
110 .await?;
111
112 if let Ok(wrapper_api_error) = serde_json::from_str::<WrapperApiError>(src.as_str()) {
113 return Err(CreatePostcardError::Api(wrapper_api_error.error));
114 }
115
116 match serde_json::from_str(src.as_str()) {
117 Ok(ok) => Ok(ok),
118 Err(err) => Err(CreatePostcardError::Json(err, src)),
119 }
120 }
121}
122
123impl<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l>
124 CreatePostcardRequestNoMerge<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l>
125{
126 pub async fn send(self) -> Result<CreatePostcardResponse, CreatePostcardError> {
127 let request = serde_json::to_string(&self.json_request)?;
128
129 let src = self
130 .client
131 .post(self.url.as_ref())
132 .header(CONTENT_TYPE, APPLICATION_JSON)
133 .header(IDEMPOTENCY_KEY, self.idempotency_key)
134 .basic_auth::<&str, &str>(self.api_key, None)
135 .body(request)
136 .send()
137 .await?
138 .text()
139 .await?;
140
141 if let Ok(wrapper_api_error) = serde_json::from_str::<WrapperApiError>(src.as_str()) {
142 return Err(CreatePostcardError::Api(wrapper_api_error.error));
143 }
144
145 match serde_json::from_str(src.as_str()) {
146 Ok(ok) => Ok(ok),
147 Err(err) => Err(CreatePostcardError::Json(err, src)),
148 }
149 }
150}