libverify_core/
license.rs1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3pub enum LicenseCategory {
4 Permissive,
6 WeakCopyleft,
8 StrongCopyleft,
10 Unknown,
12}
13
14pub fn classify_license(spdx_id: &str) -> LicenseCategory {
16 let id = spdx_id.trim();
18
19 let strong_copyleft = [
21 "GPL-2.0",
22 "GPL-2.0-only",
23 "GPL-2.0-or-later",
24 "GPL-3.0",
25 "GPL-3.0-only",
26 "GPL-3.0-or-later",
27 "AGPL-3.0",
28 "AGPL-3.0-only",
29 "AGPL-3.0-or-later",
30 "SSPL-1.0",
31 "EUPL-1.2",
32 "EUPL-1.1",
33 "CECILL-2.1",
34 "OSL-3.0",
35 "RPL-1.5",
36 ];
37 for known in &strong_copyleft {
38 if id.eq_ignore_ascii_case(known) {
39 return LicenseCategory::StrongCopyleft;
40 }
41 }
42
43 let weak_copyleft = [
45 "LGPL-2.1",
46 "LGPL-2.1-only",
47 "LGPL-2.1-or-later",
48 "LGPL-3.0",
49 "LGPL-3.0-only",
50 "LGPL-3.0-or-later",
51 "MPL-2.0",
52 "EPL-2.0",
53 "EPL-1.0",
54 "CDDL-1.0",
55 "CDDL-1.1",
56 "CPL-1.0",
57 ];
58 for known in &weak_copyleft {
59 if id.eq_ignore_ascii_case(known) {
60 return LicenseCategory::WeakCopyleft;
61 }
62 }
63
64 let permissive = [
66 "MIT",
67 "Apache-2.0",
68 "BSD-2-Clause",
69 "BSD-3-Clause",
70 "ISC",
71 "Unlicense",
72 "0BSD",
73 "CC0-1.0",
74 "Zlib",
75 "BSL-1.0",
76 "PSF-2.0",
77 "Unicode-3.0",
78 "Unicode-DFS-2016",
79 "BlueOak-1.0.0",
80 "MIT-0",
81 ];
82 for known in &permissive {
83 if id.eq_ignore_ascii_case(known) {
84 return LicenseCategory::Permissive;
85 }
86 }
87
88 LicenseCategory::Unknown
89}
90
91pub fn is_copyleft(spdx_id: &str) -> bool {
93 matches!(
94 classify_license(spdx_id),
95 LicenseCategory::WeakCopyleft | LicenseCategory::StrongCopyleft
96 )
97}
98
99#[cfg(test)]
100mod tests {
101 use super::*;
102
103 #[test]
104 fn permissive_licenses() {
105 assert_eq!(classify_license("MIT"), LicenseCategory::Permissive);
106 assert_eq!(classify_license("Apache-2.0"), LicenseCategory::Permissive);
107 assert_eq!(
108 classify_license("BSD-3-Clause"),
109 LicenseCategory::Permissive
110 );
111 assert_eq!(classify_license("ISC"), LicenseCategory::Permissive);
112 assert_eq!(classify_license("Unlicense"), LicenseCategory::Permissive);
113 assert_eq!(classify_license("0BSD"), LicenseCategory::Permissive);
114 }
115
116 #[test]
117 fn weak_copyleft_licenses() {
118 assert_eq!(classify_license("LGPL-2.1"), LicenseCategory::WeakCopyleft);
119 assert_eq!(classify_license("MPL-2.0"), LicenseCategory::WeakCopyleft);
120 assert_eq!(classify_license("EPL-2.0"), LicenseCategory::WeakCopyleft);
121 assert_eq!(
122 classify_license("LGPL-3.0-only"),
123 LicenseCategory::WeakCopyleft
124 );
125 }
126
127 #[test]
128 fn strong_copyleft_licenses() {
129 assert_eq!(classify_license("GPL-2.0"), LicenseCategory::StrongCopyleft);
130 assert_eq!(classify_license("GPL-3.0"), LicenseCategory::StrongCopyleft);
131 assert_eq!(
132 classify_license("AGPL-3.0"),
133 LicenseCategory::StrongCopyleft
134 );
135 assert_eq!(
136 classify_license("SSPL-1.0"),
137 LicenseCategory::StrongCopyleft
138 );
139 assert_eq!(
140 classify_license("AGPL-3.0-or-later"),
141 LicenseCategory::StrongCopyleft
142 );
143 }
144
145 #[test]
146 fn unknown_license() {
147 assert_eq!(classify_license("PROPRIETARY"), LicenseCategory::Unknown);
148 assert_eq!(classify_license(""), LicenseCategory::Unknown);
149 }
150
151 #[test]
152 fn case_insensitive() {
153 assert_eq!(classify_license("mit"), LicenseCategory::Permissive);
154 assert_eq!(classify_license("gpl-3.0"), LicenseCategory::StrongCopyleft);
155 }
156
157 #[test]
158 fn is_copyleft_checks() {
159 assert!(!is_copyleft("MIT"));
160 assert!(!is_copyleft("Apache-2.0"));
161 assert!(is_copyleft("GPL-3.0"));
162 assert!(is_copyleft("LGPL-2.1"));
163 assert!(is_copyleft("AGPL-3.0"));
164 assert!(!is_copyleft("UNKNOWN"));
165 }
166
167 #[test]
168 fn whitespace_trimmed() {
169 assert_eq!(classify_license(" MIT "), LicenseCategory::Permissive);
170 }
171}