Allow properties to have unsettable int and uint fields
Allow properties structs to contain exported int and uint fields, but only if they are tagged with blueprint:"mutated". These fields will be copied by CopyProperties in order to propagate through cloning during mutations, but can only be set by Mutators and not by Blueprint files. Change-Id: Ic462385799c77667e392f4928d02d424c8f8d900
This commit is contained in:
parent
bbfa51a229
commit
11a114f454
2 changed files with 30 additions and 3 deletions
|
@ -40,7 +40,7 @@ func CopyProperties(dstValue, srcValue reflect.Value) {
|
|||
dstFieldValue := dstValue.Field(i)
|
||||
|
||||
switch srcFieldValue.Kind() {
|
||||
case reflect.Bool, reflect.String:
|
||||
case reflect.Bool, reflect.String, reflect.Int, reflect.Uint:
|
||||
dstFieldValue.Set(srcFieldValue)
|
||||
case reflect.Struct:
|
||||
CopyProperties(dstFieldValue, srcFieldValue)
|
||||
|
@ -104,7 +104,7 @@ func ZeroProperties(structValue reflect.Value) {
|
|||
fieldValue := structValue.Field(i)
|
||||
|
||||
switch fieldValue.Kind() {
|
||||
case reflect.Bool, reflect.String, reflect.Struct, reflect.Slice:
|
||||
case reflect.Bool, reflect.String, reflect.Struct, reflect.Slice, reflect.Int, reflect.Uint:
|
||||
fieldValue.Set(reflect.Zero(fieldValue.Type()))
|
||||
case reflect.Ptr, reflect.Interface:
|
||||
if !fieldValue.IsNil() {
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"blueprint/proptools"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type packedProperty struct {
|
||||
|
@ -154,6 +155,11 @@ func unpackStructValue(namePrefix string, structValue reflect.Value,
|
|||
panic(fmt.Errorf("field %s contains a non-struct pointer",
|
||||
field.Name))
|
||||
}
|
||||
case reflect.Int, reflect.Uint:
|
||||
if !hasTag(field, "blueprint", "mutated") {
|
||||
panic(fmt.Errorf(`int field %s must be tagged blueprint:"mutated"`, field.Name))
|
||||
}
|
||||
|
||||
default:
|
||||
panic(fmt.Errorf("unsupported kind for field %s: %s",
|
||||
field.Name, kind))
|
||||
|
@ -167,9 +173,19 @@ func unpackStructValue(namePrefix string, structValue reflect.Value,
|
|||
continue
|
||||
}
|
||||
|
||||
var newErrs []error
|
||||
|
||||
if hasTag(field, "blueprint", "mutated") {
|
||||
errs = append(errs,
|
||||
fmt.Errorf("mutated field %s cannot be set in a Blueprint file", propertyName))
|
||||
if len(errs) >= maxErrors {
|
||||
return errs
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
packedProperty.unpacked = true
|
||||
|
||||
var newErrs []error
|
||||
switch kind := fieldValue.Kind(); kind {
|
||||
case reflect.Bool:
|
||||
newErrs = unpackBool(fieldValue, packedProperty.property)
|
||||
|
@ -261,3 +277,14 @@ func unpackStruct(namePrefix string, structValue reflect.Value,
|
|||
|
||||
return unpackStructValue(namePrefix, structValue, propertyMap)
|
||||
}
|
||||
|
||||
func hasTag(field reflect.StructField, name, value string) bool {
|
||||
tag := field.Tag.Get(name)
|
||||
for _, entry := range strings.Split(tag, ",") {
|
||||
if entry == value {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue