package_parser/pkgs/dotnet/
nuget_central.rs1use std::path::Path;
2
3use packageurl::PackageUrl;
4use crate::types::{DependentPackage, Package};
5use serde::Deserialize;
6
7use crate::{error::SourcePkgError, PackageManifest};
8
9#[derive(Debug, Deserialize)]
10struct Project {
11 #[serde(rename = "ItemGroup")]
12 item_group: ItemGroup,
13}
14
15#[derive(Debug, Deserialize)]
16struct ItemGroup {
17 #[serde(rename = "PackageVersion", default)]
18 items: Vec<PackageVersion>,
19}
20
21#[derive(Debug, Deserialize)]
22struct PackageVersion {
23 #[serde(rename = "Include")]
24 name: String,
25 #[serde(rename = "Version")]
26 version: String,
27}
28
29pub struct NuGetCentral;
30
31impl NuGetCentral {
32 pub fn new() -> Self {
33 Self
34 }
35
36 async fn parse(path: impl AsRef<Path>) -> Result<Package, SourcePkgError> {
37 let content = tokio::fs::read_to_string(path).await?;
38 let project: Project = quick_xml::de::from_str(&content)?;
39
40 let mut dependencies = vec![];
41
42 for item in project.item_group.items {
43 dependencies.push(DependentPackage {
44 purl: PackageUrl::new("nuget", item.name)
45 .unwrap()
46 .with_version(&item.version)
47 .to_string(),
48 requirement: item.version,
49 is_resolved: true,
50 is_optional: false,
51 is_runtime: true,
52 ..Default::default()
53 });
54 }
55
56 Ok(Package {
57 dependencies,
58 ..Default::default()
59 })
60 }
61}
62
63#[async_trait::async_trait]
64impl PackageManifest for NuGetCentral {
65 fn get_name(&self) -> String {
66 "nuget".into()
67 }
68
69 async fn recognize(&self, path: &Path) -> Result<Package, SourcePkgError> {
70 let root = Self::parse(path).await?;
71 Ok(root)
72 }
73
74 fn file_name_patterns(&self) -> &'static [&'static str] {
75 &[
76 "Directory.packages.props",
77 "Directory.Packages.props",
78 "directory.packages.props",
79 "directory.Packages.props",
80 ]
81 }
82}
83
84#[cfg(test)]
85mod test {
86 use super::*;
87
88 #[tokio::test]
89 async fn central() {
90 let path = Path::new(concat!(
91 env!("CARGO_MANIFEST_DIR"),
92 "/testdata/nuget/Directory.packages.props"
93 ));
94 let package = NuGetCentral::new().recognize(path).await.unwrap();
95 dbg!(package);
96 }
97}