github.com/fozzysec/SiaPrime@v0.0.0-20190612043147-66c8e8d11fe3/build/var.go (about) 1 package build 2 3 import "reflect" 4 5 // A Var represents a variable whose value depends on which Release is being 6 // compiled. None of the fields may be nil, and all fields must have the same 7 // type. 8 type Var struct { 9 Standard interface{} 10 Dev interface{} 11 Testing interface{} 12 // prevent unkeyed literals 13 _ struct{} 14 } 15 16 // Select returns the field of v that corresponds to the current Release. 17 // 18 // Since the caller typically makes a type assertion on the result, it is 19 // important to point out that type assertions are stricter than conversions. 20 // Specifically, you cannot write: 21 // 22 // type myint int 23 // Select(Var{0, 0, 0}).(myint) 24 // 25 // Because 0 will be interpreted as an int, which is not assignable to myint. 26 // Instead, you must explicitly cast each field in the Var, or cast the return 27 // value of Select after the type assertion. The former is preferred. 28 func Select(v Var) interface{} { 29 if v.Standard == nil || v.Dev == nil || v.Testing == nil { 30 panic("nil value in build variable") 31 } 32 st, dt, tt := reflect.TypeOf(v.Standard), reflect.TypeOf(v.Dev), reflect.TypeOf(v.Testing) 33 if !dt.AssignableTo(st) || !tt.AssignableTo(st) { 34 // NOTE: we use AssignableTo instead of the more lenient ConvertibleTo 35 // because type assertions require the former. 36 panic("build variables must have a single type") 37 } 38 switch Release { 39 case "standard": 40 return v.Standard 41 case "dev": 42 return v.Dev 43 case "testing": 44 return v.Testing 45 default: 46 panic("unrecognized Release: " + Release) 47 } 48 }