nuget_client/ops/
get_package_versions.rs1use std::pin::Pin;
2
3use futures::{Stream, StreamExt};
4use serde::{Deserialize, Serialize};
5use crate::Result;
6
7use crate::model::PackageMetadata;
8
9#[derive(Debug, Deserialize, Clone, Serialize)]
10struct RootResponse {
11 count: usize,
12 items: Vec<RegistrationPage>
13}
14
15#[derive(Debug, Deserialize, Clone, Serialize)]
16struct RegistrationPage {
17 #[serde(rename = "@id")]
18 id: String,
19 count: usize,
20 items: Option<Vec<RegistrationLeaf>>,
21 parent: Option<String>,
22 lower: Option<String>,
23 upper: Option<String>,
24}
25impl RegistrationPage {
26 async fn content<'a>(self, nuget: &'a crate::NugetRegistry) -> Result<OpaqueRegLeafStream<'a>> {
27 if let Some(items) = self.items {
28 return Ok(Box::pin(futures::stream::iter(items.into_iter().map(Ok))));
29 }
30
31 let url = nuget.client.get(self.id.clone()).send().await?.error_for_status()?.bytes().await?;
32 let url: RegistrationPage = serde_json::from_slice(&url)?;
33
34 Ok(Box::pin(futures::stream::iter(url.items.unwrap().into_iter().map(Ok))))
35 }
36}
37
38#[derive(Debug, Deserialize, Clone, Serialize)]
39#[non_exhaustive]
40#[serde(rename_all = "camelCase")]
41pub struct RegistrationLeaf {
42 #[serde(rename = "@id")]
43 pub id: String,
44 pub catalog_entry: PackageMetadata,
45 pub package_content: String,
46}
47
48type OpaqueRegLeafStream<'a> = Pin<Box<dyn Stream<Item=Result<RegistrationLeaf>> + Send + 'a>>;
49
50pub async fn execute<'a>(nuget: &'a crate::NugetRegistry, package_name: &str) -> Result<impl Stream<Item=Result<RegistrationLeaf>> + Send + Unpin + 'a> {
51 let base_url = nuget.resource_arr(&[
52 "RegistrationsBaseUrl/3.6.0",
53 "RegistrationsBaseUrl/3.4.0",
54 "RegistrationsBaseUrl/3.0.0-rc",
55 "RegistrationsBaseUrl/3.0.0-beta",
56 "RegistrationsBaseUrl/3.0.0",
57 ])?;
58
59 let mut suffix = format!("{}/index.json", package_name);
60 suffix.make_ascii_lowercase();
61 let url = base_url.join(&suffix)?;
62 dbg!((&base_url, &suffix, &url));
63
64 let root = nuget.client.get(url).send().await?.error_for_status()?.bytes().await?;
65 let root: RootResponse = serde_json::from_slice(&root)?;
66
67 dbg!(&root);
68
69 let mut stream = futures::stream::iter(root.items);
70 let mut stream = stream.flat_map(move |page| futures::stream::once(async move {
71 match page.content(nuget).await {
72 Ok(stream) => stream,
73 Err(e) => Box::pin(futures::stream::once(async move { Err(e) })) as OpaqueRegLeafStream<'a>
74 }
75 }).flatten());
76
77 Ok(Box::pin(stream))
78}