From 5f1e0fcdecf8b3d877dc35ed95252bf0731eb9d3 Mon Sep 17 00:00:00 2001 From: Matthew Zeitlin <37011898+mzeitlin11@users.noreply.github.com> Date: Fri, 5 Apr 2024 13:37:04 -0400 Subject: [PATCH 1/3] Remove some client allocations --- async-stripe/src/client/headers.rs | 14 ++++++++------ async-stripe/src/client/stripe.rs | 21 +++++++-------------- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/async-stripe/src/client/headers.rs b/async-stripe/src/client/headers.rs index ac0400410..6e84f9b12 100644 --- a/async-stripe/src/client/headers.rs +++ b/async-stripe/src/client/headers.rs @@ -1,3 +1,5 @@ +use std::fmt::{Display, Formatter}; + use crate::AccountId; use crate::ApiVersion; use crate::ApplicationId; @@ -9,16 +11,16 @@ pub struct AppInfo { pub version: Option, } -impl ToString for AppInfo { +impl Display for AppInfo { /// Formats a plugin's 'App Info' into a string that can be added to the end of an User-Agent string. /// /// This formatting matches that of other libraries, and if changed then it should be changed everywhere. - fn to_string(&self) -> String { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match (&self.version, &self.url) { - (Some(a), Some(b)) => format!("{}/{} ({})", &self.name, a, b), - (Some(a), None) => format!("{}/{}", &self.name, a), - (None, Some(b)) => format!("{} ({})", &self.name, b), - _ => self.name.to_string(), + (Some(a), Some(b)) => write!(f, "{}/{a} ({b})", &self.name), + (Some(a), None) => write!(f, "{}/{a}", &self.name), + (None, Some(b)) => write!(f, "{} ({b})", &self.name), + _ => f.write_str(&self.name), } } } diff --git a/async-stripe/src/client/stripe.rs b/async-stripe/src/client/stripe.rs index bf720b048..e058db0e3 100644 --- a/async-stripe/src/client/stripe.rs +++ b/async-stripe/src/client/stripe.rs @@ -21,9 +21,7 @@ pub struct Client { secret_key: String, headers: Headers, strategy: RequestStrategy, - app_info: Option, api_base: Url, - api_root: String, } impl Client { @@ -44,9 +42,7 @@ impl Client { stripe_account: None, }, strategy: RequestStrategy::Once, - app_info: None, api_base: Url::parse(url.into()).expect("invalid url"), - api_root: "v1".to_string(), } } @@ -80,8 +76,7 @@ impl Client { url: Option, ) -> Self { let app_info = AppInfo { name, version, url }; - self.headers.user_agent = format!("{} {}", USER_AGENT, app_info.to_string()); - self.app_info = Some(app_info); + self.headers.user_agent = format!("{USER_AGENT} {app_info}"); self } @@ -156,9 +151,8 @@ impl Client { return err(StripeError::QueryStringSerialize(qs_ser_err)); } - let body = std::str::from_utf8(params_buffer.as_slice()) - .expect("Unable to extract string from params_buffer") - .to_string(); + let body = + String::from_utf8(params_buffer).expect("Unable to extract string from params_buffer"); req.set_body(Body::from_string(body)); @@ -168,7 +162,7 @@ impl Client { fn url(&self, path: &str) -> Url { let mut url = self.api_base.clone(); - url.set_path(&format!("{}/{}", self.api_root, path.trim_start_matches('/'))); + url.set_path(&format!("v1/{}", path.trim_start_matches('/'))); url } @@ -179,9 +173,8 @@ impl Client { let qs_ser = &mut serde_qs::Serializer::new(&mut params_buffer); serde_path_to_error::serialize(¶ms, qs_ser).map_err(StripeError::from)?; - let params = std::str::from_utf8(params_buffer.as_slice()) - .expect("Unable to extract string from params_buffer") - .to_string(); + let params = + String::from_utf8(params_buffer).expect("Unable to extract string from params_buffer"); url.set_query(Some(¶ms)); Ok(url) @@ -189,7 +182,7 @@ impl Client { fn create_request(&self, method: Method, url: Url) -> Request { let mut req = Request::new(method, url); - req.insert_header("authorization", &format!("Bearer {}", self.secret_key)); + req.insert_header("authorization", format!("Bearer {}", self.secret_key)); for (key, value) in self.headers.to_array().iter().filter_map(|(k, v)| v.map(|v| (*k, v))) { req.insert_header(key, value); From 816b9f862cfc6d5ef940f51cd8e36e39614da731 Mon Sep 17 00:00:00 2001 From: Matthew Zeitlin <37011898+mzeitlin11@users.noreply.github.com> Date: Fri, 5 Apr 2024 13:38:46 -0400 Subject: [PATCH 2/3] Simplify webhook signature parse --- stripe_webhook/src/webhook.rs | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/stripe_webhook/src/webhook.rs b/stripe_webhook/src/webhook.rs index 184b900a9..9b11134a9 100644 --- a/stripe_webhook/src/webhook.rs +++ b/stripe_webhook/src/webhook.rs @@ -1,4 +1,3 @@ -use std::collections::HashMap; use std::str::FromStr; use chrono::Utc; @@ -138,22 +137,24 @@ struct Signature<'r> { impl<'r> Signature<'r> { fn parse(raw: &'r str) -> Result, WebhookError> { - let headers: HashMap<&str, &str> = raw - .split(',') - .map(|header| { - let mut key_and_value = header.split('='); - let key = key_and_value.next(); - let value = key_and_value.next(); - (key, value) - }) - .filter_map(|(key, value)| match (key, value) { - (Some(key), Some(value)) => Some((key, value)), - _ => None, - }) - .collect(); - let t = headers.get("t").ok_or(WebhookError::BadSignature)?; - let v1 = headers.get("v1").ok_or(WebhookError::BadSignature)?; - Ok(Signature { t: t.parse::().map_err(WebhookError::BadHeader)?, v1 }) + let mut t: Option = None; + let mut v1: Option<&'r str> = None; + for pair in raw.split(',') { + let (key, val) = pair.split_once('=').ok_or(WebhookError::BadSignature)?; + match key { + "t" => { + t = Some(val.parse().map_err(WebhookError::BadHeader)?); + } + "v1" => { + v1 = Some(val); + } + _ => {} + } + } + Ok(Signature { + t: t.ok_or(WebhookError::BadSignature)?, + v1: v1.ok_or(WebhookError::BadSignature)?, + }) } } From cff37d3e1ca56ca4e9a5bf9a44a4d6b97ecae605 Mon Sep 17 00:00:00 2001 From: Matthew Zeitlin <37011898+mzeitlin11@users.noreply.github.com> Date: Fri, 5 Apr 2024 13:44:19 -0400 Subject: [PATCH 3/3] Fix openapi clippy --- openapi/src/url_finder.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/openapi/src/url_finder.rs b/openapi/src/url_finder.rs index fd4ee695b..745d653ca 100644 --- a/openapi/src/url_finder.rs +++ b/openapi/src/url_finder.rs @@ -24,9 +24,7 @@ impl UrlFinder { } pub fn url_for_object(&self, object: &str) -> Option { - let Some(unprefixed_link) = self.doc_links.get(object) else { - return None; - }; + let unprefixed_link = self.doc_links.get(object)?; Some(format!("https://stripe.com/docs/api{}", unprefixed_link)) } }