Skip to content

Commit fdca6c3

Browse files
authored
Merge pull request #36 from smarty/comp-analysis
Component Analysis
2 parents 3806d2c + 0434602 commit fdca6c3

File tree

4 files changed

+312
-1
lines changed

4 files changed

+312
-1
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ us_reverse_geo_api:
4242
RUST_LOG=trace cargo run --example us_reverse_geo_api
4343

4444
us_street_api:
45-
RUST_LOG=trace cargo run --example us_street_api
45+
RUST_LOG=trace cargo run --example us_street_api && RUST_LOG=trace cargo run --example us_street_component_analysis
4646

4747
us_zipcode_api:
4848
RUST_LOG=trace cargo run --example us_zipcode_api
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
extern crate serde_json;
2+
extern crate smarty_rust_sdk;
3+
extern crate tokio;
4+
5+
use smarty_rust_sdk::us_street_api::lookup::{Lookup, MatchStrategy};
6+
7+
use smarty_rust_sdk::sdk::authentication::SecretKeyCredential;
8+
use smarty_rust_sdk::sdk::batch::Batch;
9+
use smarty_rust_sdk::sdk::options::OptionsBuilder;
10+
use smarty_rust_sdk::us_street_api::client::USStreetAddressClient;
11+
use std::error::Error;
12+
13+
#[tokio::main]
14+
async fn main() -> Result<(), Box<dyn Error>> {
15+
let lookup = Lookup {
16+
street: "1600 Amphitheatre Pkwy".to_string(),
17+
last_line: "Mountain View, CA".to_string(),
18+
max_candidates: 10,
19+
match_strategy: MatchStrategy::Enhanced, // Enhanced matching is required to return component analysis results.
20+
..Default::default()
21+
};
22+
23+
let mut batch = Batch::default();
24+
batch.push(lookup)?;
25+
26+
let authentication = SecretKeyCredential::new(
27+
std::env::var("SMARTY_AUTH_ID").expect("Missing SMARTY_AUTH_ID env variable"),
28+
std::env::var("SMARTY_AUTH_TOKEN").expect("Missing SMARTY_AUTH_TOKEN env variable"),
29+
);
30+
31+
let options = OptionsBuilder::new(Some(authentication))
32+
.with_component_analysis() // To add component analysis feature you need to specify when you create the options for the client.
33+
.build();
34+
35+
let client = USStreetAddressClient::new(options)?;
36+
37+
client.send(&mut batch).await?;
38+
39+
// Here is an example of how to access component analysis
40+
for record in batch.records() {
41+
if !record.results.is_empty() {
42+
println!("Component Analysis Results:\n {}",serde_json::to_string_pretty(&record.results[0].analysis.components)?);
43+
}
44+
}
45+
46+
Ok(())
47+
}

smarty-rust-sdk/src/us_street_api/candidate.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,4 +83,31 @@ pub struct Analysis {
8383
pub suitelink_match: bool,
8484
pub ews_match: bool,
8585
pub enhanced_match: String,
86+
pub components: ComponentAnalysis,
87+
}
88+
89+
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
90+
#[serde(default)]
91+
pub struct MatchInfo {
92+
pub status: String,
93+
pub change: Vec<String>,
94+
}
95+
96+
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
97+
#[serde(default)]
98+
pub struct ComponentAnalysis {
99+
pub primary_number: MatchInfo,
100+
pub street_predirection: MatchInfo,
101+
pub street_name: MatchInfo,
102+
pub street_postdirection: MatchInfo,
103+
pub street_suffix: MatchInfo,
104+
pub secondary_number: MatchInfo,
105+
pub secondary_designator: MatchInfo,
106+
pub extra_secondary_number: MatchInfo,
107+
pub extra_secondary_designator: MatchInfo,
108+
pub city_name: MatchInfo,
109+
pub state_abbreviation: MatchInfo,
110+
pub zipcode: MatchInfo,
111+
pub plus4_code: MatchInfo,
112+
pub urbanization: MatchInfo,
86113
}

