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  }