smarty_rust_sdk/sdk/
mod.rs1use crate::sdk::error::SmartyError;
2use reqwest::Response;
3use reqwest_middleware::RequestBuilder;
4use serde::de::DeserializeOwned;
5use serde_repr::{Deserialize_repr, Serialize_repr};
6use std::fmt::{Display, Formatter};
7
8pub mod authentication;
9pub mod batch;
10pub mod client;
11pub mod error;
12pub mod logging;
13pub mod options;
14pub mod retry_strategy;
15
16pub const VERSION: &str = env!("CARGO_PKG_VERSION");
17pub const MAX_BATCH_SIZE: usize = 100;
18
19#[derive(Default, Debug, Clone, PartialEq, Serialize_repr, Deserialize_repr)]
20#[repr(u8)]
21pub enum CoordinateLicense {
22 #[default]
23 CoordinateLicenseSmartyStreets = 0,
24 CoordinateLicenseSmartyStreetsProprietary = 1,
25}
26
27impl Display for CoordinateLicense {
28 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
29 match self {
30 CoordinateLicense::CoordinateLicenseSmartyStreets => {
31 write!(f, "SmartyStreets")
32 }
33 CoordinateLicense::CoordinateLicenseSmartyStreetsProprietary => {
34 write!(f, "SmartyStreets Proprietary")
35 }
36 }
37 }
38}
39
40pub(crate) async fn send_request_full(request: RequestBuilder) -> Result<Response, SmartyError> {
41 request.send().await.map_err(|e| match e {
42 reqwest_middleware::Error::Middleware(e) => SmartyError::from(e),
43 reqwest_middleware::Error::Reqwest(e) => SmartyError::from(e),
44 })
45}
46
47pub(crate) async fn parse_response_json<C: DeserializeOwned>(
48 response: Response,
49) -> Result<C, SmartyError> {
50 if !response.status().is_success() {
51 let status_code = response.status();
52 let body = response.text().await?;
53
54 return Err(SmartyError::HttpError {
55 code: status_code,
56 detail: body,
57 });
58 }
59
60 Ok(response.json::<C>().await?)
61}
62
63pub(crate) async fn send_request<C: DeserializeOwned>(
64 request: RequestBuilder,
65) -> Result<C, SmartyError> {
66 let response = send_request_full(request).await?;
67 parse_response_json(response).await
68}
69
70#[allow(clippy::trivially_copy_pass_by_ref)]
72pub(crate) fn is_zero(num: &i64) -> bool {
73 *num == 0
74}
75
76pub(crate) fn has_param<P: PartialEq + Display + Default>(
77 name: String,
78 param: P,
79) -> Option<(String, String)> {
80 if param != P::default() {
81 Some((name, param.to_string()))
82 } else {
83 None
84 }
85}
86
87pub(crate) fn has_vec_param(
88 name: String,
89 separator: &'static str,
90 param: Vec<String>,
91) -> Option<(String, String)> {
92 if !param.is_empty() {
93 Some((name, param.join(separator)))
94 } else {
95 None
96 }
97}
98
99#[cfg(test)]
101mod tests {
102 use crate::sdk::authentication::SecretKeyCredential;
103 use crate::sdk::batch::Batch;
104 use crate::sdk::client::Client;
105 use crate::sdk::options::OptionsBuilder;
106
107 #[test]
108 fn batch_test() {
109 let lookup = "Hello World".to_string();
110 let mut batch = Batch::default();
111 batch.push(lookup).unwrap();
112
113 assert_eq!(batch.len(), 1);
114 assert_eq!(batch.records()[0], "Hello World".to_string())
115 }
116
117 #[test]
118 fn authentication_test() {
119 let authentication = SecretKeyCredential::new("1234".to_string(), "ABCD".to_string());
120
121 assert_eq!(authentication.auth_id, "1234".to_string());
122 assert_eq!(authentication.auth_token, "ABCD".to_string());
123 }
124
125 #[test]
126 fn client_test() {
127 let client = Client::new(
128 "https://www.smarty.com".parse().unwrap(),
129 OptionsBuilder::new(None).build(),
130 "docs",
131 )
132 .unwrap();
133
134 assert_eq!(client.url.to_string(), "https://www.smarty.com/docs");
135 }
136}