chiark / gitweb /
client: Instrudoce api_request_ok and api_request_raw
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Fri, 2 Feb 2024 21:07:47 +0000 (21:07 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Fri, 2 Feb 2024 22:57:23 +0000 (22:57 +0000)
This avoids open-coded (and easy-to-forget) error handling at each
call site.

Presently, the only caller of api_request_raw is api_request_success,
because the sites that want anything else are open-coding
execute_and_log_request etc.

src/client.rs

index c17077f6b98880bda1fcf4cf6a76f96f05edb553..a46d18f76e6b42a0ad1777171c2e0ed1edd68a20 100644 (file)
@@ -659,7 +659,11 @@ impl Client {
         req.build(&base_url, client, self.auth.user_token.as_deref())
     }
 
-    fn api_request(
+    /// Sends and logs, but doesn't do any checking on the response
+    ///
+    /// You must call `.is_success()` (or equivalent) on the response
+    /// yourself.
+    fn api_request_raw(
         &mut self,
         req: Req,
     ) -> Result<(String, reqwest::blocking::Response), ClientError> {
@@ -669,6 +673,21 @@ impl Client {
         Ok((urlstr, rsp))
     }
 
+    /// Makes a request and insists it was a plain success
+    ///
+    /// Calls `.is_success()` for you.
+    fn api_request_ok(
+        &mut self,
+        req: Req,
+    ) -> Result<(String, reqwest::blocking::Response), ClientError> {
+        let (url, rsp) = self.api_request_raw(req)?;
+        let rspstatus = rsp.status();
+        if !rspstatus.is_success() {
+            return Err(ClientError::from_response(&url, rsp));
+        }
+        Ok((url, rsp))
+    }
+
     /// Makes a request and deserialises the returned JSON
     ///
     /// Insists that the response is a success.
@@ -680,11 +699,7 @@ impl Client {
         // There's a lot of code here that doesn't depend on T, but
         // the generics will monomorphise it for each T.  If we cared enough
         // about binary size, we could make a non-generic inner function.
-        let (url, rsp) = self.api_request(req)?;
-        let rspstatus = rsp.status();
-        if !rspstatus.is_success() {
-            return Err(ClientError::from_response(&url, rsp));
-        }
+        let (url, rsp) = self.api_request_ok(req)?;
         let text = rsp.text()?;
         let t: T = serde_json::from_str(&text).map_err(|e0| {
             let url = url.clone();
@@ -1006,11 +1021,7 @@ impl Client {
             }
         };
 
-        let (url, rsp) = self.api_request(req)?;
-        let rspstatus = rsp.status();
-        if !rspstatus.is_success() {
-            return Err(ClientError::from_response(&url, rsp));
-        }
+        let (url, rsp) = self.api_request_ok(req)?;
 
         // Keep the Link: headers after we consume the response, for
         // use later once we've constructed a Feed
@@ -1388,13 +1399,8 @@ impl Client {
             Some(id) => req.param("in_reply_to_id", id),
         };
 
-        let (url, rsp) = self.api_request(req)?;
-        let rspstatus = rsp.status();
-        if !rspstatus.is_success() {
-            Err(ClientError::from_response(&url, rsp))
-        } else {
-            Ok(())
-        }
+        self.api_request_ok(req)?;
+        Ok(())
     }
 
     pub fn fave_boost_post(
@@ -1477,13 +1483,8 @@ impl Client {
                 req
             }
         };
-        let (url, rsp) = self.api_request(req)?;
-        let rspstatus = rsp.status();
-        if !rspstatus.is_success() {
-            Err(ClientError::from_response(&url, rsp))
-        } else {
-            Ok(())
-        }
+        self.api_request_ok(req)?;
+        Ok(())
     }
 
     pub fn set_account_flag(
@@ -1506,13 +1507,8 @@ impl Client {
                 Req::post(&format!("api/v1/accounts/{id}/unmute"))
             }
         };
-        let (url, rsp) = self.api_request(req)?;
-        let rspstatus = rsp.status();
-        if !rspstatus.is_success() {
-            Err(ClientError::from_response(&url, rsp))
-        } else {
-            Ok(())
-        }
+        self.api_request_ok(req)?;
+        Ok(())
     }
 
     pub fn set_account_details(