imp: accept any string-like parameter

Use the power of the `AsRef` trait to take generic parameters for
several API functions. This makes the API more ergonomic because the
callers may pass in static `str` slices or references to owned `String`s
or even more exotic things like a `Cow`, all based on their particular
situation.

Update the tests and examples to use the most natural types they have
available.

Fixes #77. No existing code should break, as `&String` implements
`AsRef<str>` and `AsRef<Path>`
This commit is contained in:
Lyle Mantooth
2019-04-03 09:01:28 -04:00
parent de57b8fbdf
commit 108162fcf8
9 changed files with 24 additions and 16 deletions

View File

@@ -34,7 +34,7 @@ fn main() {
let authenticator = Authenticator::new(&secret,
DefaultAuthenticatorDelegate,
client,
DiskTokenStorage::new(&"token_store.json".to_string())
DiskTokenStorage::new("token_store.json")
.unwrap(),
Some(FlowType::InstalledInteractive));
let client = hyper::Client::with_connector(

View File

@@ -165,7 +165,7 @@ fn publish_stuff(methods: &PubsubMethods, message: &str) {
// If called as '.../service_account pub', act as publisher; if called as '.../service_account
// sub', act as subscriber.
fn main() {
let client_secret = oauth::service_account_key_from_file(&"pubsub-auth.json".to_string())
let client_secret = oauth::service_account_key_from_file("pubsub-auth.json")
.unwrap();
let client = hyper::Client::with_connector(HttpsConnector::new(NativeTlsClient::new().unwrap()));
let mut access = oauth::ServiceAccountAccess::new(client_secret, client);

View File

@@ -238,8 +238,7 @@ where
}
}
RefreshResult::RefreshError(ref err_str, ref err_description) => {
self.delegate
.token_refresh_failed(&err_str, &err_description);
self.delegate.token_refresh_failed(err_str, err_description);
let storage_err =
match self.storage.set(scope_key, &scopes, None) {
Ok(_) => String::new(),

View File

@@ -90,7 +90,11 @@ pub trait AuthenticatorDelegate {
/// Called if we could not acquire a refresh token for a reason possibly specified
/// by the server.
/// This call is made for the delegate's information only.
fn token_refresh_failed(&mut self, error: &String, error_description: &Option<String>) {
fn token_refresh_failed<S: AsRef<str>>(
&mut self,
error: S,
error_description: &Option<String>,
) {
{
let _ = error;
}
@@ -136,7 +140,11 @@ pub trait AuthenticatorDelegate {
/// We need the user to navigate to a URL using their browser and potentially paste back a code
/// (or maybe not). Whether they have to enter a code depends on the InstalledFlowReturnMethod
/// used.
fn present_user_url(&mut self, url: &String, need_code: bool) -> Option<String> {
fn present_user_url<S: AsRef<str> + fmt::Display>(
&mut self,
url: S,
need_code: bool,
) -> Option<String> {
if need_code {
println!(
"Please direct your browser to {}, follow the instructions and enter the \

View File

@@ -314,7 +314,7 @@ pub mod tests {
fn working_flow() {
use crate::helper::parse_application_secret;
let appsecret = parse_application_secret(&TEST_APP_SECRET.to_string()).unwrap();
let appsecret = parse_application_secret(TEST_APP_SECRET).unwrap();
let mut flow = DeviceFlow::new(
hyper::Client::with_connector(<MockGoogleAuth as Default>::default()),
&appsecret,

View File

@@ -28,8 +28,9 @@ pub fn read_application_secret(path: &Path) -> io::Result<ApplicationSecret> {
}
/// Read an application secret from a JSON string.
pub fn parse_application_secret(secret: &String) -> io::Result<ApplicationSecret> {
let result: serde_json::Result<ConsoleApplicationSecret> = serde_json::from_str(secret);
pub fn parse_application_secret<S: AsRef<str>>(secret: S) -> io::Result<ApplicationSecret> {
let result: serde_json::Result<ConsoleApplicationSecret> =
serde_json::from_str(secret.as_ref());
match result {
Err(e) => Err(io::Error::new(
io::ErrorKind::InvalidData,
@@ -52,7 +53,7 @@ pub fn parse_application_secret(secret: &String) -> io::Result<ApplicationSecret
/// Read a service account key from a JSON file. You can download the JSON keys from the Google
/// Cloud Console or the respective console of your service provider.
pub fn service_account_key_from_file(path: &String) -> io::Result<ServiceAccountKey> {
pub fn service_account_key_from_file<S: AsRef<Path>>(path: S) -> io::Result<ServiceAccountKey> {
let mut key = String::new();
let mut file = fs::OpenOptions::new().read(true).open(path)?;
file.read_to_string(&mut key)?;

View File

@@ -166,7 +166,7 @@ mod tests {
#[test]
fn refresh_flow() {
let appsecret = parse_application_secret(&TEST_APP_SECRET.to_string()).unwrap();
let appsecret = parse_application_secret(TEST_APP_SECRET).unwrap();
let mut c = hyper::Client::with_connector(<MockGoogleRefresh as Default>::default());
let mut flow = RefreshFlow::new(&mut c);

View File

@@ -351,7 +351,7 @@ mod tests {
//#[test]
#[allow(dead_code)]
fn test_service_account_e2e() {
let key = service_account_key_from_file(&TEST_PRIVATE_KEY_PATH.to_string()).unwrap();
let key = service_account_key_from_file(TEST_PRIVATE_KEY_PATH).unwrap();
let client =
hyper::Client::with_connector(HttpsConnector::new(NativeTlsClient::new().unwrap()));
let mut acc = ServiceAccountAccess::new(key, client);
@@ -364,7 +364,7 @@ mod tests {
#[test]
fn test_jwt_initialize_claims() {
let key = service_account_key_from_file(&TEST_PRIVATE_KEY_PATH.to_string()).unwrap();
let key = service_account_key_from_file(TEST_PRIVATE_KEY_PATH).unwrap();
let scopes = vec!["scope1", "scope2", "scope3"];
let claims = super::init_claims_from_key(&key, &scopes);
@@ -384,7 +384,7 @@ mod tests {
#[test]
fn test_jwt_sign() {
let key = service_account_key_from_file(&TEST_PRIVATE_KEY_PATH.to_string()).unwrap();
let key = service_account_key_from_file(TEST_PRIVATE_KEY_PATH).unwrap();
let scopes = vec!["scope1", "scope2", "scope3"];
let claims = super::init_claims_from_key(&key, &scopes);
let jwt = super::JWT::new(claims);

View File

@@ -132,9 +132,9 @@ pub struct DiskTokenStorage {
}
impl DiskTokenStorage {
pub fn new(location: &String) -> Result<DiskTokenStorage, io::Error> {
pub fn new<S: AsRef<str>>(location: S) -> Result<DiskTokenStorage, io::Error> {
let mut dts = DiskTokenStorage {
location: location.clone(),
location: location.as_ref().to_owned(),
tokens: HashMap::new(),
};