github.com/consensys/gnark@v0.11.0/io/roundtrip.go (about) 1 package io 2 3 import ( 4 "bytes" 5 "errors" 6 "io" 7 "reflect" 8 ) 9 10 // RoundTripCheck is a helper to check that a serialization round trip is correct. 11 // It writes the object to a buffer, then reads it back and checks that the reconstructed object is equal to the original. 12 // It supports both io.ReaderFrom and UnsafeReaderFrom interfaces (to object) 13 // It also supports both io.WriterTo and WriterRawTo interfaces (from object) 14 func RoundTripCheck(from any, to func() any) error { 15 var buf bytes.Buffer 16 17 reconstruct := func(written int64) error { 18 // if builder implements io.ReaderFrom 19 if r, ok := to().(io.ReaderFrom); ok { 20 read, err := r.ReadFrom(bytes.NewReader(buf.Bytes())) 21 if err != nil { 22 return err 23 } 24 if !reflect.DeepEqual(from, r) { 25 return errors.New("reconstructed object don't match original (ReadFrom)") 26 } 27 if written != read { 28 return errors.New("bytes written / read don't match") 29 } 30 } 31 32 // if builder implements gnarkio.UnsafeReaderFrom 33 if r, ok := to().(UnsafeReaderFrom); ok { 34 read, err := r.UnsafeReadFrom(bytes.NewReader(buf.Bytes())) 35 if err != nil { 36 return err 37 } 38 if !reflect.DeepEqual(from, r) { 39 return errors.New("reconstructed object don't match original (UnsafeReadFrom)") 40 } 41 if written != read { 42 return errors.New("bytes written / read don't match") 43 } 44 } 45 return nil 46 } 47 48 // if from implements io.WriterTo 49 if w, ok := from.(io.WriterTo); ok { 50 written, err := w.WriteTo(&buf) 51 if err != nil { 52 return err 53 } 54 55 if err := reconstruct(written); err != nil { 56 return err 57 } 58 } 59 60 buf.Reset() 61 62 // if from implements gnarkio.WriterRawTo 63 if w, ok := from.(WriterRawTo); ok { 64 written, err := w.WriteRawTo(&buf) 65 if err != nil { 66 return err 67 } 68 69 if err := reconstruct(written); err != nil { 70 return err 71 } 72 } 73 74 return nil 75 } 76 77 func DumpRoundTripCheck(from any, to func() any) error { 78 var buf bytes.Buffer 79 80 if err := from.(BinaryDumper).WriteDump(&buf); err != nil { 81 return err 82 } 83 84 r := to().(BinaryDumper) 85 if err := r.ReadDump(bytes.NewReader(buf.Bytes())); err != nil { 86 return err 87 } 88 if !reflect.DeepEqual(from, r) { 89 return errors.New("reconstructed object don't match original (ReadDump)") 90 } 91 return nil 92 }