@@ -137,7 +137,7 @@ impl<const TRANSFER: bool> Deref for ValidConsignment<TRANSFER> {
137137/// with `endpoints` and process up to the genesis.
138138#[ derive( Clone , Debug , Display ) ]
139139#[ display( AsciiArmor :: to_ascii_armored_string) ]
140- #[ derive( StrictType , StrictDumb , StrictEncode , StrictDecode ) ]
140+ #[ derive( StrictType , StrictDumb , StrictEncode , StrictDecode , PartialEq ) ]
141141#[ strict_type( lib = LIB_NAME_RGB_STD ) ]
142142#[ cfg_attr(
143143 feature = "serde" ,
@@ -377,7 +377,7 @@ impl<const TRANSFER: bool> StrictArmor for Consignment<TRANSFER> {
377377
378378 fn armor_id ( & self ) -> Self :: Id { self . commit_id ( ) }
379379 fn armor_headers ( & self ) -> Vec < ArmorHeader > {
380- vec ! [
380+ let mut headers = vec ! [
381381 ArmorHeader :: new( ASCII_ARMOR_VERSION , format!( "{:#}" , self . version) ) ,
382382 ArmorHeader :: new(
383383 ASCII_ARMOR_CONSIGNMENT_TYPE ,
@@ -389,11 +389,175 @@ impl<const TRANSFER: bool> StrictArmor for Consignment<TRANSFER> {
389389 ) ,
390390 ArmorHeader :: new( ASCII_ARMOR_CONTRACT , self . contract_id( ) . to_string( ) ) ,
391391 ArmorHeader :: new( ASCII_ARMOR_SCHEMA , self . schema. schema_id( ) . to_string( ) ) ,
392- ArmorHeader :: with(
392+ ] ;
393+ if !self . ifaces . is_empty ( ) {
394+ headers. push ( ArmorHeader :: with (
393395 ASCII_ARMOR_IFACE ,
394396 self . ifaces . keys ( ) . map ( |iface| iface. name . to_string ( ) ) ,
395- ) ,
396- ArmorHeader :: with( ASCII_ARMOR_TERMINAL , self . terminals. keys( ) . map( BundleId :: to_string) ) ,
397- ]
397+ ) ) ;
398+ }
399+ if !self . terminals . is_empty ( ) {
400+ headers. push ( ArmorHeader :: with (
401+ ASCII_ARMOR_TERMINAL ,
402+ self . terminals . keys ( ) . map ( BundleId :: to_string) ,
403+ ) ) ;
404+ }
405+ headers
406+ }
407+ }
408+
409+ impl < const TRANSFER : bool > FromStr for Consignment < TRANSFER > {
410+ type Err = armor:: StrictArmorError ;
411+ fn from_str ( s : & str ) -> Result < Self , Self :: Err > { Self :: from_ascii_armored_str ( s) }
412+ }
413+
414+ #[ cfg( test) ]
415+ mod test {
416+ use super :: * ;
417+
418+ #[ test]
419+ fn contract_str_round_trip ( ) {
420+ let contract = Contract :: from_str ( include_str ! ( "../../asset/armored_contract.default" ) )
421+ . expect ( "contract from str should work" ) ;
422+ assert_eq ! (
423+ contract. to_string( ) ,
424+ include_str!( "../../asset/armored_contract.default" ) ,
425+ "contract string round trip fails"
426+ ) ;
427+ }
428+
429+ #[ test]
430+ fn error_contract_strs ( ) {
431+ assert ! (
432+ Contract :: from_str(
433+ r#"-----BEGIN RGB CONSIGNMENT-----
434+ Id: rgb:csg:poAMvm9j-NdapxqA-MJ@5dwP-d@IIt2A-T@5OiXE-Tl54Yew#guide-campus-arctic
435+ Version: 2
436+ Type: contract
437+ Contract: rgb:qm7P@06T-uuBQT56-ovwOLzx-9Gka7Nb-84Nwo8g-blLb8kw
438+ Schema: rgb:sch:CyqM42yAdM1moWyNZPQedAYt73BM$k9z$dKLUXY1voA#cello-global-deluxe
439+ Check-SHA256: 181748dae0c83cbb44f6ccfdaddf6faca0bc4122a9f35fef47bab9aea023e4a1
440+
441+ 0ssI2000000000000000000000000000000000000000000000000000000D0CRI`I$>^aZh38Qb#nj!
442+ 0000000000000000000000d59ZDjxe00000000dDb8~4rVQz13d2MfXa{vGU00000000000000000000
443+ 0000000000000
444+
445+ -----END RGB CONSIGNMENT-----"#
446+ )
447+ . is_ok( )
448+ ) ;
449+
450+ // Wrong Id
451+ assert ! (
452+ Contract :: from_str(
453+ r#"-----BEGIN RGB CONSIGNMENT-----
454+ Id: rgb:csg:aaaaaaaa-aaaaaaa-aaaaaaa-aaaaaaa-aaaaaaa-aaaaaaa#guide-campus-arctic
455+ Version: 2
456+ Type: contract
457+ Contract: rgb:qm7P@06T-uuBQT56-ovwOLzx-9Gka7Nb-84Nwo8g-blLb8kw
458+ Schema: rgb:sch:CyqM42yAdM1moWyNZPQedAYt73BM$k9z$dKLUXY1voA#cello-global-deluxe
459+ Check-SHA256: 181748dae0c83cbb44f6ccfdaddf6faca0bc4122a9f35fef47bab9aea023e4a1
460+
461+ 0ssI2000000000000000000000000000000000000000000000000000000D0CRI`I$>^aZh38Qb#nj!
462+ 0000000000000000000000d59ZDjxe00000000dDb8~4rVQz13d2MfXa{vGU00000000000000000000
463+ 0000000000000
464+
465+ -----END RGB CONSIGNMENT-----"#
466+ )
467+ . is_err( )
468+ ) ;
469+
470+ // Wrong checksum
471+ assert ! (
472+ Contract :: from_str(
473+ r#"-----BEGIN RGB CONSIGNMENT-----
474+ Id: rgb:csg:poAMvm9j-NdapxqA-MJ@5dwP-d@IIt2A-T@5OiXE-Tl54Yew#guide-campus-arctic
475+ Version: 2
476+ Type: contract
477+ Contract: rgb:qm7P@06T-uuBQT56-ovwOLzx-9Gka7Nb-84Nwo8g-blLb8kw
478+ Schema: rgb:sch:CyqM42yAdM1moWyNZPQedAYt73BM$k9z$dKLUXY1voA#cello-global-deluxe
479+ Check-SHA256: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
480+
481+ 0ssI2000000000000000000000000000000000000000000000000000000D0CRI`I$>^aZh38Qb#nj!
482+ 0000000000000000000000d59ZDjxe00000000dDb8~4rVQz13d2MfXa{vGU00000000000000000000
483+ 0000000000000
484+
485+ -----END RGB CONSIGNMENT-----"#
486+ )
487+ . is_err( )
488+ ) ;
489+ }
490+
491+ #[ test]
492+ fn transfer_str_round_trip ( ) {
493+ let transfer = Transfer :: from_str ( include_str ! ( "../../asset/armored_transfer.default" ) )
494+ . expect ( "transfer from str should work" ) ;
495+ assert_eq ! (
496+ transfer. to_string( ) ,
497+ include_str!( "../../asset/armored_transfer.default" ) ,
498+ "transfer string round trip fails"
499+ ) ;
500+ }
501+
502+ #[ test]
503+ fn error_transfer_strs ( ) {
504+ assert ! (
505+ Transfer :: from_str(
506+ r#"-----BEGIN RGB CONSIGNMENT-----
507+ Id: rgb:csg:poAMvm9j-NdapxqA-MJ@5dwP-d@IIt2A-T@5OiXE-Tl54Yew#guide-campus-arctic
508+ Version: 2
509+ Type: contract
510+ Contract: rgb:qm7P@06T-uuBQT56-ovwOLzx-9Gka7Nb-84Nwo8g-blLb8kw
511+ Schema: rgb:sch:CyqM42yAdM1moWyNZPQedAYt73BM$k9z$dKLUXY1voA#cello-global-deluxe
512+ Check-SHA256: 181748dae0c83cbb44f6ccfdaddf6faca0bc4122a9f35fef47bab9aea023e4a1
513+
514+ 0ssI2000000000000000000000000000000000000000000000000000000D0CRI`I$>^aZh38Qb#nj!
515+ 0000000000000000000000d59ZDjxe00000000dDb8~4rVQz13d2MfXa{vGU00000000000000000000
516+ 0000000000000
517+
518+ -----END RGB CONSIGNMENT-----"#
519+ )
520+ . is_ok( )
521+ ) ;
522+
523+ // Wrong Id
524+ assert ! (
525+ Transfer :: from_str(
526+ r#"-----BEGIN RGB CONSIGNMENT-----
527+ Id: rgb:csg:aaaaaaaa-aaaaaaa-aaaaaaa-aaaaaaa-aaaaaaa-aaaaaaa#guide-campus-arctic
528+ Version: 2
529+ Type: contract
530+ Contract: rgb:qm7P@06T-uuBQT56-ovwOLzx-9Gka7Nb-84Nwo8g-blLb8kw
531+ Schema: rgb:sch:CyqM42yAdM1moWyNZPQedAYt73BM$k9z$dKLUXY1voA#cello-global-deluxe
532+ Check-SHA256: 181748dae0c83cbb44f6ccfdaddf6faca0bc4122a9f35fef47bab9aea023e4a1
533+
534+ 0ssI2000000000000000000000000000000000000000000000000000000D0CRI`I$>^aZh38Qb#nj!
535+ 0000000000000000000000d59ZDjxe00000000dDb8~4rVQz13d2MfXa{vGU00000000000000000000
536+ 0000000000000
537+
538+ -----END RGB CONSIGNMENT-----"#
539+ )
540+ . is_err( )
541+ ) ;
542+
543+ // Wrong checksum
544+ assert ! (
545+ Transfer :: from_str(
546+ r#"-----BEGIN RGB CONSIGNMENT-----
547+ Id: rgb:csg:poAMvm9j-NdapxqA-MJ@5dwP-d@IIt2A-T@5OiXE-Tl54Yew#guide-campus-arctic
548+ Version: 2
549+ Type: contract
550+ Contract: rgb:qm7P@06T-uuBQT56-ovwOLzx-9Gka7Nb-84Nwo8g-blLb8kw
551+ Schema: rgb:sch:CyqM42yAdM1moWyNZPQedAYt73BM$k9z$dKLUXY1voA#cello-global-deluxe
552+ Check-SHA256: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
553+
554+ 0ssI2000000000000000000000000000000000000000000000000000000D0CRI`I$>^aZh38Qb#nj!
555+ 0000000000000000000000d59ZDjxe00000000dDb8~4rVQz13d2MfXa{vGU00000000000000000000
556+ 0000000000000
557+
558+ -----END RGB CONSIGNMENT-----"#
559+ )
560+ . is_err( )
561+ ) ;
398562 }
399563}
0 commit comments