github.com/machinefi/w3bstream@v1.6.5-rc9.0.20240426031326-b8c7c4876e72/pkg/depends/kit/sqlx/scanner/scan_iter.go (about) 1 package scanner 2 3 import ( 4 "reflect" 5 6 "github.com/machinefi/w3bstream/pkg/depends/x/reflectx" 7 ) 8 9 type ScanIterator interface { 10 // New a ptr value for scan 11 New() interface{} 12 // Next for receive scanned value 13 Next(v interface{}) error 14 } 15 16 func ScanIteratorFor(v interface{}) (ScanIterator, error) { 17 switch x := v.(type) { 18 case ScanIterator: 19 return x, nil 20 default: 21 t := reflectx.DeRef(reflect.TypeOf(v)) 22 if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 { 23 return &SliceScanIterator{ 24 t.Elem(), reflectx.Indirect(reflect.ValueOf(v)), 25 }, nil 26 } 27 return &SingleScanIterator{v: v}, nil 28 } 29 } 30 31 type SliceScanIterator struct { 32 t reflect.Type 33 v reflect.Value 34 } 35 36 func (s *SliceScanIterator) New() interface{} { 37 return reflectx.New(s.t).Addr().Interface() 38 } 39 40 func (s *SliceScanIterator) Next(v interface{}) error { 41 s.v.Set(reflect.Append(s.v, reflect.ValueOf(v).Elem())) 42 return nil 43 } 44 45 type SingleScanIterator struct { 46 v interface{} 47 hasResults bool 48 } 49 50 func (s *SingleScanIterator) New() interface{} { 51 return s.v 52 } 53 54 func (s *SingleScanIterator) Next(v interface{}) error { 55 s.hasResults = true 56 return nil 57 } 58 59 func (s *SingleScanIterator) HasRecord() bool { return s.hasResults }