smarty_rust_sdk/sdk/
mod.rs

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