Skip to main content

rig_core/operation/
listing.rs

1//! Model listing: one call per page, and [`Model::list`] to follow the
2//! cursors.
3//!
4//! ```
5//! use rig_core::model::ModelList;
6//! use rig_core::operation::ModelPage;
7//!
8//! let page = ModelPage { models: ModelList::new(Vec::new()), next: None };
9//! assert!(page.next.is_none());
10//! ```
11
12use super::Whole;
13use crate::driver::{Model, Transport};
14use crate::error::ProviderError;
15use crate::model::ModelList;
16use crate::wire::{Call, Free, Operation, Wire};
17
18/// Lists provider models, one page per call.
19#[derive(Debug, Clone, Copy, PartialEq, Eq)]
20pub struct ModelListing;
21
22/// One page of a model listing, and the cursor of the page after it.
23#[derive(Debug, Clone)]
24pub struct ModelPage {
25    /// The page's models, in the order the provider listed them.
26    pub models: ModelList,
27    /// The next page's cursor. `None` on the last page.
28    pub next: Option<String>,
29}
30
31impl Operation for ModelListing {
32    /// The cursor of the page to read: `None` for the first.
33    type Request = Option<String>;
34    type Event = std::convert::Infallible;
35    type End = ModelPage;
36    type Response = ModelPage;
37    type Fold = Whole<Self>;
38    type Emit = Free;
39
40    fn fold(_request: &Self::Request, _call: &mut Call<'_>) -> Self::Fold {
41        Whole::new()
42    }
43}
44
45impl<W, T> Model<W, T>
46where
47    W: Wire<Op = ModelListing>,
48    T: Transport<W>,
49{
50    /// Every model the provider lists, every page followed in order.
51    ///
52    /// A failed page names the provider and its request path. Paging stops
53    /// at a cursor that repeats the one just answered, and after a bounded
54    /// number of pages.
55    pub async fn list(&self) -> Result<ModelList, ProviderError> {
56        let provider = self.name();
57        let pages = crate::driver::follow_cursors(provider, "model_listing", |cursor| async move {
58            let page = self.call_routed(cursor).await.map_err(|(error, path)| {
59                crate::model::listing::with_route(error, provider, &path)
60            })?;
61            Ok((page.models, page.next))
62        })
63        .await?;
64        Ok(ModelList::new(pages.into_iter().flatten().collect()))
65    }
66}