Skip to content

Commit 56ea920

Browse files
Merge pull request #37 from smarty/jacob/international-postal-code-api
Add support for International Postal Code API
2 parents fdca6c3 + d316fea commit 56ea920

File tree

9 files changed

+191
-4
lines changed

9 files changed

+191
-4
lines changed

Makefile

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ clippy:
2626
international_autocomplete_api:
2727
RUST_LOG=trace cargo run --example international_autocomplete_api
2828

29+
international_postal_code_api:
30+
RUST_LOG=trace cargo run --example international_postal_code_api
31+
2932
international_street_api:
3033
RUST_LOG=trace cargo run --example international_street_api
3134

@@ -50,6 +53,6 @@ us_zipcode_api:
5053
us_enrichment_api:
5154
RUST_LOG=trace cargo run --example us_enrichment_api
5255

53-
examples: international_autocomplete_api international_street_api logger us_autocomplete_pro_api us_extract_api us_reverse_geo_api us_street_api us_zipcode_api
56+
examples: international_autocomplete_api international_postal_code_api international_street_api logger us_autocomplete_pro_api us_extract_api us_reverse_geo_api us_street_api us_zipcode_api
5457

55-
.PHONY: clean test dependencies package examples clippy international_autocomplete_api international_street_api logger us_autocomplete_pro_api us_extract_api us_reverse_geo_api us_street_api us_zipcode_api us_enrichment_api
58+
.PHONY: clean test dependencies package examples clippy international_autocomplete_api international_postal_code_api international_street_api logger us_autocomplete_pro_api us_extract_api us_reverse_geo_api us_street_api us_zipcode_api us_enrichment_api

smarty-rust-sdk/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ name = "international_street_api"
5555
[[example]]
5656
name = "international_autocomplete_api"
5757

