@@ -234,11 +234,61 @@ impl<S: Stamp> TurnkeyClient<S> {
234234 & self ,
235235 request : Request ,
236236 path : String ,
237+ ) -> Result < Activity , TurnkeyClientError > {
238+ let post_body = serde_json:: to_string ( & request) ?;
239+ self . process_activity_internal ( post_body, path, None ) . await
240+ }
241+
242+ /// POSTs an activity with a provided `stamp` and polls until the status is "COMPLETE"
243+ ///
244+ /// `process_activity` accepts a arbitrary `Request` and `path` to POST to the Turnkey API.
245+ /// It encapsulates the polling logic and is generally meant to be called by other
246+ /// activity-specific client functions (e.g. `create_sub_organization`).
247+ ///
248+ /// Given the Turnkey API is backwards-compatible, this function can be used to submit old versions of activities.
249+ /// For example, if the latest version for create_sub_organization is "ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V7",
250+ /// you may want to use `process_activity` to process `ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V6`. Note that this
251+ /// requires manually setting the correct URL and activity request type.
252+ /// The response is an generic Activity. If you're invoking this function manually you'll have to manually look at
253+ /// the correct `.activity.result` enum.
254+ ///
255+ /// # Returns
256+ ///
257+ /// This function returns an `Activity` object which contains the deserialized version of the response.
258+ ///
259+ /// # Errors
260+ ///
261+ /// If the server errors with a validation error, a server error, a deserialization error, the proper variant of `TurnkeyClientError` is returned.
262+ /// If the activity is pending and exceeds the maximum amount of retries allowed, `TurnkeyClientError::ExceededRetries` is returned.
263+ /// If the activity requires consensus, `TurnkeyClientError::ActivityRequiresApproval` is returned.
264+ pub async fn process_activity_with_stamp < Request : DeserializeOwned > (
265+ & self ,
266+ post_body : String ,
267+ path : String ,
268+ stamp : StampHeader ,
269+ ) -> Result < Activity , TurnkeyClientError > {
270+ // validate post_body matches the expected request type
271+ serde_json:: from_str :: < Request > ( & post_body) ?;
272+ self . process_activity_internal ( post_body, path, Some ( stamp) )
273+ . await
274+ }
275+
276+ async fn process_activity_internal (
277+ & self ,
278+ post_body : String ,
279+ path : String ,
280+ stamp : Option < StampHeader > ,
237281 ) -> Result < Activity , TurnkeyClientError > {
238282 let mut retry_count = 0 ;
239283
284+ let stamp = match & stamp {
285+ Some ( stamp) => stamp. clone ( ) ,
286+ None => self . api_key . stamp ( post_body. as_bytes ( ) ) ?,
287+ } ;
240288 loop {
241- let response: ActivityResponse = self . process_request ( & request, path. clone ( ) ) . await ?;
289+ let response: ActivityResponse = self
290+ . process_request_internal ( post_body. clone ( ) , path. clone ( ) , stamp. clone ( ) )
291+ . await ?;
242292 let activity = response
243293 . activity
244294 . ok_or_else ( || TurnkeyClientError :: MissingActivity ) ?;
@@ -296,9 +346,42 @@ impl<S: Stamp> TurnkeyClient<S> {
296346 Request : Serialize ,
297347 Response : DeserializeOwned ,
298348 {
299- let url = format ! ( "{}{}" , self . base_url, path) ;
300349 let post_body = serde_json:: to_string ( & request) ?;
301- let StampHeader { name, value } = self . api_key . stamp ( post_body. as_bytes ( ) ) ?;
350+ let stamp = self . api_key . stamp ( post_body. as_bytes ( ) ) ?;
351+ self . process_request_internal ( post_body, path, stamp) . await
352+ }
353+
354+ /// Processes a `Request` (at `path`) by:
355+ /// * Serializing the request to JSON
356+ /// * POSTing the POST body with the provided stamp to the Turnkey API
357+ ///
358+ /// This function is generic and can handle POSTing queries or activities.
359+ pub async fn process_request_with_stamp < Request , Response > (
360+ & self ,
361+ post_body : String ,
362+ path : String ,
363+ stamp : StampHeader ,
364+ ) -> Result < Response , TurnkeyClientError >
365+ where
366+ Request : DeserializeOwned ,
367+ Response : DeserializeOwned ,
368+ {
369+ // validate post_body matches the expected request type
370+ serde_json:: from_str :: < Request > ( & post_body) ?;
371+ self . process_request_internal ( post_body, path, stamp) . await
372+ }
373+
374+ async fn process_request_internal < Response > (
375+ & self ,
376+ post_body : String ,
377+ path : String ,
378+ stamp : StampHeader ,
379+ ) -> Result < Response , TurnkeyClientError >
380+ where
381+ Response : DeserializeOwned ,
382+ {
383+ let StampHeader { name, value } = stamp;
384+ let url = format ! ( "{}{}" , self . base_url, path) ;
302385 let res = self
303386 . http
304387 . post ( url)
0 commit comments