tiltify 0.1.1

A basic client library for Tiltifiy's API
Documentation
use std::sync::Arc;

use serde::{de::DeserializeOwned, Deserialize};

use crate::client::{ClientInner, ResponseMeta};

#[derive(Deserialize, Debug)]
pub(crate) struct PaginationLinks {
    prev: Option<String>,
    next: Option<String>,
}

#[derive(Deserialize, Debug)]
pub(crate) struct PaginationResponse<T> {
    meta: ResponseMeta,
    data: Vec<T>,
    links: PaginationLinks,
}

pub struct Paginator<T> {
    pub data: Vec<T>,
    links: PaginationLinks,
    client: Arc<ClientInner>,
}

impl<T: DeserializeOwned> Paginator<T> {
    pub(crate) async fn get(
        client: Arc<ClientInner>,
        endpoint: &str,
    ) -> crate::Result<Paginator<T>> {
        let response = client.get(endpoint, None).await?;
        let response = response.json::<PaginationResponse<T>>().await?;
        Ok(Paginator {
            client: client.clone(),
            data: response.data,
            links: response.links,
        })
    }

    pub async fn next(&self) -> crate::Result<Option<Paginator<T>>> {
        match &self.links.next {
            Some(next) => {
                if next.is_empty() {
                    return Ok(None);
                }
                Ok(Some(Paginator::get(self.client.clone(), &next).await?))
            }
            None => Ok(None),
        }
    }

    pub async fn prev(&self) -> crate::Result<Option<Paginator<T>>> {
        match &self.links.prev {
            Some(prev) => {
                if prev.is_empty() {
                    return Ok(None);
                }
                Ok(Some(Paginator::get(self.client.clone(), &prev).await?))
            }
            None => Ok(None),
        }
    }
}