@@ -543,6 +543,151 @@ func TestMarshal_Chan(t *testing.T) {
543543 })
544544}
545545
546+ func TestMarshal_Func (t * testing.T ) {
547+ expected := []byte {
548+ 0x18 , 0x53 , 0x80 , 0x67 , 0x01 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
549+ 0x1F , 0x43 , 0xB6 , 0x75 , 0x01 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
550+ 0xE7 , 0x81 , 0x01 ,
551+ }
552+ type Cluster struct {
553+ Timecode uint64 `ebml:"Timecode"`
554+ }
555+
556+ t .Run ("FuncStruct" , func (t * testing.T ) {
557+ input := & struct {
558+ Segment struct {
559+ Cluster func () Cluster `ebml:"Cluster,size=unknown"`
560+ } `ebml:"Segment,size=unknown"`
561+ }{}
562+ input .Segment .Cluster = func () Cluster {
563+ return Cluster {Timecode : 0x01 }
564+ }
565+
566+ var b bytes.Buffer
567+ if err := Marshal (input , & b ); err != nil {
568+ t .Fatalf ("Unexpected error: '%v'" , err )
569+ }
570+ if ! bytes .Equal (expected , b .Bytes ()) {
571+ t .Errorf ("Marshaled binary doesn't match:\n expected: %v,\n got: %v" , expected , b .Bytes ())
572+ }
573+ })
574+ t .Run ("FuncStructPtr" , func (t * testing.T ) {
575+ input := & struct {
576+ Segment struct {
577+ Cluster func () * Cluster `ebml:"Cluster,size=unknown"`
578+ } `ebml:"Segment,size=unknown"`
579+ }{}
580+
581+ t .Run ("Valid" , func (t * testing.T ) {
582+ input .Segment .Cluster = func () * Cluster {
583+ return & Cluster {Timecode : 0x01 }
584+ }
585+
586+ var b bytes.Buffer
587+ if err := Marshal (input , & b ); err != nil {
588+ t .Fatalf ("Unexpected error: '%v'" , err )
589+ }
590+ if ! bytes .Equal (expected , b .Bytes ()) {
591+ t .Errorf ("Marshaled binary doesn't match:\n expected: %v,\n got: %v" , expected , b .Bytes ())
592+ }
593+ })
594+ t .Run ("Nil" , func (t * testing.T ) {
595+ input .Segment .Cluster = func () * Cluster {
596+ return nil
597+ }
598+
599+ if err := Marshal (input , & bytes.Buffer {}); ! errs .Is (err , ErrIncompatibleType ) {
600+ t .Fatalf ("Expected error: '%v', got: '%v'" , ErrIncompatibleType , err )
601+ }
602+ })
603+ })
604+ t .Run ("FuncStructSlice" , func (t * testing.T ) {
605+ input := & struct {
606+ Segment struct {
607+ Cluster func () []Cluster `ebml:"Cluster,size=unknown"`
608+ } `ebml:"Segment,size=unknown"`
609+ }{}
610+ input .Segment .Cluster = func () []Cluster {
611+ return []Cluster {
612+ {Timecode : 0x01 },
613+ {Timecode : 0x02 },
614+ }
615+ }
616+
617+ var b bytes.Buffer
618+ if err := Marshal (input , & b ); err != nil {
619+ t .Fatalf ("Unexpected error: '%v'" , err )
620+ }
621+ expected := []byte {
622+ 0x18 , 0x53 , 0x80 , 0x67 , 0x01 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
623+ 0x1F , 0x43 , 0xB6 , 0x75 , 0x01 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
624+ 0xE7 , 0x81 , 0x01 ,
625+ 0x1F , 0x43 , 0xB6 , 0x75 , 0x01 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
626+ 0xE7 , 0x81 , 0x02 ,
627+ }
628+ if ! bytes .Equal (expected , b .Bytes ()) {
629+ t .Errorf ("Marshaled binary doesn't match:\n expected: %v,\n got: %v" , expected , b .Bytes ())
630+ }
631+ })
632+ t .Run ("FuncWithError" , func (t * testing.T ) {
633+ input := & struct {
634+ Segment struct {
635+ Cluster func () (Cluster , error ) `ebml:"Cluster,size=unknown"`
636+ } `ebml:"Segment,size=unknown"`
637+ }{}
638+
639+ t .Run ("Valid" , func (t * testing.T ) {
640+ input .Segment .Cluster = func () (Cluster , error ) {
641+ return Cluster {Timecode : 0x01 }, nil
642+ }
643+
644+ var b bytes.Buffer
645+ if err := Marshal (input , & b ); err != nil {
646+ t .Fatalf ("Unexpected error: '%v'" , err )
647+ }
648+ if ! bytes .Equal (expected , b .Bytes ()) {
649+ t .Errorf ("Marshaled binary doesn't match:\n expected: %v,\n got: %v" , expected , b .Bytes ())
650+ }
651+ })
652+ t .Run ("Error" , func (t * testing.T ) {
653+ expectedErr := errors .New ("an error" )
654+ input .Segment .Cluster = func () (Cluster , error ) {
655+ return Cluster {Timecode : 0x01 }, expectedErr
656+ }
657+
658+ if err := Marshal (input , & bytes.Buffer {}); ! errs .Is (err , expectedErr ) {
659+ t .Fatalf ("Expected error: '%v', got: '%v'" , expectedErr , err )
660+ }
661+ })
662+ t .Run ("NonErrorType" , func (t * testing.T ) {
663+ input := & struct {
664+ Segment struct {
665+ Cluster func () (* Cluster , int ) `ebml:"Cluster,size=unknown"`
666+ } `ebml:"Segment,size=unknown"`
667+ }{}
668+ input .Segment .Cluster = func () (* Cluster , int ) {
669+ return nil , 1
670+ }
671+
672+ if err := Marshal (input , & bytes.Buffer {}); ! errs .Is (err , ErrIncompatibleType ) {
673+ t .Fatalf ("Expected error: '%v', got: '%v'" , ErrIncompatibleType , err )
674+ }
675+ })
676+ })
677+ t .Run ("InvalidFunc" , func (t * testing.T ) {
678+ input := & struct {
679+ Segment struct {
680+ Cluster func () `ebml:"Cluster,size=unknown"`
681+ } `ebml:"Segment,size=unknown"`
682+ }{}
683+ input .Segment .Cluster = func () {}
684+
685+ if err := Marshal (input , & bytes.Buffer {}); ! errs .Is (err , ErrIncompatibleType ) {
686+ t .Fatalf ("Expected error: '%v', got: '%v'" , ErrIncompatibleType , err )
687+ }
688+ })
689+ }
690+
546691func BenchmarkMarshal (b * testing.B ) {
547692 type EBMLHeader struct {
548693 DocType string `ebml:"EBMLDocType"`
0 commit comments