// ------------------------------------------------------------------------ // Project atila // Active Thing (activething.com) git.activething.com/go // // File name reflect_struct_field.go // Created by DEV // Modified 26/01/2024 // // Copyright 2024 activething.com // ------------------------------------------------------------------------ // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ------------------------------------------------------------------------ package reflects import ( "activething.com/go/gogo/core/opts" "activething.com/go/gogo/core/slices" "reflect" "strings" "unicode" ) type ( RField struct { RType reflect.Type RField reflect.StructField Name string SName string // scaped name HName string // html name BName []byte // name bytes Index []int Tags map[string]slices.String Flags uint16 EqualFoldFn func(s, t []byte) bool } ) func NewRField (rfield reflect.StructField, options ...opts.OptionFnc[RField]) *RField { rf := &RField{ RField: rfield, Tags : make(map[string]slices.String), } rf.parseTag("json",nil) return opts.Apply(rf,options...) } func (f *RField) parseTag (tagKey string, onOptionFn func(*RField,int,string)) { if _,h := f.Tags[tagKey]; !h { t := f.RField.Tag.Get(tagKey) if len(t) > 0 { l := strings.Split(t,",") f.Tags[tagKey]= l if onOptionFn != nil { for i,o := range l { onOptionFn(f,i,o) } } } } } func parseTag (field reflect.StructField, tagKey string, onOptionFn func(int,string)) (slices.String,bool) { t := field.Tag.Get(tagKey) if len(t) > 0 { l := strings.Split(t,",") if onOptionFn != nil { for i,o := range l { onOptionFn(i,o) } } return l,true } return nil,true } func isValidTag(s string) bool { if s == "" { return false } for _, c := range s { switch { case strings.ContainsRune("!#$%&()*+-./:;<=>?@[]^_{|}~ ", c): case !unicode.IsLetter(c) && !unicode.IsDigit(c): return false } } return true }