Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ us_reverse_geo_api:
RUST_LOG=trace cargo run --example us_reverse_geo_api

us_street_api:
RUST_LOG=trace cargo run --example us_street_api
RUST_LOG=trace cargo run --example us_street_api && RUST_LOG=trace cargo run --example us_street_component_analysis

us_zipcode_api:
RUST_LOG=trace cargo run --example us_zipcode_api
Expand Down
47 changes: 47 additions & 0 deletions smarty-rust-sdk/examples/us_street_component_analysis.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
extern crate serde_json;
extern crate smarty_rust_sdk;
extern crate tokio;

use smarty_rust_sdk::us_street_api::lookup::{Lookup, MatchStrategy};

use smarty_rust_sdk::sdk::authentication::SecretKeyCredential;
use smarty_rust_sdk::sdk::batch::Batch;
use smarty_rust_sdk::sdk::options::OptionsBuilder;
use smarty_rust_sdk::us_street_api::client::USStreetAddressClient;
use std::error::Error;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let lookup = Lookup {
street: "1600 Amphitheatre Pkwy".to_string(),
last_line: "Mountain View, CA".to_string(),
max_candidates: 10,
match_strategy: MatchStrategy::Enhanced, // Enhanced matching is required to return component analysis results.
..Default::default()
};

let mut batch = Batch::default();
batch.push(lookup)?;

let authentication = SecretKeyCredential::new(
std::env::var("SMARTY_AUTH_ID").expect("Missing SMARTY_AUTH_ID env variable"),
std::env::var("SMARTY_AUTH_TOKEN").expect("Missing SMARTY_AUTH_TOKEN env variable"),
);

let options = OptionsBuilder::new(Some(authentication))
.with_component_analysis() // To add component analysis feature you need to specify when you create the options for the client.
.build();

let client = USStreetAddressClient::new(options)?;

client.send(&mut batch).await?;

// Here is an example of how to access component analysis
for record in batch.records() {
if !record.results.is_empty() {
println!("Component Analysis Results:\n {}",serde_json::to_string_pretty(&record.results[0].analysis.components)?);
}
}

Ok(())
}
27 changes: 27 additions & 0 deletions smarty-rust-sdk/src/us_street_api/candidate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,31 @@ pub struct Analysis {
pub suitelink_match: bool,
pub ews_match: bool,
pub enhanced_match: String,
pub components: ComponentAnalysis,
}

#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(default)]
pub struct MatchInfo {
pub status: String,
pub change: Vec<String>,
}

