package annotation import ( "reflect" "strings" cur "git.loafle.net/commons_go/util/reflect" ) type AnnotationFieldMeta struct { fieldName string options anotationMetaOptions } type anotationMetaOptions string func (o anotationMetaOptions) Contains(optionName string) bool { if len(o) == 0 { return false } s := string(o) for s != "" { var next string i := strings.Index(s, AnnotationAttributeSpliter) if i >= 0 { s, next = s[:i], s[i+1:] } if s == optionName { return true } s = next } return false } func getMetaFields(t reflect.Type) map[string]*AnnotationFieldMeta { fields := make(map[string]*AnnotationFieldMeta, 0) rt, _, _ := cur.GetTypeInfo(t) if reflect.Struct != rt.Kind() { return fields } for i := 0; i < rt.NumField(); i++ { f := rt.Field(i) if f.Anonymous { pFields := getMetaFields(f.Type) for k, v := range pFields { fields[k] = v } } else { name, metaOptions := parseAnnotationMeta(f.Tag) if "" == name { continue } fields[name] = &AnnotationFieldMeta{ fieldName: f.Name, options: metaOptions, } } } return fields } func parseAnnotationMeta(tag reflect.StructTag) (string, anotationMetaOptions) { s := strings.Trim(tag.Get(AnnotationMetaTag), " ") if "" == s { return "", "" } if idx := strings.Index(s, AnnotationAttributeSpliter); idx != -1 { return s[:idx], anotationMetaOptions(s[idx+1:]) } return s, anotationMetaOptions("") } func setMetaAttributes(def *AnnotationDefinition, rv reflect.Value, attributes map[string]string) { for k, v := range attributes { meta := def.fields[k] f := rv.FieldByName(meta.fieldName) f.Set(reflect.ValueOf(v)) } }