github.com/mavryk-network/mvgo@v1.19.9/contract/bind/or.go (about) 1 package bind 2 3 import ( 4 "github.com/mavryk-network/mvgo/micheline" 5 6 "github.com/pkg/errors" 7 ) 8 9 // Or is a type that can be either L or R. 10 // 11 // It maps to michelson's `or` type. 12 type Or[L, R any] struct { 13 l L 14 r R 15 isRight bool 16 } 17 18 // Left returns a new Or[L, R] filled with the left value. 19 func Left[L, R any](l L) Or[L, R] { 20 return Or[L, R]{l: l} 21 } 22 23 // Right returns a new Or[L, R] filled with the right value. 24 func Right[L, R any](r R) Or[L, R] { 25 return Or[L, R]{r: r, isRight: true} 26 } 27 28 func (o Or[L, R]) IsLeft() bool { 29 return !o.isRight 30 } 31 32 func (o Or[L, R]) IsRight() bool { 33 return o.isRight 34 } 35 36 // Left returns the left value and true, if the Or is Left. 37 func (o Or[L, R]) Left() (L, bool) { 38 return o.l, !o.isRight 39 } 40 41 // Right returns the right value and true, if the Or is Right. 42 func (o Or[L, R]) Right() (R, bool) { 43 return o.r, o.isRight 44 } 45 46 func (o Or[L, R]) MarshalPrim(optimized bool) (micheline.Prim, error) { 47 if o.isRight { 48 inner, err := MarshalPrim(o.r, optimized) 49 if err != nil { 50 return micheline.Prim{}, err 51 } 52 return micheline.NewCode(micheline.D_RIGHT, inner), nil 53 } else { 54 inner, err := MarshalPrim(o.l, optimized) 55 if err != nil { 56 return micheline.Prim{}, err 57 } 58 return micheline.NewCode(micheline.D_LEFT, inner), nil 59 } 60 } 61 62 func (o *Or[L, R]) UnmarshalPrim(prim micheline.Prim) error { 63 switch prim.OpCode { 64 case micheline.D_LEFT: 65 if len(prim.Args) != 1 { 66 return errors.New("prim Left should have 1 arg") 67 } 68 o.isRight = false 69 return UnmarshalPrim(prim.Args[0], &o.l) 70 case micheline.D_RIGHT: 71 if len(prim.Args) != 1 { 72 return errors.New("prim Right should have 1 arg") 73 } 74 o.isRight = true 75 return UnmarshalPrim(prim.Args[0], &o.r) 76 default: 77 return errors.Errorf("unexpected opCode when unmarshalling Or: %s", prim.OpCode) 78 } 79 } 80 81 func (o Or[L, R]) keyHash() hashType { 82 if l, ok := o.Left(); ok { 83 valHash := hashFunc(zero[L]())(l) 84 return hashBytes(append([]byte{0}, valHash[:]...)) 85 } else { 86 r, _ := o.Right() 87 valHash := hashFunc(zero[R]())(r) 88 return hashBytes(append([]byte{1}, valHash[:]...)) 89 } 90 }