4343//! // Create an empty triples map
4444//! let triples = TriplesMap {
4545//! reference_triples: None,
46- //! endorse_triples : None,
46+ //! endorsed_triples : None,
4747//! identity_triples: None,
4848//! attest_key_triples: None,
4949//! dependency_triples: None,
5858//! let comid = ConciseMidTag {
5959//! language: None,
6060//! tag_identity,
61- //! entities: vec![entity],
61+ //! entities: Some( vec![entity].into()) ,
6262//! linked_tags: None,
6363//! triples,
6464//! extension: None,
8585//! All components support optional extensions through [`ExtensionMap`] for future expandability.
8686
8787use crate :: {
88- core:: { RawValueType , TaggedBytes } ,
88+ core:: { NonEmptyVec , RawValueType , TaggedBytes } ,
8989 generate_tagged,
9090 triples:: { EnvironmentMap , MeasuredElementTypeChoice , MeasurementMap , MeasurementValuesMap } ,
91- AttestKeyTripleRecord , ConditionalEndorsementSeriesTripleRecord ,
91+ AttestKeyTripleRecord , ComidError , ConditionalEndorsementSeriesTripleRecord ,
9292 ConditionalEndorsementTripleRecord , CoswidTripleRecord , DomainDependencyTripleRecord ,
9393 DomainMembershipTripleRecord , EndorsedTripleRecord , ExtensionMap , IdentityTripleRecord ,
94- ReferenceTripleRecord , Text , Tstr , Uint , Uri , UuidType ,
94+ ReferenceTripleRecord , Result , Text , Tstr , Uint , Uri , UuidType ,
9595} ;
9696use derive_more:: { Constructor , From , TryFrom } ;
9797use serde:: { Deserialize , Serialize } ;
@@ -120,12 +120,13 @@ pub struct ConciseMidTag<'a> {
120120 #[ serde( rename = "1" ) ]
121121 pub tag_identity : TagIdentityMap < ' a > ,
122122 /// List of entities associated with this tag
123+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
123124 #[ serde( rename = "2" ) ]
124- pub entities : Vec < ComidEntityMap < ' a > > ,
125+ pub entities : Option < NonEmptyVec < ComidEntityMap < ' a > > > ,
125126 /// Optional references to other related tags
126127 #[ serde( skip_serializing_if = "Option::is_none" ) ]
127128 #[ serde( rename = "3" ) ]
128- pub linked_tags : Option < Vec < LinkedTagMap < ' a > > > ,
129+ pub linked_tags : Option < NonEmptyVec < LinkedTagMap < ' a > > > ,
129130 /// Collection of triples describing the module
130131 #[ serde( rename = "4" ) ]
131132 pub triples : TriplesMap < ' a > ,
@@ -198,7 +199,7 @@ impl<'a> ConciseMidTag<'a> {
198199 environment : & EnvironmentMap < ' a > ,
199200 mkey : MeasuredElementTypeChoice < ' a > ,
200201 value : & T ,
201- ) -> Result < ( ) , std:: io:: Error >
202+ ) -> std:: io:: Result < ( ) >
202203 where
203204 T : ?Sized + Serialize ,
204205 {
@@ -223,17 +224,17 @@ impl<'a> ConciseMidTag<'a> {
223224 None => {
224225 let new_record = ReferenceTripleRecord {
225226 ref_env : environment. clone ( ) ,
226- ref_claims : vec ! [ measurement] ,
227+ ref_claims : vec ! [ measurement] . into ( ) ,
227228 } ;
228- self . triples . reference_triples = Some ( vec ! [ new_record] ) ;
229+ self . triples . reference_triples = Some ( vec ! [ new_record] . into ( ) ) ;
229230 }
230231 Some ( vec) => {
231232 if let Some ( record) = vec. iter_mut ( ) . find ( |r| r. ref_env == * environment) {
232233 record. ref_claims . push ( measurement) ;
233234 } else {
234235 let new_record = ReferenceTripleRecord {
235236 ref_env : environment. clone ( ) ,
236- ref_claims : vec ! [ measurement] ,
237+ ref_claims : vec ! [ measurement] . into ( ) ,
237238 } ;
238239 vec. push ( new_record) ;
239240 }
@@ -246,7 +247,7 @@ impl<'a> ConciseMidTag<'a> {
246247 environment : & EnvironmentMap < ' a > ,
247248 mkey : MeasuredElementTypeChoice < ' a > ,
248249 value : & T ,
249- ) -> Result < ( ) , std:: io:: Error >
250+ ) -> std:: io:: Result < ( ) >
250251 where
251252 T : ?Sized + Serialize ,
252253 {
@@ -267,13 +268,13 @@ impl<'a> ConciseMidTag<'a> {
267268 authorized_by : None ,
268269 } ;
269270
270- match & mut self . triples . endorse_triples {
271+ match & mut self . triples . endorsed_triples {
271272 None => {
272273 let new_record = EndorsedTripleRecord {
273274 condition : environment. clone ( ) ,
274- endorsement : vec ! [ measurement] ,
275+ endorsement : vec ! [ measurement] . into ( ) ,
275276 } ;
276- self . triples . endorse_triples = Some ( vec ! [ new_record] ) ;
277+ self . triples . endorsed_triples = Some ( vec ! [ new_record] . into ( ) ) ;
277278 }
278279
279280 Some ( vec) => {
@@ -282,7 +283,7 @@ impl<'a> ConciseMidTag<'a> {
282283 } else {
283284 let new_record = EndorsedTripleRecord {
284285 condition : environment. clone ( ) ,
285- endorsement : vec ! [ measurement] ,
286+ endorsement : vec ! [ measurement] . into ( ) ,
286287 } ;
287288 vec. push ( new_record) ;
288289 }
@@ -386,58 +387,171 @@ pub enum TagRelTypeChoice {
386387 Replaces ,
387388}
388389
389- /// Collection of different types of triples describing the module characteristics
390+ /// Collection of different types of triples describing the module characteristics. It is
391+ /// **HIGHLY** recommended to use the TriplesMapBuilder, to ensure the CDDL enforcement of
392+ /// at least one field being present.
390393#[ derive( Default , Debug , Serialize , Deserialize , From , PartialEq , Eq , PartialOrd , Ord , Clone ) ]
391394#[ repr( C ) ]
392395pub struct TriplesMap < ' a > {
393396 /// Optional reference triples that link to external references
394397 #[ serde( skip_serializing_if = "Option::is_none" ) ]
395398 #[ serde( rename = "0" ) ]
396- pub reference_triples : Option < Vec < ReferenceTripleRecord < ' a > > > ,
399+ pub reference_triples : Option < NonEmptyVec < ReferenceTripleRecord < ' a > > > ,
397400
398401 /// Optional endorsement triples that contain verification information
399402 #[ serde( skip_serializing_if = "Option::is_none" ) ]
400403 #[ serde( rename = "1" ) ]
401- pub endorse_triples : Option < Vec < EndorsedTripleRecord < ' a > > > ,
404+ pub endorsed_triples : Option < NonEmptyVec < EndorsedTripleRecord < ' a > > > ,
402405
403406 /// Optional identity triples that provide identity information
404407 #[ serde( skip_serializing_if = "Option::is_none" ) ]
405408 #[ serde( rename = "2" ) ]
406- pub identity_triples : Option < Vec < IdentityTripleRecord < ' a > > > ,
409+ pub identity_triples : Option < NonEmptyVec < IdentityTripleRecord < ' a > > > ,
407410
408411 /// Optional attestation key triples containing cryptographic keys
409412 #[ serde( skip_serializing_if = "Option::is_none" ) ]
410413 #[ serde( rename = "3" ) ]
411- pub attest_key_triples : Option < Vec < AttestKeyTripleRecord < ' a > > > ,
414+ pub attest_key_triples : Option < NonEmptyVec < AttestKeyTripleRecord < ' a > > > ,
412415
413416 /// Optional domain dependency triples describing relationships between domains
414417 #[ serde( skip_serializing_if = "Option::is_none" ) ]
415418 #[ serde( rename = "4" ) ]
416- pub dependency_triples : Option < Vec < DomainDependencyTripleRecord < ' a > > > ,
419+ pub dependency_triples : Option < NonEmptyVec < DomainDependencyTripleRecord < ' a > > > ,
417420
418421 /// Optional domain membership triples describing domain associations
419422 #[ serde( skip_serializing_if = "Option::is_none" ) ]
420423 #[ serde( rename = "5" ) ]
421- pub membership_triples : Option < Vec < DomainMembershipTripleRecord < ' a > > > ,
424+ pub membership_triples : Option < NonEmptyVec < DomainMembershipTripleRecord < ' a > > > ,
422425
423426 /// Optional SWID triples containing software identification data
424427 #[ serde( skip_serializing_if = "Option::is_none" ) ]
425428 #[ serde( rename = "6" ) ]
426- pub coswid_triples : Option < Vec < CoswidTripleRecord < ' a > > > ,
429+ pub coswid_triples : Option < NonEmptyVec < CoswidTripleRecord < ' a > > > ,
427430
428431 /// Optional conditional endorsement series triples for complex endorsement chains
429432 #[ serde( skip_serializing_if = "Option::is_none" ) ]
430433 #[ serde( rename = "8" ) ]
431434 pub conditional_endorsement_series_triples :
432- Option < Vec < ConditionalEndorsementSeriesTripleRecord < ' a > > > ,
435+ Option < NonEmptyVec < ConditionalEndorsementSeriesTripleRecord < ' a > > > ,
433436
434437 /// Optional conditional endorsement triples for conditional verification
435438 #[ serde( skip_serializing_if = "Option::is_none" ) ]
436439 #[ serde( rename = "10" ) ]
437- pub conditional_endorsement_triples : Option < Vec < ConditionalEndorsementTripleRecord < ' a > > > ,
440+ pub conditional_endorsement_triples :
441+ Option < NonEmptyVec < ConditionalEndorsementTripleRecord < ' a > > > ,
438442
439443 /// Optional extensible attributes for future expansion
440444 #[ serde( skip_serializing_if = "Option::is_none" ) ]
441445 #[ serde( flatten) ]
442446 pub extension : Option < ExtensionMap < ' a > > ,
443447}
448+
449+ #[ derive( Default ) ]
450+ pub struct TriplesMapBuilder < ' a > {
451+ reference_triples : Option < NonEmptyVec < ReferenceTripleRecord < ' a > > > ,
452+ endorsed_triples : Option < NonEmptyVec < EndorsedTripleRecord < ' a > > > ,
453+ identity_triples : Option < NonEmptyVec < IdentityTripleRecord < ' a > > > ,
454+ attest_key_triples : Option < NonEmptyVec < AttestKeyTripleRecord < ' a > > > ,
455+ dependency_triples : Option < NonEmptyVec < DomainDependencyTripleRecord < ' a > > > ,
456+ membership_triples : Option < NonEmptyVec < DomainMembershipTripleRecord < ' a > > > ,
457+ coswid_triples : Option < NonEmptyVec < CoswidTripleRecord < ' a > > > ,
458+ conditional_endorsement_series_triples :
459+ Option < NonEmptyVec < ConditionalEndorsementSeriesTripleRecord < ' a > > > ,
460+ conditional_endorsement_triples : Option < NonEmptyVec < ConditionalEndorsementTripleRecord < ' a > > > ,
461+ extension : Option < ExtensionMap < ' a > > ,
462+ }
463+
464+ impl < ' a > TriplesMapBuilder < ' a > {
465+ // Setter methods for each field
466+ pub fn reference_triples ( mut self , value : NonEmptyVec < ReferenceTripleRecord < ' a > > ) -> Self {
467+ self . reference_triples = Some ( value) ;
468+ self
469+ }
470+
471+ pub fn endorsed_triples ( mut self , value : NonEmptyVec < EndorsedTripleRecord < ' a > > ) -> Self {
472+ self . endorsed_triples = Some ( value) ;
473+ self
474+ }
475+
476+ pub fn identity_triples ( mut self , value : NonEmptyVec < IdentityTripleRecord < ' a > > ) -> Self {
477+ self . identity_triples = Some ( value) ;
478+ self
479+ }
480+
481+ pub fn attest_key_triples ( mut self , value : NonEmptyVec < AttestKeyTripleRecord < ' a > > ) -> Self {
482+ self . attest_key_triples = Some ( value) ;
483+ self
484+ }
485+
486+ pub fn dependency_triples (
487+ mut self ,
488+ value : NonEmptyVec < DomainDependencyTripleRecord < ' a > > ,
489+ ) -> Self {
490+ self . dependency_triples = Some ( value) ;
491+ self
492+ }
493+
494+ pub fn membership_triples (
495+ mut self ,
496+ value : NonEmptyVec < DomainMembershipTripleRecord < ' a > > ,
497+ ) -> Self {
498+ self . membership_triples = Some ( value) ;
499+ self
500+ }
501+
502+ pub fn coswid_triples ( mut self , value : NonEmptyVec < CoswidTripleRecord < ' a > > ) -> Self {
503+ self . coswid_triples = Some ( value) ;
504+ self
505+ }
506+
507+ pub fn conditional_endorsement_series_triples (
508+ mut self ,
509+ value : NonEmptyVec < ConditionalEndorsementSeriesTripleRecord < ' a > > ,
510+ ) -> Self {
511+ self . conditional_endorsement_series_triples = Some ( value) ;
512+ self
513+ }
514+
515+ pub fn conditional_endorsement_triples (
516+ mut self ,
517+ value : NonEmptyVec < ConditionalEndorsementTripleRecord < ' a > > ,
518+ ) -> Self {
519+ self . conditional_endorsement_triples = Some ( value) ;
520+ self
521+ }
522+
523+ pub fn extension ( mut self , value : ExtensionMap < ' a > ) -> Self {
524+ self . extension = Some ( value) ;
525+ self
526+ }
527+
528+ /// Builds the TriplesMap, returning an error if no fields are set
529+ pub fn build ( self ) -> Result < TriplesMap < ' a > > {
530+ if self . reference_triples . is_none ( )
531+ && self . endorsed_triples . is_none ( )
532+ && self . identity_triples . is_none ( )
533+ && self . attest_key_triples . is_none ( )
534+ && self . dependency_triples . is_none ( )
535+ && self . membership_triples . is_none ( )
536+ && self . coswid_triples . is_none ( )
537+ && self . conditional_endorsement_series_triples . is_none ( )
538+ && self . conditional_endorsement_triples . is_none ( )
539+ && self . extension . is_none ( )
540+ {
541+ return Err ( ComidError :: EmptyTriplesMap ) ?;
542+ }
543+
544+ Ok ( TriplesMap {
545+ reference_triples : self . reference_triples ,
546+ endorsed_triples : self . endorsed_triples ,
547+ identity_triples : self . identity_triples ,
548+ attest_key_triples : self . attest_key_triples ,
549+ dependency_triples : self . dependency_triples ,
550+ membership_triples : self . membership_triples ,
551+ coswid_triples : self . coswid_triples ,
552+ conditional_endorsement_series_triples : self . conditional_endorsement_series_triples ,
553+ conditional_endorsement_triples : self . conditional_endorsement_triples ,
554+ extension : self . extension ,
555+ } )
556+ }
557+ }
0 commit comments