package bun
import "reflect"
func indirect (v reflect .Value ) reflect .Value {
switch v .Kind () {
case reflect .Interface :
return indirect (v .Elem ())
case reflect .Ptr :
return v .Elem ()
default :
return v
}
}
func walk (v reflect .Value , index []int , fn func (reflect .Value )) {
v = reflect .Indirect (v )
switch v .Kind () {
case reflect .Slice :
sliceLen := v .Len ()
for i := 0 ; i < sliceLen ; i ++ {
visitField (v .Index (i ), index , fn )
}
default :
visitField (v , index , fn )
}
}
func visitField (v reflect .Value , index []int , fn func (reflect .Value )) {
v = reflect .Indirect (v )
if len (index ) > 0 {
v = v .Field (index [0 ])
if v .Kind () == reflect .Ptr && v .IsNil () {
return
}
walk (v , index [1 :], fn )
} else {
fn (v )
}
}
func typeByIndex (t reflect .Type , index []int ) reflect .Type {
for _ , x := range index {
switch t .Kind () {
case reflect .Ptr :
t = t .Elem ()
case reflect .Slice :
t = indirectType (t .Elem ())
}
t = t .Field (x ).Type
}
return indirectType (t )
}
func indirectType (t reflect .Type ) reflect .Type {
if t .Kind () == reflect .Ptr {
t = t .Elem ()
}
return t
}
func sliceElemType (v reflect .Value ) reflect .Type {
elemType := v .Type ().Elem ()
if elemType .Kind () == reflect .Interface && v .Len () > 0 {
return indirect (v .Index (0 ).Elem ()).Type ()
}
return indirectType (elemType )
}
func makeSliceNextElemFunc (v reflect .Value ) func () reflect .Value {
if v .Kind () == reflect .Array {
var pos int
return func () reflect .Value {
v := v .Index (pos )
pos ++
return v
}
}
sliceType := v .Type ()
elemType := sliceType .Elem ()
if elemType .Kind () == reflect .Ptr {
elemType = elemType .Elem ()
return func () reflect .Value {
if v .Len () < v .Cap () {
v .Set (v .Slice (0 , v .Len ()+1 ))
elem := v .Index (v .Len () - 1 )
if elem .IsNil () {
elem .Set (reflect .New (elemType ))
}
return elem .Elem ()
}
elem := reflect .New (elemType )
v .Set (reflect .Append (v , elem ))
return elem .Elem ()
}
}
zero := reflect .Zero (elemType )
return func () reflect .Value {
l := v .Len ()
c := v .Cap ()
if l < c {
v .Set (v .Slice (0 , l +1 ))
return v .Index (l )
}
v .Set (reflect .Append (v , zero ))
return v .Index (l )
}
}
The pages are generated with Golds v0.3.6 . (GOOS=darwin GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds .