示例#1
0
func getFlag(field reflect.StructField) (ths flagSpec) {
	ftlen := len(field.Tag)
	if ftlen > 0 && string(field.Tag[ftlen-1]) == "!" {
		if ftlen > 1 && string(field.Tag[ftlen-2]) != "\\" {
			field.Tag = field.Tag[:ftlen-1]
			ths.imperitive = true
		} else if ftlen > 2 {
			field.Tag = reflect.StructTag(string(field.Tag[:len(field.Tag)-2]) + "!")
		} else {
			ths.imperitive = true
		}
	}
	parts := strings.Split(string(field.Tag), ";")
	switch useName := true; len(parts) {
	case 3:
		useName = false
		ths.names = strings.Split(parts[2], ",")
		fallthrough
	case 2:
		ths.deflt = parts[1]
		fallthrough
	case 1:
		ths.usage = parts[0]
		fallthrough
	case 0:
		ths.typ = field.Type
		if useName {
			ths.names = append(ths.names, strings.ToLower(field.Name))
		}
	default:
		panic("Too many fields!")
	}
	return
}
示例#2
0
文件: type.go 项目: fishedee/fishgo
func getFieldByNameInner(t reflect.Type, name string) (reflect.StructField, bool) {
	nameArray := Explode(name, ".")
	if len(nameArray) == 0 {
		return reflect.StructField{}, false
	}
	var isExist bool
	var resultStruct reflect.StructField
	resultIndex := []int{}
	for _, singleName := range nameArray {
		resultStruct, isExist = t.FieldByName(singleName)
		if !isExist {
			return reflect.StructField{}, false
		}
		resultIndex = append(resultIndex, resultStruct.Index...)
		t = resultStruct.Type
	}
	resultStruct.Index = resultIndex
	return resultStruct, true
}
//Returns the field or fields needed to fully write the struct's field
func compileField(sf reflect.StructField, t reflect.Type, ind []int) []field {
	temp := sf.Index[0]
	sf.Index = make([]int, len(ind)+1)
	copy(sf.Index, ind)
	sf.Index[len(ind)] = temp
	f := field{sField: sf}

	cond := sf.Tag.Get("if")
	if len(cond) > 0 {
		var args [3]string
		pos := strings.Index(cond, ",")
		args[0] = cond[:pos]
		cond = cond[pos+1:]
		pos = strings.Index(cond, ",")
		args[1] = cond[:pos]
		args[2] = cond[pos+1:]
		checkField, ok := t.FieldByName(args[0])
		if !ok {
			panic(fmt.Errorf("Unknown field: %s", args[0]))
		}
		in := make([]int, len(checkField.Index)+len(ind))
		copy(in, ind)
		copy(in[len(ind):], checkField.Index)

		valsStr := strings.Split(args[2], "|")
		vals := make([]int64, len(valsStr))
		for i := range vals {
			vals[i], _ = strconv.ParseInt(valsStr[i], 10, 64)
		}

		switch args[1] {
		case "!=":
			f.condition = func(root reflect.Value) bool {
				val := root.FieldByIndex(in).Int()
				for _, v := range vals {
					if v != val {
						return true
					}
				}
				return false
			}
		case "==":
			f.condition = func(root reflect.Value) bool {
				val := root.FieldByIndex(ind).Int()
				for _, v := range vals {
					if v == val {
						return true
					}
				}
				return false
			}
		}
	} else {
		f.condition = condAlways
	}

	switch sf.Type.Kind() {
	case reflect.Bool:
		f.write = encodeBool
		f.read = decodeBool
	case reflect.Int8:
		f.write = encodeInt8
		f.read = decodeInt8
	case reflect.Uint8:
		f.write = encodeUint8
		f.read = decodeUint8
	case reflect.Int16:
		f.write = encodeInt16
		f.read = decodeInt16
	case reflect.Uint16:
		f.write = encodeUint16
		f.read = decodeUint16
	case reflect.Int32:
		f.write = encodeInt32
		f.read = decodeInt32
	case reflect.Int64:
		f.write = encodeInt64
		f.read = decodeInt64
	case reflect.Float32:
		f.write = encodeFloat32
		f.read = decodeFloat32
	case reflect.Float64:
		f.write = encodeFloat64
		f.read = decodeFloat64
	case reflect.String:
		f.write = encodeString
		f.read = decodeString
	case reflect.Slice:
		e := sf.Type.Elem()
		f.write, f.read = getSliceCoders(e, sf)
	case reflect.Map:
		if sf.Tag.Get("metadata") == "true" {
			f.write = encodeMetadata
			f.read = decodeMetadata
		} else {
			panic("Maps NYI")
		}
	case reflect.Struct:
		return compileStruct(sf.Type, sf.Index)
	case reflect.Int: //VarInt
		f.write = encodeVarInt
		f.read = decodeVarInt
	default:
		panic(fmt.Errorf("Unhandled type %s for %s", sf.Type.Kind().String(), sf.Name))
	}
	if f.write == nil {
		panic(fmt.Errorf("Missing write for type %s", sf.Type.Kind()))
	}
	if f.read == nil {
		panic(fmt.Errorf("Missing read for type %s", sf.Type.Kind()))
	}
	return []field{f}
}