Skip to main content

package_parser/pkgs/
chef_json.rs

1use packageurl::PackageUrl;
2use serde_json::from_reader;
3use serde_json::Value;
4
5use crate::error::SourcePkgError;
6use crate::pkgs::common::model::{DependentPackage, Package, PackageManifest};
7
8use std::fs::File;
9use std::path::Path;
10
11pub struct ChefJson {}
12
13impl ChefJson {
14    pub fn new() -> Self {
15        Self {}
16    }
17
18    fn parse(path: impl AsRef<Path>) -> Result<Package, SourcePkgError> {
19        let mut file = File::open(path)?;
20        let root: Value = from_reader(&mut file)?;
21
22        let name = match &root["name"] {
23            Value::String(name) => name.into(),
24            _ => "".into(),
25        };
26        let version = match &root["version"] {
27            Value::String(version) => version.into(),
28            _ => "".into(),
29        };
30        let license = match &root["license"] {
31            Value::String(license) => license.into(),
32            _ => "".into(),
33        };
34        let requirements = match &root["dependencies"] {
35            Value::Object(dependencies) => {
36                let mut requirements = vec![];
37                for (name, version) in dependencies {
38                    let version = match version {
39                        Value::String(name) => name.into(),
40                        _ => "".into(),
41                    };
42
43                    // FIXME: fix the purl name
44                    requirements.push(DependentPackage {
45                        purl: PackageUrl::new("chef", name)
46                            .expect("purl arguments are invalid")
47                            .to_string(),
48                        requirement: version,
49                        ..Default::default()
50                    });
51                }
52                requirements
53            }
54            _ => vec![],
55        };
56
57        let package = Package {
58            name,
59            version,
60            declared_license: license,
61            dependencies: requirements,
62            ..Default::default()
63        };
64
65        Ok(package)
66    }
67}
68
69#[async_trait::async_trait]
70impl PackageManifest for ChefJson {
71    fn get_name(&self) -> String {
72        "chef".into()
73    }
74
75    async fn recognize(&self, path: &Path) -> Result<Package, SourcePkgError> {
76        Self::parse(path)
77    }
78
79    fn file_name_patterns(&self) -> &'static [&'static str] {
80        &["metadata.json"]
81    }
82}