docker_registry/v2/
catalog.rs1use 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}