#![deny(missing_docs,
missing_debug_implementations, missing_copy_implementations,
trivial_casts, trivial_numeric_casts,
unstable_features, unsafe_code,
unused_import_braces, unused_qualifications)]
use std::env;
use reqwest;
use roxmltree;
pub mod address;
const SECURE_ENDPOINT: &'static str = "https://secure.shippingapis.com/ShippingAPI.dll?API=";
const UNSECURE_ENDPOINT: &'static str = "http://production.shippingapis.com/ShippingAPI.dll?API=";
const ENV_USER_ID: &'static str = "USPS_USER_ID";
const ENV_PASSWORD: &'static str = "USPS_PASSWORD";
#[derive(Debug, PartialEq)]
pub struct USPSWebTool {
secure: bool,
user_id: String,
password: String,
}
impl USPSWebTool {
pub fn init(user_id: &str, password: &str) -> Self {
USPSWebTool {
secure: true,
user_id: String::from(user_id),
password: String::from(password)
}
}
pub fn new() -> Result<Self, env::VarError> {
let user_id = env::var(ENV_USER_ID)?;
let password = env::var(ENV_PASSWORD)?;
Ok(USPSWebTool {
secure: true,
user_id,
password,
})
}
pub fn use_http(mut self) -> Self {
self.secure = false;
self
}
pub fn verify_address(&self, address: address::USPSAddress) -> Result<address::USPSAddress, Box<dyn std::error::Error>> {
let mut req;
if self.secure {
req = String::from(SECURE_ENDPOINT);
} else {
req = String::from(UNSECURE_ENDPOINT);
}
req.push_str("Verify&XML=");
req.push_str(&format!("<AddressValidateRequest USERID=\"{}\"><Revision>1</Revision>", self.user_id));
req.push_str(&address.xml());
req.push_str("</AddressValidateRequest>");
let body = reqwest::get(&req)?.text()?;
println!("{:?}", body);
let xml = roxmltree::Document::parse(&body)?;
Ok(address::USPSAddress::from_xml(xml))
}
}
#[cfg(test)]
mod tests {
use super::*;
const DUMMY_UN: &'static str = "USERNAME";
const DUMMY_PW: &'static str = "PASSWORD";
#[test]
fn init_constructor() {
let dummy_struct = USPSWebTool {
secure: true,
user_id: String::from(DUMMY_UN),
password: String::from(DUMMY_PW),
};
assert_eq!(USPSWebTool::init(DUMMY_UN, DUMMY_PW), dummy_struct);
}
#[test]
fn new_constructor() {
env::set_var(ENV_USER_ID, DUMMY_UN);
env::set_var(ENV_PASSWORD, DUMMY_PW);
let dummy_struct = USPSWebTool {
secure: true,
user_id: String::from(DUMMY_UN),
password: String::from(DUMMY_PW),
};
assert_eq!(USPSWebTool::new().unwrap(), dummy_struct);
}
#[test]
#[should_panic]
fn new_contructor_no_env() {
env::remove_var(ENV_USER_ID);
env::remove_var(ENV_PASSWORD);
let dummy_struct = USPSWebTool {
secure: true,
user_id: String::from(DUMMY_UN),
password: String::from(DUMMY_PW),
};
assert_eq!(USPSWebTool::new().unwrap(), dummy_struct);
}
#[test]
fn use_http() {
let dummy_struct = USPSWebTool {
secure: false,
user_id: String::from(DUMMY_UN),
password: String::from(DUMMY_PW),
};
assert_eq!(USPSWebTool::init(DUMMY_UN, DUMMY_PW).use_http(),
dummy_struct);
}
mod address_test {
use super::*;
#[test]
fn test_address_1() {
let api = USPSWebTool::init("348XVRQT1293", "088NI00MI876");
let home = address::USPSAddress::quick("429 2nd Ave W", "104", "Seattle", "WA", "98119");
api.verify_address(home).unwrap();
}
}
}