docker_registry/v2/
catalog.rs

1use async_stream::try_stream;
2use futures::{
3  stream::Stream,
4  {self},
5};
6use log::trace;
7use reqwest::{Method, RequestBuilder, StatusCode};
8use serde::{Deserialize, Serialize};
9
10use crate::{errors::Result, v2};
11
12#[derive(Debug, Default, Deserialize, Serialize)]
13struct Catalog {
14  pub repositories: Vec<String>,
15}
16
17impl v2::Client {
18  pub fn get_catalog<'a, 'b: 'a>(&'b self, paginate: Option<u32>) -> impl Stream<Item = Result<String>> + 'a {
19    let url = {
20      let suffix = if let Some(n) = paginate {
21        format!("?n={n}")
22      } else {
23        "".to_string()
24      };
25      let ep = format!("{}/v2/_catalog{}", self.base_url.clone(), suffix);
26
27      reqwest::Url::parse(&ep).map_err(crate::Error::from)
28    };
29
30    try_stream! {
31        let req = self.build_reqwest(Method::GET, url?);
32
33        let catalog = fetch_catalog(req).await?;
34
35        for repo in catalog.repositories {
36            yield repo;
37        }
38    }
39  }
40}
41
42async fn fetch_catalog(req: RequestBuilder) -> Result<Catalog> {
43  let r = req.send().await?;
44  let status = r.status();
45  trace!("Got status: {status:?}");
46  match status {
47    StatusCode::OK => r.json::<Catalog>().await.map_err(Into::into),
48    _ => Err(crate::Error::UnexpectedHttpStatus(status)),
49  }
50}