smarty-rust-sdk/src/us_street_api/mod.rs

Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ mod tests {
99
use crate::sdk::options::OptionsBuilder;
1010
use crate::us_street_api::client::USStreetAddressClient;
1111
use crate::us_street_api::lookup::{Lookup, MatchStrategy};
12+
use serde_json::json;
13+
use crate::us_street_api::candidate::Candidate;
1214

1315
#[test]
1416
fn client_test() {
@@ -71,4 +73,239 @@ mod tests {
7173
);
7274
assert_eq!(batch.records().len(), 4);
7375
}
76+
77+
#[test]
78+
fn full_candidate_test_with_top_level_fields() {
79+
let data = json!({
80+
"input_id": "1234",
81+
"candidate_index": 0,
82+
"delivery_line_1": "1600 Amphitheatre Pkwy",
83+
"delivery_line_2": "Ste 100",
84+
"last_line": "Mountain View CA 94043-1351",
85+
"delivery_point_barcode": "940431351000",
86+
"components": {
87+
"urbanization": "URB",
88+
"primary_number": "1600",
89+
"street_name": "Amphitheatre",
90+
"street_predirection": "N",
91+
"street_postdirection": "W",
92+
"street_suffix": "Pkwy",
93+
"secondary_number": "100",
94+
"secondary_designator": "Ste",
95+
"extra_secondary_number": "200",
96+
"extra_secondary_designator": "Apt",
97+
"pmb_designator": "PMB",
98+
"pmb_number": "300",
99+
"city_name": "Mountain View",
100+
"default_city_name": "Mountain View",
101+
"state_abbreviation": "CA",
102+
"zipcode": "94043",
103+
"plus4_code": "1351",
104+
"delivery_point": "00",
105+
"delivery_point_check_digit": "1"
106+
},
107+
"metadata": {
108+
"record_type": "S",
109+
"zip_type": "Standard",
110+
"county_fips": "06085",
111+
"county_name": "Santa Clara",
112+
"carrier_route": "C001",
113+
"congressional_district": "18",
114+
"building_default_indicator": "Y",
115+
"rdi": "Residential",
116+
"elot_sequence": "0056",
117+
"elot_sort": "A",
118+
"latitude": 37.422,
119+
"longitude": -122.084,
120+
"precision": "Zip9",
121+
"time_zone": "Pacific",
122+
"utc_offset": -8.0,
123+
"dst": true,
124+
"ews_match": false
125+
},
126+
"analysis": {
127+
"dpv_match_code": "Y",
128+
"dpv_footnotes": "AABB",
129+
"dpv_cmra": "N",
130+
"dpv_vacant": "N",
131+
"dpv_no_stat": "N",
132+
"active": "Y",
133+
"ews_match": false,
134+
"footnotes": "N#",
135+
"lacslink_code": "L",
136+
"lacslink_indicator": "Y",
137+
"suitelink_match": true,
138+
"enhanced_match": "Y",
139+
"components": {
140+
"primary_number": {
141+
"status": "confirmed",
142+
"change": ["added"]
143+
},
144+
"street_predirection": {
145+
"status": "unconfirmed",
146+
"change": ["spelling"]
147+
},
148+
"street_name": {
149+
"status": "confirmed",
150+
"change": ["replaced"]
151+
},
152+
"street_postdirection": {
153+
"status": "confirmed",
154+
"change": []
155+
},
156+
"street_suffix": {
157+
"status": "confirmed",
158+
"change": ["spelling"]
159+
},
160+
"secondary_number": {
161+
"status": "unconfirmed",
162+
"change": ["added"]
163+
},
164+
"secondary_designator": {
165+
"status": "confirmed",
166+
"change": ["replaced"]
167+
},
168+
"extra_secondary_number": {
169+
"status": "confirmed",
170+
"change": ["spelling"]
171+
},
172+
"extra_secondary_designator": {
173+
"status": "confirmed",
174+
"change": ["added"]
175+
},
176+
"city_name": {
177+
"status": "unconfirmed",
178+
"change": ["replaced"]
179+
},
180+
"state_abbreviation": {
181+
"status": "confirmed",
182+
"change": []
183+
},
184+
"zipcode": {
185+
"status": "confirmed",
186+
"change": ["spelling"]
187+
},
188+
"plus4_code": {
189+
"status": "confirmed",
190+
"change": ["added"]
191+
},
192+
"urbanization": {
193+
"status": "unconfirmed",
194+
"change": []
195+
}
196+
}
197+
}
198+
});
199+
200+
let candidate: Candidate = serde_json::from_value(data).unwrap();
201+
202+
// Top-level
203+
assert_eq!(candidate.input_id, "1234");
204+
assert_eq!(candidate.candidate_index, 0);
205+
assert_eq!(candidate.delivery_line_1, "1600 Amphitheatre Pkwy");
206+
assert_eq!(candidate.delivery_line_2, "Ste 100");
207+
assert_eq!(candidate.last_line, "Mountain View CA 94043-1351");
208+
assert_eq!(candidate.delivery_point_barcode, "940431351000");
209+
210+
// Components
211+
let c = &candidate.components;
212+
assert_eq!(c.urbanization, "URB");
213+
assert_eq!(c.primary_number, "1600");
214+
assert_eq!(c.street_name, "Amphitheatre");
215+
assert_eq!(c.street_predirection, "N");
216+
assert_eq!(c.street_postdirection, "W");
217+
assert_eq!(c.street_suffix, "Pkwy");
218+
assert_eq!(c.secondary_number, "100");
219+
assert_eq!(c.secondary_designator, "Ste");
220+
assert_eq!(c.extra_secondary_number, "200");
221+
assert_eq!(c.extra_secondary_designator, "Apt");
222+
assert_eq!(c.pmb_designator, "PMB");
223+
assert_eq!(c.pmb_number, "300");
224+
assert_eq!(c.city_name, "Mountain View");
225+
assert_eq!(c.default_city_name, "Mountain View");
226+
assert_eq!(c.state_abbreviation, "CA");
227+
assert_eq!(c.zipcode, "94043");
228+
assert_eq!(c.plus4_code, "1351");
229+
assert_eq!(c.delivery_point, "00");
230+
assert_eq!(c.delivery_point_check_digit, "1");
231+
232+
// Metadata
233+
let m = &candidate.metadata;
234+
assert_eq!(m.record_type, "S");
235+
assert_eq!(m.zip_type, "Standard");
236+
assert_eq!(m.county_fips, "06085");
237+
assert_eq!(m.county_name, "Santa Clara");
238+
assert_eq!(m.carrier_route, "C001");
239+
assert_eq!(m.congressional_district, "18");
240+
assert_eq!(m.building_default_indicator, "Y");
241+
assert_eq!(m.rdi, "Residential");
242+
assert_eq!(m.elot_sequence, "0056");
243+
assert_eq!(m.elot_sort, "A");
244+
assert_eq!(m.latitude, 37.422);
245+
assert_eq!(m.longitude, -122.084);
246+
assert_eq!(m.precision, "Zip9");
247+
assert_eq!(m.time_zone, "Pacific");
248+
assert_eq!(m.utc_offset, -8.0);
249+
assert!(m.dst);
250+
assert!(!m.ews_match);
251+
252+
// Analysis
253+
let a = &candidate.analysis;
254+
assert_eq!(a.dpv_match_code, "Y");
255+
assert_eq!(a.dpv_footnotes, "AABB");
256+
assert_eq!(a.dpv_cmra, "N");
257+
assert_eq!(a.dpv_vacant, "N");
258+
assert_eq!(a.active, "Y");
259+
assert!(!a.ews_match);
260+
assert_eq!(a.footnotes, "N#");
261+
assert_eq!(a.lacslink_code, "L");
262+
assert_eq!(a.lacslink_indicator, "Y");
263+
assert!(a.suitelink_match);
264+
assert_eq!(a.dpv_no_stat, "N");
265+
assert_eq!(a.enhanced_match, "Y");
266+
267+
// Component Analysis (nested)
268+
let ca = &a.components;
269+
assert_eq!(ca.primary_number.status, "confirmed");
270+
assert_eq!(ca.primary_number.change, vec!["added"]);
271+
272+
assert_eq!(ca.street_predirection.status, "unconfirmed");
273+
assert_eq!(ca.street_predirection.change, vec!["spelling"]);
274+
275+
assert_eq!(ca.street_name.status, "confirmed");
276+
assert_eq!(ca.street_name.change, vec!["replaced"]);
277+
278+
assert_eq!(ca.street_postdirection.status, "confirmed");
279+
assert!(ca.street_postdirection.change.is_empty());
280+
281+
assert_eq!(ca.street_suffix.status, "confirmed");
282+
assert_eq!(ca.street_suffix.change, vec!["spelling"]);
283+
284+
assert_eq!(ca.secondary_number.status, "unconfirmed");
285+
assert_eq!(ca.secondary_number.change, vec!["added"]);
286+
287+
assert_eq!(ca.secondary_designator.status, "confirmed");
288+
assert_eq!(ca.secondary_designator.change, vec!["replaced"]);
289+
290+
assert_eq!(ca.extra_secondary_number.status, "confirmed");
291+
assert_eq!(ca.extra_secondary_number.change, vec!["spelling"]);
292+
293+
assert_eq!(ca.extra_secondary_designator.status, "confirmed");
294+
assert_eq!(ca.extra_secondary_designator.change, vec!["added"]);
295+
296+
assert_eq!(ca.city_name.status, "unconfirmed");
297+
assert_eq!(ca.city_name.change, vec!["replaced"]);
298+
299+
assert_eq!(ca.state_abbreviation.status, "confirmed");
300+
assert!(ca.state_abbreviation.change.is_empty());
301+
302+
assert_eq!(ca.zipcode.status, "confirmed");
303+
assert_eq!(ca.zipcode.change, vec!["spelling"]);
304+
305+
assert_eq!(ca.plus4_code.status, "confirmed");
306+
assert_eq!(ca.plus4_code.change, vec!["added"]);
307+
308+
assert_eq!(ca.urbanization.status, "unconfirmed");
309+
assert!(ca.urbanization.change.is_empty());
310+
}
74311
}

0 commit comments

Comments
 (0)