github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/pkg/cache/optional.go (about) 1 package cache 2 3 import "io" 4 5 // Optional is used to read/write values that can be missing. Most of the case, it will be pointers 6 // to articulated objects. Optional.MarshalCache first write a boolean indicating if the value 7 // is present or not. If it is not present, nothing is written next. However, if it is present 8 // the value will be written using the standard path through WriteValue. 9 // 10 // When reading a missing value, we get a correct pointer zero value of nil instead of a pointer to 11 // initialized zero value from new(Type). new(Type) != nil. 12 type Optional[T any] struct { 13 Value *T 14 ptr *T 15 } 16 17 func (o *Optional[T]) MarshalCache(writer io.Writer) (err error) { 18 present := o.Value != nil 19 if err = write(writer, present); err != nil { 20 return 21 } 22 if !present { 23 return nil 24 } 25 26 return WriteValue(writer, o.Value) 27 } 28 29 func (o *Optional[T]) UnmarshalCache(version uint64, reader io.Reader) (err error) { 30 var present bool 31 if err = read(reader, &present); err != nil { 32 return 33 } 34 if !present { 35 return 36 } 37 38 var value T 39 if err = ReadValue(reader, &value, version); err != nil { 40 return err 41 } 42 o.ptr = &value 43 return 44 } 45 46 // Get returns pointer to the value that was unmarshaled. We cannot simply set o.Value to point to 47 // the value read, because nil pointers cannot be dereferenced. 48 func (o *Optional[T]) Get() *T { 49 return o.ptr 50 }