smarty_rust_sdk/us_street_api/
lookup.rs

1use crate::sdk::{has_param, is_zero};
2use crate::us_street_api::candidate::Candidates;
3use serde::Serialize;
4use std::fmt::{Display, Formatter};
5
6#[derive(Debug, Clone, PartialEq, Serialize)]
7#[serde(default)]
8pub struct Lookup {
9    #[serde(skip_serializing_if = "String::is_empty")]
10    pub street: String,
11    #[serde(skip_serializing_if = "String::is_empty")]
12    pub street2: String,
13    #[serde(skip_serializing_if = "String::is_empty")]
14    pub secondary: String,
15    #[serde(skip_serializing_if = "String::is_empty")]
16    pub city: String,
17    #[serde(skip_serializing_if = "String::is_empty")]
18    pub state: String,
19    #[serde(skip_serializing_if = "String::is_empty")]
20    pub zipcode: String,
21    #[serde(rename = "lastline")]
22    #[serde(skip_serializing_if = "String::is_empty")]
23    pub last_line: String, // "lastline" in json
24    #[serde(skip_serializing_if = "String::is_empty")]
25    pub addressee: String,
26    #[serde(skip_serializing_if = "String::is_empty")]
27    pub urbanization: String,
28    #[serde(skip_serializing_if = "String::is_empty")]
29    pub input_id: String,
30
31    #[serde(rename = "candidates")]
32    #[serde(skip_serializing_if = "is_zero")]
33    pub max_candidates: i64, // Default Value: 1 // candidates in json
34
35    #[serde(rename = "match")]
36    pub match_strategy: MatchStrategy, // "match" in json
37
38    #[serde(rename = "format")]
39    pub format_output: OutputFormat,
40
41    pub county_source: Option<CountySource>,
42
43    #[serde(skip_serializing)]
44    pub results: Candidates,
45}
46
47impl Default for Lookup {
48    fn default() -> Self {
49        Lookup {
50            street: String::default(),
51            street2: String::default(),
52            secondary: String::default(),
53            city: String::default(),
54            state: String::default(),
55            zipcode: String::default(),
56            last_line: String::default(),
57            addressee: String::default(),
58            urbanization: String::default(),
59            input_id: String::default(),
60            max_candidates: 1,
61
62            match_strategy: Default::default(),
63            format_output: Default::default(),
64            county_source: Default::default(),
65            results: vec![],
66        }
67    }
68}
69
70impl Lookup {
71    pub(crate) fn into_param_array(self) -> Vec<(String, String)> {
72        let mut max_candidates_string = self.max_candidates.to_string();
73
74        if self.max_candidates <= 0 {
75            max_candidates_string = String::default();
76        }
77
78        if self.match_strategy == MatchStrategy::Enhanced {
79            max_candidates_string = 5.to_string();
80        }
81
82        let mut res = vec![
83            has_param("street".to_string(), self.street),
84            has_param("street2".to_string(), self.street2),
85            has_param("secondary".to_string(), self.secondary),
86            has_param("city".to_string(), self.city),
87            has_param("state".to_string(), self.state),
88            has_param("zipcode".to_string(), self.zipcode),
89            has_param("lastline".to_string(), self.last_line),
90            has_param("addressee".to_string(), self.addressee),
91            has_param("urbanization".to_string(), self.urbanization),
92            has_param("input_id".to_string(), self.input_id),
93            has_param("candidates".to_string(), max_candidates_string),
94            has_param("match".to_string(), self.match_strategy.to_string()),
95            has_param("format".to_string(), self.format_output.to_string()),
96        ];
97
98        if let Some(source) = self.county_source {
99            res.push(Some(("country_source".to_string(), source.to_string())));
100        }
101
102        res.iter().filter_map(Option::clone).collect::<Vec<_>>()
103    }
104}
105
106#[derive(Default, Debug, Clone, PartialEq, Serialize)]
107#[serde(rename_all = "snake_case")]
108pub enum MatchStrategy {
109    #[default]
110    Strict,
111    Invalid,
112    Enhanced,
113}
114
115impl Display for MatchStrategy {
116    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
117        match self {
118            MatchStrategy::Strict => {
119                write!(f, "strict")
120            }
121            MatchStrategy::Invalid => {
122                write!(f, "invalid")
123            }
124            MatchStrategy::Enhanced => {
125                write!(f, "enhanced")
126            }
127        }
128    }
129}
130
131#[derive(Default, Debug, Clone, PartialEq, Serialize)]
132pub enum OutputFormat {
133    #[default]
134    FormatDefault,
135    ProjectUsa,
136}
137
138impl Display for OutputFormat {
139    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
140        match self {
141            OutputFormat::FormatDefault => {
142                write!(f, "default")
143            }
144            OutputFormat::ProjectUsa => {
145                write!(f, "project-usa")
146            }
147        }
148    }
149}
150
151#[derive(Default, Debug, Clone, PartialEq, Serialize)]
152#[serde(rename_all = "snake_case")]
153pub enum CountySource {
154    #[default]
155    Postal,
156    Geographic,
157}
158
159impl Display for CountySource {
160    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
161        match self {
162            CountySource::Postal => {
163                write!(f, "postal")
164            }
165            CountySource::Geographic => {
166                write!(f, "geographic")
167            }
168        }
169    }
170}