58+
[[example]]
59+
name = "international_postal_code_api"
60+
5861
[[example]]
5962
name = "logger"
6063

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
extern crate serde_json;
2+
extern crate smarty_rust_sdk;
3+
extern crate tokio;
4+
5+
use smarty_rust_sdk::international_postal_code_api::client::InternationalPostalCodeClient;
6+
use smarty_rust_sdk::international_postal_code_api::lookup::Lookup;
7+
use smarty_rust_sdk::sdk::authentication::SecretKeyCredential;
8+
use smarty_rust_sdk::sdk::options::OptionsBuilder;
9+
use std::error::Error;
10+
11+
#[tokio::main]
12+
async fn main() -> Result<(), Box<dyn Error>> {
13+
let lookup = &mut Lookup {
14+
input_id: "ID-8675309".to_string(),
15+
locality: "Sao Paulo".to_string(),
16+
administrative_area: "SP".to_string(),
17+
country: "Brazil".to_string(),
18+
postal_code: "02516".to_string(),
19+
..Default::default()
20+
};
21+
22+
let authentication = SecretKeyCredential::new(
23+
std::env::var("SMARTY_AUTH_ID").expect("Missing SMARTY_AUTH_ID env variable"),
24+
std::env::var("SMARTY_AUTH_TOKEN").expect("Missing SMARTY_AUTH_TOKEN env variable"),
25+
);
26+
27+
let options = OptionsBuilder::new(Some(authentication))
28+
.with_logging()
29+
.build();
30+
31+
let client = InternationalPostalCodeClient::new(options)?;
32+
33+
client.send(lookup).await?;
34+
35+
println!("{}", serde_json::to_string_pretty(&lookup.results)?);
36+
37+
Ok(())
38+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
use serde::{Deserialize, Serialize};
2+
3+
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
4+
#[serde(default)]
5+
pub struct Candidate {
6+
pub input_id: String,
7+
pub administrative_area: String,
8+
pub sub_administrative_area: String,
9+
pub super_administrative_area: String,
10+
pub country_iso_3: String,
11+
pub locality: String,
12+
pub dependent_locality: String,
13+
pub dependent_locality_name: String,
14+
pub double_dependent_locality: String,
15+
#[serde(rename = "postal_code")]
16+
pub postal_code: String,
17+
pub postal_code_extra: String,
18+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
use crate::international_postal_code_api::candidate::Candidate;
2+
use crate::international_postal_code_api::lookup::Lookup;
3+
use crate::sdk::client::Client;
4+
use crate::sdk::error::SmartyError;
5+
use crate::sdk::options::Options;
6+
use crate::sdk::send_request;
7+
use reqwest::Method;
8+
use smarty_rust_proc_macro::smarty_api;
9+
10+
#[smarty_api(
11+
api_path = "lookup",
12+
default_url = "https://international-postal-code.api.smarty.com/",
13+
lookup_style(lookup),
14+
lookup_type = "Lookup",
15+
result_type = "Vec<Candidate>"
16+
)]
17+
pub struct InternationalPostalCodeClient;
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
use crate::international_postal_code_api::candidate::Candidate;
2+
use crate::sdk::has_param;
3+
4+
#[derive(Clone, Debug, PartialEq, Default)]
5+
pub struct Lookup {
6+
pub input_id: String,
7+
pub country: String,
8+
pub locality: String,
9+
pub administrative_area: String,
10+
pub postal_code: String,
11+
12+
pub results: Vec<Candidate>,
13+
}
14+
15+
impl Lookup {
16+
pub(crate) fn into_param_array(self) -> Vec<(String, String)> {
17+
vec![
18+
has_param("input_id".to_string(), self.input_id),
19+
has_param("country".to_string(), self.country),
20+
has_param("locality".to_string(), self.locality),
21+
has_param("administrative_area".to_string(), self.administrative_area),
22+
has_param("postal_code".to_string(), self.postal_code),
23+
]
24+
.into_iter()
25+
.filter_map(std::convert::identity)
26+
.collect()
27+
}
28+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
pub mod candidate;
2+
pub mod client;
3+
pub mod lookup;
4+
5+
#[cfg(test)]
6+
mod tests {
7+
use crate::international_postal_code_api::candidate::Candidate;
8+
use crate::international_postal_code_api::client::InternationalPostalCodeClient;
9+
use crate::international_postal_code_api::lookup::Lookup;
10+
use crate::sdk::options::OptionsBuilder;
11+
use serde_json::from_str;
12+
13+
#[test]
14+
fn client_test() {
15+
let client = InternationalPostalCodeClient::new(OptionsBuilder::new(None).build()).unwrap();
16+
17+
assert_eq!(
18+
client.client.url.to_string(),
19+
"https://international-postal-code.api.smarty.com/lookup".to_string()
20+
);
21+
}
22+
23+
#[test]
24+
fn lookup_test() {
25+
let lookup = Lookup {
26+
input_id: "ID-8675309".to_string(),
27+
locality: "Sao Paulo".to_string(),
28+
administrative_area: "SP".to_string(),
29+
country: "Brazil".to_string(),
30+
postal_code: "02516".to_string(),
31+
..Default::default()
32+
};
33+
34+
let expected_params = vec![
35+
("input_id".to_string(), "ID-8675309".to_string()),
36+
("country".to_string(), "Brazil".to_string()),
37+
("locality".to_string(), "Sao Paulo".to_string()),
38+
("administrative_area".to_string(), "SP".to_string()),
39+
("postal_code".to_string(), "02516".to_string()),
40+
];
41+
42+
assert_eq!(lookup.into_param_array(), expected_params);
43+
}
44+
45+
#[test]
46+
fn candidate_test() {
47+
let payload = r#"[
48+
{
49+
"input_id": "ID-8675309",
50+
"administrative_area": "SP",
51+
"sub_administrative_area": "Greater Sao Paulo",
52+
"super_administrative_area": "Southeast",
53+
"country_iso_3": "BRA",
54+
"locality": "Sao Paulo",
55+
"dependent_locality": "Vila Guilherme",
56+
"dependent_locality_name": "Santana",
57+
"double_dependent_locality": "Zona Norte",
58+
"postal_code": "02516",
59+
"postal_code_extra": "050"
60+
}
61+
]"#;
62+
63+
let candidates: Vec<Candidate> = from_str(payload).expect("Failed to deserialize JSON");
64+
assert_eq!(candidates.len(), 1);
65+
66+
let candidate = &candidates[0];
67+
assert_eq!(candidate.input_id, "ID-8675309");
68+
assert_eq!(candidate.country_iso_3, "BRA");
69+
assert_eq!(candidate.locality, "Sao Paulo");
70+
assert_eq!(candidate.dependent_locality, "Vila Guilherme");
71+
assert_eq!(candidate.dependent_locality_name, "Santana");
72+
assert_eq!(candidate.double_dependent_locality, "Zona Norte");
73+
assert_eq!(candidate.administrative_area, "SP");
74+
assert_eq!(candidate.sub_administrative_area, "Greater Sao Paulo");
75+
assert_eq!(candidate.super_administrative_area, "Southeast");
76+
assert_eq!(candidate.postal_code, "02516");
77+
assert_eq!(candidate.postal_code_extra, "050");
78+
}
79+
}

smarty-rust-sdk/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
pub mod international_autocomplete_api;
2+
pub mod international_postal_code_api;
23
pub mod international_street_api;
34
pub mod sdk;
45
pub mod us_autocomplete_pro_api;

smarty-rust-sdk/src/sdk/client.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@ impl Client {
5454
if let Some(auth) = &self.options.authentication {
5555
builder = auth.authenticate(builder);
5656
}
57-
57+
5858
if !self.options.license.is_empty() {
59-
builder = builder.query(&[("license".to_string(), self.options.license.clone())]);
59+
builder = builder.query(&[("license".to_string(), self.options.license.clone())]);
6060
}
6161

6262
for (header_key, header_value) in self.options.headers.clone() {

0 commit comments

Comments
 (0)