From 2b18f3679ef318278d418effa978cf8a5690540a Mon Sep 17 00:00:00 2001 From: Glenn Griffin Date: Thu, 8 Aug 2019 14:21:21 -0700 Subject: [PATCH] Modify GetToken::token. Change it to accept an iterator of items that can be converted to `String`s rather than an iterator of items that can be referenced as `&str`s. Primarily this allows it to be called with a larger variety of inputs. For example ::std::env::args().skip(1) can now be passed directly to token, where before it would first need to be collected into a vector. Since all implementations unconditionally collected the iterator into a vector this shouldn't have any negative impact on performance and should actually reduce the number of allocations in some uses. It simplifies the signature since the lifetime bounds are no longer required. --- src/authenticator.rs | 6 +++--- src/device.rs | 14 +++++++------- src/installed.rs | 14 +++++++------- src/service_account.rs | 14 +++++++------- src/storage.rs | 14 +++++--------- src/types.rs | 6 +++--- 6 files changed, 32 insertions(+), 36 deletions(-) diff --git a/src/authenticator.rs b/src/authenticator.rs index fa68076..36b3277 100644 --- a/src/authenticator.rs +++ b/src/authenticator.rs @@ -85,13 +85,13 @@ impl< self.inner.lock().unwrap().application_secret() } - fn token<'b, I, T>( + fn token( &mut self, scopes: I, ) -> Box + Send> where - T: AsRef + Ord + 'b, - I: Iterator, + T: Into, + I: IntoIterator, { let (scope_key, scopes) = hash_scopes(scopes); let store = self.store.clone(); diff --git a/src/device.rs b/src/device.rs index 83898b2..67d7048 100644 --- a/src/device.rs +++ b/src/device.rs @@ -44,15 +44,15 @@ impl< C: hyper::client::connect::Connect + Sync + 'static, > GetToken for DeviceFlow { - fn token<'b, I, T>( + fn token( &mut self, scopes: I, ) -> Box + Send> where - T: AsRef + Ord + 'b, - I: Iterator, + T: Into, + I: IntoIterator, { - self.retrieve_device_token(Vec::from_iter(scopes.map(|s| s.as_ref().to_string()))) + self.retrieve_device_token(Vec::from_iter(scopes.into_iter().map(Into::into))) } fn api_key(&mut self) -> Option { None @@ -413,7 +413,7 @@ mod tests { .create(); let fut = flow - .token(vec!["https://www.googleapis.com/scope/1"].iter()) + .token(vec!["https://www.googleapis.com/scope/1"]) .then(|token| { let token = token.unwrap(); assert_eq!("accesstoken", token.access_token); @@ -445,7 +445,7 @@ mod tests { .create(); let fut = flow - .token(vec!["https://www.googleapis.com/scope/1"].iter()) + .token(vec!["https://www.googleapis.com/scope/1"]) .then(|token| { assert!(token.is_err()); assert!(format!("{}", token.unwrap_err()).contains("invalid_client_id")); @@ -476,7 +476,7 @@ mod tests { .create(); let fut = flow - .token(vec!["https://www.googleapis.com/scope/1"].iter()) + .token(vec!["https://www.googleapis.com/scope/1"]) .then(|token| { assert!(token.is_err()); assert!(format!("{}", token.unwrap_err()).contains("Access denied by user")); diff --git a/src/installed.rs b/src/installed.rs index 72b38c5..893fbe6 100644 --- a/src/installed.rs +++ b/src/installed.rs @@ -61,15 +61,15 @@ where impl GetToken for InstalledFlow { - fn token<'b, I, T>( + fn token( &mut self, scopes: I, ) -> Box + Send> where - T: AsRef + Ord + 'b, - I: Iterator, + T: Into, + I: IntoIterator, { - Box::new(self.obtain_token(scopes.into_iter().map(|s| s.as_ref().to_string()).collect())) + Box::new(self.obtain_token(scopes.into_iter().map(Into::into).collect())) } fn api_key(&mut self) -> Option { None @@ -625,7 +625,7 @@ mod tests { .create(); let fut = inf - .token(vec!["https://googleapis.com/some/scope"].iter()) + .token(vec!["https://googleapis.com/some/scope"]) .and_then(|tok| { assert_eq!("accesstoken", tok.access_token); assert_eq!("refreshtoken", tok.refresh_token); @@ -653,7 +653,7 @@ mod tests { .create(); let fut = inf - .token(vec!["https://googleapis.com/some/scope"].iter()) + .token(vec!["https://googleapis.com/some/scope"]) .and_then(|tok| { assert_eq!("accesstoken", tok.access_token); assert_eq!("refreshtoken", tok.refresh_token); @@ -675,7 +675,7 @@ mod tests { .create(); let fut = inf - .token(vec!["https://googleapis.com/some/scope"].iter()) + .token(vec!["https://googleapis.com/some/scope"]) .then(|tokr| { assert!(tokr.is_err()); assert!(format!("{}", tokr.unwrap_err()).contains("invalid_code")); diff --git a/src/service_account.rs b/src/service_account.rs index a215a3e..598722a 100644 --- a/src/service_account.rs +++ b/src/service_account.rs @@ -315,13 +315,13 @@ impl GetToken for ServiceAccountAccess where C: hyper::client::connect::Connect, { - fn token<'b, I, T>( + fn token( &mut self, scopes: I, ) -> Box + Send> where - T: AsRef + Ord + 'b, - I: Iterator, + T: Into, + I: IntoIterator, { let (hash, scps0) = hash_scopes(scopes); let cache = self.cache.clone(); @@ -443,7 +443,7 @@ mod tests { .create(); let mut acc = ServiceAccountAccess::new(key.clone(), client.clone()); let fut = acc - .token(vec!["https://www.googleapis.com/auth/pubsub"].iter()) + .token(vec!["https://www.googleapis.com/auth/pubsub"]) .and_then(|tok| { assert!(tok.access_token.contains("ya29.c.ElouBywiys0Ly")); assert_eq!(Some(3600), tok.expires_in); @@ -463,7 +463,7 @@ mod tests { .is_some()); // Test that token is in cache (otherwise mock will tell us) let fut = acc - .token(vec!["https://www.googleapis.com/auth/pubsub"].iter()) + .token(vec!["https://www.googleapis.com/auth/pubsub"]) .and_then(|tok| { assert!(tok.access_token.contains("ya29.c.ElouBywiys0Ly")); assert_eq!(Some(3600), tok.expires_in); @@ -482,7 +482,7 @@ mod tests { .create(); let mut acc = ServiceAccountAccess::new(key.clone(), client.clone()); let fut = acc - .token(vec!["https://www.googleapis.com/auth/pubsub"].iter()) + .token(vec!["https://www.googleapis.com/auth/pubsub"]) .then(|result| { assert!(result.is_err()); Ok(()) as Result<(), ()> @@ -509,7 +509,7 @@ mod tests { let mut acc = ServiceAccountAccess::new(key, client); println!( "{:?}", - acc.token(vec!["https://www.googleapis.com/auth/pubsub"].iter()) + acc.token(vec!["https://www.googleapis.com/auth/pubsub"]) .wait() ); } diff --git a/src/storage.rs b/src/storage.rs index af6248a..8c63949 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -35,19 +35,15 @@ pub trait TokenStorage { } /// Calculate a hash value describing the scopes, and return a sorted Vec of the scopes. -pub fn hash_scopes<'a, I, T>(scopes: I) -> (u64, Vec) +pub fn hash_scopes(scopes: I) -> (u64, Vec) where - T: AsRef + Ord + 'a, - I: IntoIterator, + T: Into, + I: IntoIterator, { - let mut sv: Vec<&str> = scopes - .into_iter() - .map(|s| s.as_ref()) - .collect::>(); + let mut sv: Vec = scopes.into_iter().map(Into::into).collect(); sv.sort(); let mut sh = DefaultHasher::new(); - &sv.hash(&mut sh); - let sv = sv.iter().map(|s| s.to_string()).collect(); + sv.hash(&mut sh); (sh.finish(), sv) } diff --git a/src/types.rs b/src/types.rs index f4d6797..72229b7 100644 --- a/src/types.rs +++ b/src/types.rs @@ -240,13 +240,13 @@ impl FromStr for Scheme { /// The `api_key()` method is an alternative in case there are no scopes or /// if no user is involved. pub trait GetToken { - fn token<'b, I, T>( + fn token( &mut self, scopes: I, ) -> Box + Send> where - T: AsRef + Ord + 'b, - I: Iterator; + T: Into, + I: IntoIterator; fn api_key(&mut self) -> Option;