1 | // SPDX-FileCopyrightText: 2020-2021 HH Partners |
2 | // |
3 | // SPDX-License-Identifier: MIT |
4 | |
5 | use serde::{Deserialize, Serialize}; |
6 | use strum_macros::AsRefStr; |
7 | |
8 | /// <https://spdx.github.io/spdx-spec/7-relationships-between-SPDX-elements/#71-relationship> |
9 | #[derive (Debug, Serialize, Deserialize, PartialEq, Clone, Eq, Hash)] |
10 | #[serde(rename_all = "camelCase" )] |
11 | pub struct Relationship { |
12 | /// SPDX ID of the element. |
13 | pub spdx_element_id: String, |
14 | |
15 | /// SPDX ID of the related element. |
16 | pub related_spdx_element: String, |
17 | |
18 | /// Type of the relationship. |
19 | pub relationship_type: RelationshipType, |
20 | |
21 | /// <https://spdx.github.io/spdx-spec/7-relationships-between-SPDX-elements/#72-relationship-comment> |
22 | #[serde(skip_serializing_if = "Option::is_none" )] |
23 | #[serde(default)] |
24 | pub comment: Option<String>, |
25 | } |
26 | |
27 | impl Relationship { |
28 | /// Create a new relationship. |
29 | pub fn new( |
30 | spdx_element_id: &str, |
31 | related_spdx_element: &str, |
32 | relationship_type: RelationshipType, |
33 | comment: Option<String>, |
34 | ) -> Self { |
35 | Self { |
36 | spdx_element_id: spdx_element_id.to_string(), |
37 | related_spdx_element: related_spdx_element.to_string(), |
38 | relationship_type, |
39 | comment, |
40 | } |
41 | } |
42 | } |
43 | |
44 | /// <https://spdx.github.io/spdx-spec/7-relationships-between-SPDX-elements/#71-relationship> |
45 | #[derive (Serialize, Deserialize, Debug, PartialEq, Clone, AsRefStr, Eq, Hash)] |
46 | #[serde(rename_all = "SCREAMING_SNAKE_CASE" )] |
47 | pub enum RelationshipType { |
48 | Describes, |
49 | DescribedBy, |
50 | Contains, |
51 | ContainedBy, |
52 | DependsOn, |
53 | DependencyOf, |
54 | DependencyManifestOf, |
55 | BuildDependencyOf, |
56 | DevDependencyOf, |
57 | OptionalDependencyOf, |
58 | ProvidedDependencyOf, |
59 | TestDependencyOf, |
60 | RuntimeDependencyOf, |
61 | ExampleOf, |
62 | Generates, |
63 | GeneratedFrom, |
64 | AncestorOf, |
65 | DescendantOf, |
66 | VariantOf, |
67 | DistributionArtifact, |
68 | PatchFor, |
69 | PatchApplied, |
70 | CopyOf, |
71 | FileAdded, |
72 | FileDeleted, |
73 | FileModified, |
74 | ExpandedFromArchive, |
75 | DynamicLink, |
76 | StaticLink, |
77 | DataFileOf, |
78 | TestCaseOf, |
79 | BuildToolOf, |
80 | DevToolOf, |
81 | TestOf, |
82 | TestToolOf, |
83 | DocumentationOf, |
84 | OptionalComponentOf, |
85 | MetafileOf, |
86 | PackageOf, |
87 | Amends, |
88 | PrerequisiteFor, |
89 | HasPrerequisite, |
90 | RequirementDescriptionFor, |
91 | SpecificationFor, |
92 | Other, |
93 | } |
94 | |
95 | #[cfg (test)] |
96 | mod test { |
97 | use std::fs::read_to_string; |
98 | |
99 | use crate::models::SPDX; |
100 | |
101 | use super::*; |
102 | |
103 | #[test ] |
104 | fn spdx_element_id() { |
105 | let spdx: SPDX = serde_json::from_str( |
106 | &read_to_string("tests/data/SPDXJSONExample-v2.2.spdx.json" ).unwrap(), |
107 | ) |
108 | .unwrap(); |
109 | assert_eq!( |
110 | spdx.relationships[0].spdx_element_id, |
111 | "SPDXRef-DOCUMENT" .to_string() |
112 | ); |
113 | } |
114 | #[test ] |
115 | fn related_spdx_element() { |
116 | let spdx: SPDX = serde_json::from_str( |
117 | &read_to_string("tests/data/SPDXJSONExample-v2.2.spdx.json" ).unwrap(), |
118 | ) |
119 | .unwrap(); |
120 | assert_eq!( |
121 | spdx.relationships[0].related_spdx_element, |
122 | "SPDXRef-Package" .to_string() |
123 | ); |
124 | } |
125 | #[test ] |
126 | fn relationship_type() { |
127 | let spdx: SPDX = serde_json::from_str( |
128 | &read_to_string("tests/data/SPDXJSONExample-v2.2.spdx.json" ).unwrap(), |
129 | ) |
130 | .unwrap(); |
131 | assert_eq!( |
132 | spdx.relationships[0].relationship_type, |
133 | RelationshipType::Contains |
134 | ); |
135 | assert_eq!( |
136 | spdx.relationships[2].relationship_type, |
137 | RelationshipType::CopyOf |
138 | ); |
139 | } |
140 | } |
141 | |