openai-interface 0.11.0

A low-level Rust interface for the OpenAI API
Documentation
//! Cursor pagination helpers shared by list endpoints.
//!
//! > ![warn] This module is untested!
//! > If you encounter any issues, please report them on the repository.
//!
//! OpenAI-compatible list endpoints return a page object with a `data`
//! array and pagination cursor fields. The [`Page`] type models that
//! shape generically, and [`PaginationQuery`] collects the standard query
//! parameters so individual list requests can embed it via
//! `Deref`-style composition or flattening.

/// A single page of a paginated list response.
///
/// Mirrors the official list shape:
/// `{"object": "list", "data": [...], "first_id": ..., "last_id": ...,
/// "has_more": ...}`. Fields other than `data` are optional because some
/// OpenAI-compatible providers omit them.
#[derive(Debug, Clone, serde::Deserialize)]
pub struct Page<T> {
    /// The items on this page.
    #[serde(default)]
    pub data: Vec<T>,
    /// Whether more items exist after this page.
    #[serde(default)]
    pub has_more: Option<bool>,
    /// The ID of the first item on the page, for cursor pagination.
    #[serde(default)]
    pub first_id: Option<String>,
    /// The ID of the last item on the page, for cursor pagination.
    #[serde(default)]
    pub last_id: Option<String>,
    /// The object type (`list`), if the provider sends it.
    #[serde(default)]
    pub object: Option<String>,
}

/// The standard pagination query parameters accepted by most list
/// endpoints.
///
/// List request structs embed this and pass its values into
/// `query_pairs_mut` when building the URL.
#[derive(Debug, Clone, Copy, Default)]
pub struct PaginationQuery<'a> {
    /// A cursor for pagination: the object ID that defines the place in
    /// the list *before* which items are returned.
    pub before: Option<&'a str>,
    /// A cursor for pagination: the object ID that defines the place in
    /// the list *after* which items are returned.
    pub after: Option<&'a str>,
    /// A limit on the number of objects to be returned (1-100, default
    /// 20 for most endpoints).
    pub limit: Option<u32>,
    /// The sort order of the returned objects.
    pub order: Option<PaginationOrder>,
}

/// The sort order of objects in a list response.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum PaginationOrder {
    /// Ascending order (oldest first).
    Asc,
    /// Descending order (newest first, the default).
    #[default]
    Desc,
}

impl PaginationOrder {
    /// The wire value of the order.
    #[must_use]
    pub fn as_str(self) -> &'static str {
        match self {
            PaginationOrder::Asc => "asc",
            PaginationOrder::Desc => "desc",
        }
    }
}

impl<'a> PaginationQuery<'a> {
    /// Appends the set parameters to `pairs`.
    pub fn append_to<T: url::form_urlencoded::Target>(
        &self,
        pairs: &mut url::form_urlencoded::Serializer<'_, T>,
    ) {
        if let Some(before) = self.before {
            pairs.append_pair("before", before);
        }
        if let Some(after) = self.after {
            pairs.append_pair("after", after);
        }
        if let Some(limit) = self.limit {
            pairs.append_pair("limit", &limit.to_string());
        }
        if let Some(order) = self.order {
            pairs.append_pair("order", order.as_str());
        }
    }

    /// Whether any parameter is set.
    #[must_use]
    pub fn any_set(&self) -> bool {
        self.before.is_some()
            || self.after.is_some()
            || self.limit.is_some()
            || self.order.is_some()
    }
}