apple_web_service_client/
lib.rs

1use std::io;
2
3pub use apple_web_service_endpoint::{
4    Body, Endpoint, EndpointParseResponseOutput, Request, Response,
5};
6pub use async_trait::async_trait;
7
8#[async_trait]
9pub trait Client {
10    async fn respond(&self, request: Request<Body>) -> io::Result<Response<Body>>;
11
12    async fn respond_endpoint<E: Endpoint + Send + Sync>(
13        &self,
14        endpoint: &mut E,
15    ) -> io::Result<EndpointParseResponseOutput<E::ParseResponseOutput, E::RetryReason>> {
16        let request = endpoint.render_request()?;
17        let response = self.respond(request).await?;
18        endpoint.parse_response(response)
19    }
20
21    async fn respond_endpoint_until_done<E: Endpoint + Send + Sync>(
22        &self,
23        endpoint: &mut E,
24        max_retry_count: Option<u8>,
25    ) -> io::Result<E::ParseResponseOutput> {
26        let max_retry_count = max_retry_count.unwrap_or(3);
27        let mut retry_count = 0;
28        loop {
29            match self.respond_endpoint(endpoint).await? {
30                EndpointParseResponseOutput::Retryable(_) => {
31                    retry_count += 1;
32                    if retry_count > max_retry_count {
33                        return Err(io::Error::new(
34                            io::ErrorKind::Other,
35                            "reached max retry count",
36                        ));
37                    }
38                    continue;
39                }
40                EndpointParseResponseOutput::Done(output) => {
41                    break Ok(output);
42                }
43            }
44        }
45    }
46}