@@ -11,6 +11,15 @@ const NAMESPACE: Uuid = Uuid::from_bytes([
1111 0xde , 0xad , 0xbe , 0xef , 0xca , 0xfe , 0x41 , 0x18 , 0xa1 , 0x38 , 0xb8 , 0x9f , 0x19 , 0x35 , 0xe0 , 0xa7 ,
1212] ) ;
1313
14+ /// SPDX license information extracted from an SPDX expression
15+ #[ derive( Debug , Clone , PartialEq , Eq ) ]
16+ pub struct SPDXInfo {
17+ pub spdx_licenses : Vec < String > ,
18+ pub spdx_license_exceptions : Vec < String > ,
19+ pub custom_license_refs : Vec < String > ,
20+ pub custom_document_license_refs : Vec < String > ,
21+ }
22+
1423#[ derive( Default , Debug , Clone , PartialEq , Eq ) ]
1524pub struct LicenseInfo {
1625 pub license : String ,
@@ -22,7 +31,7 @@ impl LicenseInfo {
2231 Uuid :: new_v5 ( & NAMESPACE , self . license . to_lowercase ( ) . as_bytes ( ) )
2332 }
2433
25- pub fn spdx_info ( & self ) -> ( Vec < String > , Vec < String > , Vec < String > , Vec < String > ) {
34+ pub fn spdx_info ( & self ) -> SPDXInfo {
2635 SpdxExpression :: parse ( & self . license )
2736 . map ( |parsed| {
2837 let spdx_licenses = parsed
@@ -53,23 +62,65 @@ impl LicenseInfo {
5362 . licenses ( )
5463 . iter ( )
5564 . filter ( |e| e. license_ref && e. document_ref . is_some ( ) )
56- . map ( |e| {
57- if let Some ( doc_ref ) = & e. document_ref {
65+ . filter_map ( |e| {
66+ e. document_ref . as_ref ( ) . map ( |doc_ref| {
5867 format ! ( "DocumentRef-{}:LicenseRef-{}" , doc_ref, e. identifier)
59- } else {
60- String :: default ( )
61- }
68+ } )
6269 } )
6370 . collect :: < Vec < _ > > ( ) ;
6471
65- (
72+ SPDXInfo {
6673 spdx_licenses,
6774 spdx_license_exceptions,
6875 custom_license_refs,
6976 custom_document_license_refs,
70- )
77+ }
78+ } )
79+ . unwrap_or ( SPDXInfo {
80+ spdx_licenses : vec ! [ ] ,
81+ spdx_license_exceptions : vec ! [ ] ,
82+ custom_license_refs : vec ! [ ] ,
83+ custom_document_license_refs : vec ! [ ] ,
7184 } )
72- . unwrap_or ( ( vec ! [ ] , vec ! [ ] , vec ! [ ] , vec ! [ ] ) )
85+ }
86+ }
87+
88+ pub struct LicenseBuilder {
89+ pub license_info : LicenseInfo ,
90+ }
91+
92+ impl LicenseBuilder {
93+ pub fn new ( license_info : LicenseInfo ) -> Self {
94+ Self { license_info }
95+ }
96+
97+ pub fn to_active_model ( & self ) -> license:: ActiveModel {
98+ let spdx_info = self . license_info . spdx_info ( ) ;
99+
100+ license:: ActiveModel {
101+ id : Set ( self . license_info . uuid ( ) ) ,
102+ text : Set ( self . license_info . license . clone ( ) ) ,
103+ spdx_licenses : if spdx_info. spdx_licenses . is_empty ( ) {
104+ Set ( None )
105+ } else {
106+ Set ( Some ( spdx_info. spdx_licenses ) )
107+ } ,
108+ spdx_license_exceptions : if spdx_info. spdx_license_exceptions . is_empty ( ) {
109+ Set ( None )
110+ } else {
111+ Set ( Some ( spdx_info. spdx_license_exceptions ) )
112+ } ,
113+ custom_license_refs : if spdx_info. custom_license_refs . is_empty ( ) {
114+ Set ( None )
115+ } else {
116+ Set ( Some ( spdx_info. custom_license_refs ) )
117+ } ,
118+ custom_document_license_refs : if spdx_info. custom_document_license_refs . is_empty ( ) {
119+ Set ( None )
120+ } else {
121+ Set ( Some ( spdx_info. custom_document_license_refs ) )
122+ } ,
123+ }
73124 }
74125}
75126
@@ -81,37 +132,42 @@ pub struct LicenseCreator {
81132 /// database.
82133 pub licenses : BTreeMap < Uuid , license:: ActiveModel > ,
83134
84- pub custom_license_list : Vec < licensing_infos:: ActiveModel > ,
135+ /// Custom license lookup map: license_id -> name
136+ custom_license_map : std:: collections:: HashMap < String , String > ,
85137}
86138
87139impl LicenseCreator {
88140 pub fn new ( ) -> Self {
89141 Self {
90142 licenses : Default :: default ( ) ,
91- custom_license_list : vec ! [ ] ,
143+ custom_license_map : std :: collections :: HashMap :: new ( ) ,
92144 }
93145 }
94146
95147 pub fn put_custom_license_list (
96148 & mut self ,
97- custom_license_list : Vec < licensing_infos:: ActiveModel > ,
149+ custom_license_list : & [ licensing_infos:: ActiveModel ] ,
98150 ) {
99- self . custom_license_list = custom_license_list;
151+ self . custom_license_map = custom_license_list
152+ . iter ( )
153+ . filter_map ( |c| {
154+ if let ( Set ( license_id) , Set ( name) ) = ( & c. license_id , & c. name ) {
155+ Some ( ( license_id. clone ( ) , name. clone ( ) ) )
156+ } else {
157+ None
158+ }
159+ } )
160+ . collect ( ) ;
100161 }
101162
102163 pub fn add ( & mut self , info : & LicenseInfo ) {
103164 let uuid = info. uuid ( ) ;
104165
105- let ( spdx_licenses , spdx_exceptions , custom_license_refs , custom_document_license_refs ) =
106- info . spdx_info ( ) ;
107- let missing_custom_refs : Vec < _ > = custom_license_refs
166+ let spdx_info = info . spdx_info ( ) ;
167+ let missing_custom_refs : Vec < _ > = spdx_info
168+ . custom_license_refs
108169 . iter ( )
109- . filter ( |ref_id| {
110- !self
111- . custom_license_list
112- . iter ( )
113- . any ( |c| c. license_id == Set ( ( * ref_id) . to_string ( ) ) )
114- } )
170+ . filter ( |ref_id| !self . custom_license_map . contains_key ( * ref_id) )
115171 . cloned ( )
116172 . collect ( ) ;
117173 if !missing_custom_refs. is_empty ( ) {
@@ -120,51 +176,30 @@ impl LicenseCreator {
120176 missing_custom_refs
121177 ) ;
122178 }
123- let custom_license_refs_value = if custom_license_refs. is_empty ( ) {
179+ let custom_license_refs_value = if spdx_info . custom_license_refs . is_empty ( ) {
124180 None
125181 } else {
126- Some ( self . construct_custom_license ( custom_license_refs. clone ( ) ) )
182+ Some ( self . construct_custom_license ( spdx_info . custom_license_refs . clone ( ) ) )
127183 } ;
128184
129- self . licenses . entry ( uuid) . or_insert ( license:: ActiveModel {
130- id : Set ( uuid) ,
131- text : Set ( info. license . clone ( ) ) ,
132- spdx_licenses : if spdx_licenses. is_empty ( ) {
133- Set ( None )
134- } else {
135- Set ( Some ( spdx_licenses) )
136- } ,
137- spdx_license_exceptions : if spdx_exceptions. is_empty ( ) {
138- Set ( None )
139- } else {
140- Set ( Some ( spdx_exceptions) )
141- } ,
142- custom_license_refs : Set ( custom_license_refs_value) ,
143- custom_document_license_refs : if custom_document_license_refs. is_empty ( ) {
144- Set ( None )
145- } else {
146- Set ( Some ( custom_document_license_refs) )
147- } ,
148- } ) ;
185+ let mut active_model = LicenseBuilder :: new ( info. clone ( ) ) . to_active_model ( ) ;
186+
187+ // Update custom_license_refs with constructed value
188+ if let Some ( refs) = custom_license_refs_value {
189+ active_model. custom_license_refs = Set ( Some ( refs) ) ;
190+ }
191+
192+ self . licenses . entry ( uuid) . or_insert ( active_model) ;
149193 }
150194
151195 fn construct_custom_license ( & self , custom_license_ids : Vec < String > ) -> Vec < String > {
152- use std:: collections:: HashMap ;
153- // Build a HashMap from license_id to name for fast lookup
154- let license_map: HashMap < & String , & String > = self
155- . custom_license_list
156- . iter ( )
157- . filter_map ( |c| {
158- if let ( Set ( license_id) , Set ( name) ) = ( & c. license_id , & c. name ) {
159- Some ( ( license_id, name) )
160- } else {
161- None
162- }
163- } )
164- . collect ( ) ;
165196 custom_license_ids
166197 . into_iter ( )
167- . filter_map ( |id| license_map. get ( & id) . map ( |name| format ! ( "{}:{}" , id, name) ) )
198+ . filter_map ( |id| {
199+ self . custom_license_map
200+ . get ( & id)
201+ . map ( |name| format ! ( "{}:{}" , id, name) )
202+ } )
168203 . collect ( )
169204 }
170205
0 commit comments