about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--indieauth/src/lib.rs38
1 files changed, 37 insertions, 1 deletions
diff --git a/indieauth/src/lib.rs b/indieauth/src/lib.rs
index 05122b0..741eb81 100644
--- a/indieauth/src/lib.rs
+++ b/indieauth/src/lib.rs
@@ -18,6 +18,8 @@
 //!
 //! [indieauth]: https://indieauth.spec.indieweb.org/20220212/
 //! [`axum`]: https://github.com/tokio-rs/axum
+use std::borrow::Cow;
+
 use serde::{Serialize, Deserialize};
 use url::Url;
 
@@ -302,7 +304,7 @@ impl AsRef<str> for State {
 ///     .parse()
 ///     .unwrap();
 ///
-/// url.set_query(Some(&serde_urlencoded::to_string(request).unwrap()));
+/// url.query_pairs_mut().extend_pairs(request.as_query_pairs().iter());
 ///
 /// // Open a user's browser to navigate to the authorization endpoint page...
 /// ```
@@ -336,6 +338,40 @@ pub struct AuthorizationRequest {
     pub me: Option<Url>,
 }
 
+impl AuthorizationRequest {
+    /// Transform this authorization request into a vector of string
+    /// pairs suitable into serialization into a query string.
+    ///
+    /// This is a bit more efficient than using serde, since it avoids
+    /// a deserialization an borrows where possible.
+    ///
+    /// (In the current implementation, only the scope field is owned.)
+    pub fn as_query_pairs(&'_ self) -> Vec<(&'static str, Cow<'_, str>)> {
+        let mut v = vec![
+            ("response_type", Cow::Borrowed(self.response_type.as_str())),
+            ("client_id", Cow::Borrowed(self.client_id.as_str())),
+            ("redirect_uri", Cow::Borrowed(self.redirect_uri.as_str())),
+            ("code_challenge", Cow::Borrowed(self.code_challenge.as_str())),
+            ("code_challenge_method", Cow::Borrowed(self.code_challenge.method().as_str())),
+            ("state", Cow::Borrowed(self.state.as_ref()))
+        ];
+
+        if let Some(ref scope) = self.scope {
+            v.push(
+                ("scope", Cow::Owned(scope.to_string()))
+            );
+        }
+
+        if let Some(ref me) = self.me {
+            v.push(
+                ("me", Cow::Borrowed(me.as_str()))
+            );
+        }
+
+        v
+    }
+}
+
 /// An authorization request that must be POSTed to an IndieAuth
 /// endpoint together with a token with a scope of
 /// `request_external_token:<scope>` to request external tokens with