tower-api-client 0.1.1

Toolkit for creating API clients with Tower
Documentation
use futures::{StreamExt, TryStreamExt as _};
use serde::{Deserialize, Serialize};
use std::borrow::Cow;
use stream_flatten_iters::TryStreamExt;
use tower_api_client::pagination::PaginatedRequest;
use tower_api_client::{Client, Request, RequestData, ServiceExt as _};

#[derive(Clone, Debug, Serialize)]
struct GetPassengers {
    size: usize,
    page: Option<usize>,
}

#[derive(Clone, Deserialize, Debug)]
struct Passenger {
    name: Option<String>,
}

#[derive(Clone, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct PassengersWrapper {
    total_pages: usize,
    data: Vec<Passenger>,
}

impl Request for GetPassengers {
    type Data = Self;
    type Response = PassengersWrapper;

    fn endpoint(&self) -> Cow<str> {
        "/v1/passenger".into()
    }

    fn data(&self) -> RequestData<&Self> {
        RequestData::Query(self)
    }
}

impl PaginatedRequest for GetPassengers {
    type PaginationData = usize;
    fn get_page(&self) -> Option<usize> {
        self.page
    }

    fn next_page(&self, prev_page: Option<&usize>, response: &PassengersWrapper) -> Option<usize> {
        match prev_page {
            None => Some(1),
            Some(prev_page) => {
                if prev_page == &response.total_pages {
                    None
                } else {
                    Some(prev_page + 1)
                }
            }
        }
    }

    fn update_request(&mut self, page: &usize) {
        self.page = Some(*page as usize)
    }
}

#[tokio::main]
pub async fn main() {
    env_logger::init();
    let client = Client::new("https://api.instantwebtools.net");

    let req = GetPassengers {
        page: Some(3),
        size: 10,
    };

    client
        .paginate(req)
        .take(5)
        .map(|maybe_wrapper| maybe_wrapper.map(|wrapper| wrapper.data))
        .try_flatten_iters()
        .try_for_each(|res| async move {
            println!("{}", res.name.unwrap_or_else(|| String::from("No name")));
            Ok(())
        })
        .await
        .unwrap();
}