]> git.proxmox.com Git - rustc.git/blob - vendor/spdx-rs/src/models/file_information.rs
New upstream version 1.67.1+dfsg1
[rustc.git] / vendor / spdx-rs / src / models / file_information.rs
1 // SPDX-FileCopyrightText: 2020-2021 HH Partners
2 //
3 // SPDX-License-Identifier: MIT
4
5 use serde::{Deserialize, Serialize};
6 use spdx_expression::{SimpleExpression, SpdxExpression};
7
8 use super::{Algorithm, Checksum};
9
10 /// ## File Information
11 ///
12 /// SPDX's [File Information](https://spdx.github.io/spdx-spec/4-file-information/)
13 #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
14 #[serde(rename_all = "camelCase")]
15 pub struct FileInformation {
16 /// <https://spdx.github.io/spdx-spec/4-file-information/#41-file-name>
17 pub file_name: String,
18
19 /// <https://spdx.github.io/spdx-spec/4-file-information/#42-file-spdx-identifier>
20 #[serde(rename = "SPDXID")]
21 pub file_spdx_identifier: String,
22
23 /// <https://spdx.github.io/spdx-spec/4-file-information/#43-file-type>
24 #[serde(rename = "fileTypes", skip_serializing_if = "Vec::is_empty", default)]
25 pub file_type: Vec<FileType>,
26
27 /// <https://spdx.github.io/spdx-spec/4-file-information/#44-file-checksum>
28 #[serde(rename = "checksums")]
29 pub file_checksum: Vec<Checksum>,
30
31 /// <https://spdx.github.io/spdx-spec/4-file-information/#45-concluded-license>
32 #[serde(rename = "licenseConcluded")]
33 pub concluded_license: SpdxExpression,
34
35 /// <https://spdx.github.io/spdx-spec/4-file-information/#46-license-information-in-file>
36 #[serde(rename = "licenseInfoInFiles")]
37 pub license_information_in_file: Vec<SimpleExpression>,
38
39 /// <https://spdx.github.io/spdx-spec/4-file-information/#47-comments-on-license>
40 #[serde(
41 rename = "licenseComments",
42 skip_serializing_if = "Option::is_none",
43 default
44 )]
45 pub comments_on_license: Option<String>,
46
47 /// <https://spdx.github.io/spdx-spec/4-file-information/#48-copyright-text>
48 pub copyright_text: String,
49
50 /// <https://spdx.github.io/spdx-spec/4-file-information/#412-file-comment>
51 #[serde(rename = "comment", skip_serializing_if = "Option::is_none", default)]
52 pub file_comment: Option<String>,
53
54 /// <https://spdx.github.io/spdx-spec/4-file-information/#413-file-notice>
55 #[serde(
56 rename = "noticeText",
57 skip_serializing_if = "Option::is_none",
58 default
59 )]
60 pub file_notice: Option<String>,
61
62 /// <https://spdx.github.io/spdx-spec/4-file-information/#414-file-contributor>
63 #[serde(
64 rename = "fileContributors",
65 skip_serializing_if = "Vec::is_empty",
66 default
67 )]
68 pub file_contributor: Vec<String>,
69
70 /// <https://spdx.github.io/spdx-spec/4-file-information/#415-file-attribution-text>
71 #[serde(skip_serializing_if = "Option::is_none", default)]
72 pub file_attribution_text: Option<Vec<String>>,
73 // TODO: Snippet Information.
74 }
75
76 impl Default for FileInformation {
77 fn default() -> Self {
78 Self {
79 file_name: "NOASSERTION".to_string(),
80 file_spdx_identifier: "NOASSERTION".to_string(),
81 file_type: Vec::new(),
82 file_checksum: Vec::new(),
83 concluded_license: SpdxExpression::parse("NOASSERTION").expect("will always succeed"),
84 license_information_in_file: Vec::new(),
85 comments_on_license: None,
86 copyright_text: "NOASSERTION".to_string(),
87 file_comment: None,
88 file_notice: None,
89 file_contributor: Vec::new(),
90 file_attribution_text: None,
91 }
92 }
93 }
94
95 impl FileInformation {
96 /// Create new file.
97 pub fn new(name: &str, id: &mut i32) -> Self {
98 *id += 1;
99 Self {
100 file_name: name.to_string(),
101 file_spdx_identifier: format!("SPDXRef-{}", id),
102 ..Self::default()
103 }
104 }
105
106 /// Check if hash equals.
107 pub fn equal_by_hash(&self, algorithm: Algorithm, value: &str) -> bool {
108 let checksum = self
109 .file_checksum
110 .iter()
111 .find(|&checksum| checksum.algorithm == algorithm);
112
113 checksum.map_or(false, |checksum| {
114 checksum.value.to_ascii_lowercase() == value.to_ascii_lowercase()
115 })
116 }
117
118 /// Get checksum
119 pub fn checksum(&self, algorithm: Algorithm) -> Option<&str> {
120 let checksum = self
121 .file_checksum
122 .iter()
123 .find(|&checksum| checksum.algorithm == algorithm);
124
125 checksum.map(|checksum| checksum.value.as_str())
126 }
127 }
128
129 /// <https://spdx.github.io/spdx-spec/4-file-information/#43-file-type>
130 #[derive(Debug, Serialize, Deserialize, PartialEq, PartialOrd, Clone, Copy)]
131 #[serde(rename_all = "UPPERCASE")]
132 pub enum FileType {
133 Source,
134 Binary,
135 Archive,
136 Application,
137 Audio,
138 Image,
139 Text,
140 Video,
141 Documentation,
142 SPDX,
143 Other,
144 }
145
146 #[cfg(test)]
147 mod test {
148 use std::fs::read_to_string;
149
150 use super::*;
151 use crate::models::{Checksum, FileType, SPDX};
152
153 #[test]
154 fn checksum_equality() {
155 let mut id = 1;
156 let mut file_sha256 = FileInformation::new("sha256", &mut id);
157 file_sha256
158 .file_checksum
159 .push(Checksum::new(Algorithm::SHA256, "test"));
160
161 assert!(file_sha256.equal_by_hash(Algorithm::SHA256, "test"));
162 assert!(!file_sha256.equal_by_hash(Algorithm::SHA256, "no_test"));
163
164 let mut file_md5 = FileInformation::new("md5", &mut id);
165 file_md5
166 .file_checksum
167 .push(Checksum::new(Algorithm::MD5, "test"));
168 assert!(file_md5.equal_by_hash(Algorithm::MD5, "test"));
169 assert!(!file_md5.equal_by_hash(Algorithm::MD5, "no_test"));
170 assert!(!file_md5.equal_by_hash(Algorithm::SHA1, "test"));
171 }
172
173 #[test]
174 fn get_checksum() {
175 let mut id = 1;
176 let mut file_sha256 = FileInformation::new("sha256", &mut id);
177 file_sha256
178 .file_checksum
179 .push(Checksum::new(Algorithm::SHA256, "test"));
180
181 assert_eq!(file_sha256.checksum(Algorithm::SHA256), Some("test"));
182 assert_eq!(file_sha256.checksum(Algorithm::MD2), None);
183
184 let mut file_md5 = FileInformation::new("md5", &mut id);
185 file_md5
186 .file_checksum
187 .push(Checksum::new(Algorithm::MD5, "test"));
188
189 assert_eq!(file_md5.checksum(Algorithm::MD5), Some("test"));
190 }
191
192 #[test]
193 fn file_name() {
194 let spdx: SPDX = serde_json::from_str(
195 &read_to_string("tests/data/SPDXJSONExample-v2.2.spdx.json").unwrap(),
196 )
197 .unwrap();
198 assert_eq!(
199 spdx.file_information[0].file_name,
200 "./src/org/spdx/parser/DOAPProject.java"
201 );
202 }
203 #[test]
204 fn file_spdx_identifier() {
205 let spdx: SPDX = serde_json::from_str(
206 &read_to_string("tests/data/SPDXJSONExample-v2.2.spdx.json").unwrap(),
207 )
208 .unwrap();
209 assert_eq!(
210 spdx.file_information[0].file_spdx_identifier,
211 "SPDXRef-DoapSource"
212 );
213 }
214 #[test]
215 fn file_type() {
216 let spdx: SPDX = serde_json::from_str(
217 &read_to_string("tests/data/SPDXJSONExample-v2.2.spdx.json").unwrap(),
218 )
219 .unwrap();
220 assert_eq!(spdx.file_information[0].file_type, vec![FileType::Source]);
221 }
222 #[test]
223 fn file_checksum() {
224 let spdx: SPDX = serde_json::from_str(
225 &read_to_string("tests/data/SPDXJSONExample-v2.2.spdx.json").unwrap(),
226 )
227 .unwrap();
228 assert_eq!(
229 spdx.file_information[0].file_checksum,
230 vec![Checksum {
231 algorithm: Algorithm::SHA1,
232 value: "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12".to_string()
233 }]
234 );
235 }
236 #[test]
237 fn concluded_license() {
238 let spdx: SPDX = serde_json::from_str(
239 &read_to_string("tests/data/SPDXJSONExample-v2.2.spdx.json").unwrap(),
240 )
241 .unwrap();
242 assert_eq!(
243 spdx.file_information[0].concluded_license,
244 SpdxExpression::parse("Apache-2.0").unwrap()
245 );
246 }
247 #[test]
248 fn license_information_in_file() {
249 let spdx: SPDX = serde_json::from_str(
250 &read_to_string("tests/data/SPDXJSONExample-v2.2.spdx.json").unwrap(),
251 )
252 .unwrap();
253 assert_eq!(
254 spdx.file_information[0].license_information_in_file,
255 vec![SimpleExpression::parse("Apache-2.0").unwrap()]
256 );
257 }
258 #[test]
259 fn comments_on_license() {
260 let spdx: SPDX = serde_json::from_str(
261 &read_to_string("tests/data/SPDXJSONExample-v2.2.spdx.json").unwrap(),
262 )
263 .unwrap();
264 assert_eq!(
265 spdx.file_information[2].comments_on_license,
266 Some("This license is used by Jena".to_string())
267 );
268 }
269 #[test]
270 fn copyright_text() {
271 let spdx: SPDX = serde_json::from_str(
272 &read_to_string("tests/data/SPDXJSONExample-v2.2.spdx.json").unwrap(),
273 )
274 .unwrap();
275 assert_eq!(
276 spdx.file_information[0].copyright_text,
277 "Copyright 2010, 2011 Source Auditor Inc.".to_string()
278 );
279 }
280 #[test]
281 fn file_comment() {
282 let spdx: SPDX = serde_json::from_str(
283 &read_to_string("tests/data/SPDXJSONExample-v2.2.spdx.json").unwrap(),
284 )
285 .unwrap();
286 assert_eq!(
287 spdx.file_information[1].file_comment,
288 Some("This file is used by Jena".to_string())
289 );
290 }
291 #[test]
292 fn file_notice() {
293 let spdx: SPDX = serde_json::from_str(
294 &read_to_string("tests/data/SPDXJSONExample-v2.2.spdx.json").unwrap(),
295 )
296 .unwrap();
297 assert_eq!(
298 spdx.file_information[1].file_notice,
299 Some("Apache Commons Lang\nCopyright 2001-2011 The Apache Software Foundation\n\nThis product includes software developed by\nThe Apache Software Foundation (http://www.apache.org/).\n\nThis product includes software from the Spring Framework,\nunder the Apache License 2.0 (see: StringUtils.containsWhitespace())".to_string())
300 );
301 }
302 #[test]
303 fn file_contributor() {
304 let spdx: SPDX = serde_json::from_str(
305 &read_to_string("tests/data/SPDXJSONExample-v2.2.spdx.json").unwrap(),
306 )
307 .unwrap();
308 assert_eq!(
309 spdx.file_information[1].file_contributor,
310 vec!["Apache Software Foundation".to_string()]
311 );
312 }
313 }