1mod geiger;
2mod krates_mapping;
3mod metadata;
4
5use metadata::package_id::ToCargoMetadataPackage;
6
7use ::krates::Krates;
8use cargo::core::dependency::DepKind;
9use krates::cm::Metadata;
10use std::collections::HashSet;
11use std::fmt::Display;
12use std::path::PathBuf;
13
14use krates::cm::Dependency as CargoMetadataDependency;
15use krates::cm::PackageId as CargoMetadataPackageId;
16use krates::semver::Version as CargoMetadataVersion;
17
18use crate::mapping::krates_mapping::GetPackage;
19use crate::mapping::metadata::dependency::GetDependencyInformation;
20use crate::mapping::metadata::package::GetPackageInformation;
21use crate::mapping::metadata::GetMetadataPackages;
22
23use cargo_geiger_serde::DependencyKind as CargoGeigerSerdeDependencyKind;
24use cargo_geiger_serde::PackageId as CargoGeigerSerdePackageId;
25use cargo_geiger_serde::Source as CargoGeigerSerdeSource;
26
27pub struct CargoMetadataParameters<'a> {
30 pub krates: &'a Krates,
31 pub metadata: &'a Metadata,
32}
33
34pub trait DepsNotReplaced {
35 fn deps_not_replaced<T: ToCargoMetadataPackage + Display>(
36 &self,
37 package_id: &T,
38 is_root_package: bool,
39 ) -> Option<Vec<(CargoMetadataPackageId, HashSet<CargoMetadataDependency>)>>;
40}
41
42pub trait GetPackageIdInformation {
43 fn get_package_id_licence<T: GetPackage>(
44 &self,
45 krates: &T,
46 ) -> Option<String>;
47
48 fn get_package_id_name_and_version<T: GetPackage>(
49 &self,
50 krates: &T,
51 ) -> Option<(String, CargoMetadataVersion)>;
52
53 fn get_package_id_repository<T: GetPackage>(
54 &self,
55 krates: &T,
56 ) -> Option<String>;
57}
58
59pub trait GetPackageRoot: GetPackageInformation {
60 fn get_root(&self) -> Option<PathBuf> {
61 match self.get_package_parent() {
62 Some(path) => Some(path.to_path_buf()),
63 None => {
64 eprintln!(
65 "Failed to get root for: {} {:?}",
66 self.get_package_name(),
67 self.get_package_version()
68 );
69 None
70 }
71 }
72 }
73}
74
75pub trait MatchesIgnoringSource {
76 fn matches_ignoring_source<
77 T: GetPackage,
78 U: GetPackageIdInformation + Display,
79 >(
80 &self,
81 krates: &T,
82 package_id: &U,
83 ) -> Option<bool>;
84}
85
86pub trait QueryResolve {
87 fn query_resolve(&self, query: &str) -> Option<CargoMetadataPackageId>;
88}
89
90pub trait ToCargoCoreDepKind {
91 fn to_cargo_core_dep_kind(&self) -> DepKind;
92}
93
94pub trait ToCargoGeigerDependencyKind {
95 fn to_cargo_geiger_dependency_kind(
96 &self,
97 ) -> Option<CargoGeigerSerdeDependencyKind>;
98}
99
100pub trait ToCargoGeigerPackageId {
101 fn to_cargo_geiger_package_id(
102 &self,
103 metadata: &Metadata,
104 ) -> Option<CargoGeigerSerdePackageId>;
105}
106
107pub trait ToCargoGeigerSource {
108 fn to_cargo_geiger_source(
109 &self,
110 metadata: &Metadata,
111 ) -> CargoGeigerSerdeSource;
112}
113
114pub trait ToCargoMetadataPackageId: GetDependencyInformation {
115 fn to_cargo_metadata_package_id<T: GetMetadataPackages>(
116 &self,
117 metadata: &T,
118 ) -> Option<CargoMetadataPackageId> {
119 metadata
120 .get_metadata_packages()
121 .filter(|p| {
122 p.name == self.get_dependency_name()
123 && self.get_dependency_version_req().matches(&p.version)
124 })
125 .map(|p| p.id.clone())
126 .collect::<Vec<CargoMetadataPackageId>>()
127 .pop()
128 }
129}
130
131#[cfg(test)]
132mod mapping_tests {
133 use super::*;
134
135 use rstest::*;
136 use std::path::Path;
137
138 struct MockPackage<'a> {
139 mock_package_name: String,
140 mock_package_parent: Option<&'a Path>,
141 mock_package_version: CargoMetadataVersion,
142 }
143
144 impl GetPackageInformation for MockPackage<'_> {
145 fn get_package_name(&self) -> String {
146 self.mock_package_name.clone()
147 }
148
149 fn get_package_parent(&self) -> Option<&Path> {
150 self.mock_package_parent
151 }
152
153 fn get_package_version(&self) -> CargoMetadataVersion {
154 self.mock_package_version.clone()
155 }
156 }
157
158 impl GetPackageRoot for MockPackage<'_> {}
159
160 #[rstest(
161 input_package_path_option,
162 expected_package_path_buf_option,
163 case(
164 Some(Path::new("/path/to/file")),
165 Some(PathBuf::from("/path/to/file"))
166 ),
167 case(None, None)
168 )]
169 fn get_package_root_test(
170 input_package_path_option: Option<&Path>,
171 expected_package_path_buf_option: Option<PathBuf>,
172 ) {
173 let _mock_package_parent = input_package_path_option;
174
175 let mock_package = MockPackage {
176 mock_package_name: String::from("package_name"),
177 mock_package_parent: input_package_path_option,
178 mock_package_version: CargoMetadataVersion::new(1, 1, 1),
179 };
180
181 assert_eq!(mock_package.get_root(), expected_package_path_buf_option)
182 }
183}