#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(default)]
pub struct ComponentAnalysis {
pub primary_number: MatchInfo,
pub street_predirection: MatchInfo,
pub street_name: MatchInfo,
pub street_postdirection: MatchInfo,
pub street_suffix: MatchInfo,
pub secondary_number: MatchInfo,
pub secondary_designator: MatchInfo,
pub extra_secondary_number: MatchInfo,
pub extra_secondary_designator: MatchInfo,
pub city_name: MatchInfo,
pub state_abbreviation: MatchInfo,
pub zipcode: MatchInfo,
pub plus4_code: MatchInfo,
pub urbanization: MatchInfo,
}
237 changes: 237 additions & 0 deletions smarty-rust-sdk/src/us_street_api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ mod tests {
use crate::sdk::options::OptionsBuilder;
use crate::us_street_api::client::USStreetAddressClient;
use crate::us_street_api::lookup::{Lookup, MatchStrategy};
use serde_json::json;
use crate::us_street_api::candidate::Candidate;

#[test]
fn client_test() {
Expand Down Expand Up @@ -71,4 +73,239 @@ mod tests {
);
assert_eq!(batch.records().len(), 4);
}

#[test]
fn full_candidate_test_with_top_level_fields() {
let data = json!({
"input_id": "1234",
"candidate_index": 0,
"delivery_line_1": "1600 Amphitheatre Pkwy",
"delivery_line_2": "Ste 100",
"last_line": "Mountain View CA 94043-1351",
"delivery_point_barcode": "940431351000",
"components": {
"urbanization": "URB",
"primary_number": "1600",
"street_name": "Amphitheatre",
"street_predirection": "N",
"street_postdirection": "W",
"street_suffix": "Pkwy",
"secondary_number": "100",
"secondary_designator": "Ste",
"extra_secondary_number": "200",
"extra_secondary_designator": "Apt",
"pmb_designator": "PMB",
"pmb_number": "300",
"city_name": "Mountain View",
"default_city_name": "Mountain View",
"state_abbreviation": "CA",
"zipcode": "94043",
"plus4_code": "1351",
"delivery_point": "00",
"delivery_point_check_digit": "1"
},
"metadata": {
"record_type": "S",
"zip_type": "Standard",
"county_fips": "06085",
"county_name": "Santa Clara",
"carrier_route": "C001",
"congressional_district": "18",
"building_default_indicator": "Y",
"rdi": "Residential",
"elot_sequence": "0056",
"elot_sort": "A",
"latitude": 37.422,
"longitude": -122.084,
"precision": "Zip9",
"time_zone": "Pacific",
"utc_offset": -8.0,
"dst": true,
"ews_match": false
},
"analysis": {
"dpv_match_code": "Y",
"dpv_footnotes": "AABB",
"dpv_cmra": "N",
"dpv_vacant": "N",
"dpv_no_stat": "N",
"active": "Y",
"ews_match": false,
"footnotes": "N#",
"lacslink_code": "L",
"lacslink_indicator": "Y",
"suitelink_match": true,
"enhanced_match": "Y",
"components": {
"primary_number": {
"status": "confirmed",
"change": ["added"]
},
"street_predirection": {
"status": "unconfirmed",
"change": ["spelling"]
},
"street_name": {
"status": "confirmed",
"change": ["replaced"]
},
"street_postdirection": {
"status": "confirmed",
"change": []
},
"street_suffix": {
"status": "confirmed",
"change": ["spelling"]
},
"secondary_number": {
"status": "unconfirmed",
"change": ["added"]
},
"secondary_designator": {
"status": "confirmed",
"change": ["replaced"]
},
"extra_secondary_number": {
"status": "confirmed",
"change": ["spelling"]
},
"extra_secondary_designator": {
"status": "confirmed",
"change": ["added"]
},
"city_name": {
"status": "unconfirmed",
"change": ["replaced"]
},
"state_abbreviation": {
"status": "confirmed",
"change": []
},
"zipcode": {
"status": "confirmed",
"change": ["spelling"]
},
"plus4_code": {
"status": "confirmed",
"change": ["added"]
},
"urbanization": {
"status": "unconfirmed",
"change": []
}
}
}
});

let candidate: Candidate = serde_json::from_value(data).unwrap();

// Top-level
assert_eq!(candidate.input_id, "1234");
assert_eq!(candidate.candidate_index, 0);
assert_eq!(candidate.delivery_line_1, "1600 Amphitheatre Pkwy");
assert_eq!(candidate.delivery_line_2, "Ste 100");
assert_eq!(candidate.last_line, "Mountain View CA 94043-1351");
assert_eq!(candidate.delivery_point_barcode, "940431351000");

// Components
let c = &candidate.components;
assert_eq!(c.urbanization, "URB");
assert_eq!(c.primary_number, "1600");
assert_eq!(c.street_name, "Amphitheatre");
assert_eq!(c.street_predirection, "N");
assert_eq!(c.street_postdirection, "W");
assert_eq!(c.street_suffix, "Pkwy");
assert_eq!(c.secondary_number, "100");
assert_eq!(c.secondary_designator, "Ste");
assert_eq!(c.extra_secondary_number, "200");
assert_eq!(c.extra_secondary_designator, "Apt");
assert_eq!(c.pmb_designator, "PMB");
assert_eq!(c.pmb_number, "300");
assert_eq!(c.city_name, "Mountain View");
assert_eq!(c.default_city_name, "Mountain View");
assert_eq!(c.state_abbreviation, "CA");
assert_eq!(c.zipcode, "94043");
assert_eq!(c.plus4_code, "1351");
assert_eq!(c.delivery_point, "00");
assert_eq!(c.delivery_point_check_digit, "1");

// Metadata
let m = &candidate.metadata;
assert_eq!(m.record_type, "S");
assert_eq!(m.zip_type, "Standard");
assert_eq!(m.county_fips, "06085");
assert_eq!(m.county_name, "Santa Clara");
assert_eq!(m.carrier_route, "C001");
assert_eq!(m.congressional_district, "18");
assert_eq!(m.building_default_indicator, "Y");
assert_eq!(m.rdi, "Residential");
assert_eq!(m.elot_sequence, "0056");
assert_eq!(m.elot_sort, "A");
assert_eq!(m.latitude, 37.422);
assert_eq!(m.longitude, -122.084);
assert_eq!(m.precision, "Zip9");
assert_eq!(m.time_zone, "Pacific");
assert_eq!(m.utc_offset, -8.0);
assert!(m.dst);
assert!(!m.ews_match);

// Analysis
let a = &candidate.analysis;
assert_eq!(a.dpv_match_code, "Y");
assert_eq!(a.dpv_footnotes, "AABB");
assert_eq!(a.dpv_cmra, "N");
assert_eq!(a.dpv_vacant, "N");
assert_eq!(a.active, "Y");
assert!(!a.ews_match);
assert_eq!(a.footnotes, "N#");
assert_eq!(a.lacslink_code, "L");
assert_eq!(a.lacslink_indicator, "Y");
assert!(a.suitelink_match);
assert_eq!(a.dpv_no_stat, "N");
assert_eq!(a.enhanced_match, "Y");

// Component Analysis (nested)
let ca = &a.components;
assert_eq!(ca.primary_number.status, "confirmed");
assert_eq!(ca.primary_number.change, vec!["added"]);

assert_eq!(ca.street_predirection.status, "unconfirmed");
assert_eq!(ca.street_predirection.change, vec!["spelling"]);

assert_eq!(ca.street_name.status, "confirmed");
assert_eq!(ca.street_name.change, vec!["replaced"]);

assert_eq!(ca.street_postdirection.status, "confirmed");
assert!(ca.street_postdirection.change.is_empty());

assert_eq!(ca.street_suffix.status, "confirmed");
assert_eq!(ca.street_suffix.change, vec!["spelling"]);

assert_eq!(ca.secondary_number.status, "unconfirmed");
assert_eq!(ca.secondary_number.change, vec!["added"]);

assert_eq!(ca.secondary_designator.status, "confirmed");
assert_eq!(ca.secondary_designator.change, vec!["replaced"]);

assert_eq!(ca.extra_secondary_number.status, "confirmed");
assert_eq!(ca.extra_secondary_number.change, vec!["spelling"]);

assert_eq!(ca.extra_secondary_designator.status, "confirmed");
assert_eq!(ca.extra_secondary_designator.change, vec!["added"]);

assert_eq!(ca.city_name.status, "unconfirmed");
assert_eq!(ca.city_name.change, vec!["replaced"]);

assert_eq!(ca.state_abbreviation.status, "confirmed");
assert!(ca.state_abbreviation.change.is_empty());

assert_eq!(ca.zipcode.status, "confirmed");
assert_eq!(ca.zipcode.change, vec!["spelling"]);

assert_eq!(ca.plus4_code.status, "confirmed");
assert_eq!(ca.plus4_code.change, vec!["added"]);

assert_eq!(ca.urbanization.status, "unconfirmed");
assert!(ca.urbanization.change.is_empty());
}
}