go-ml.dev/pkg/base@v0.0.0-20200610162856-60c38abac71b/tables/csv/resolver.go (about) 1 package csv 2 3 import ( 4 "fmt" 5 "go-ml.dev/pkg/base/fu" 6 "go-ml.dev/pkg/base/tables" 7 "math" 8 "reflect" 9 "strconv" 10 "time" 11 ) 12 13 type resolver func() mapper 14 15 func (r resolver) As(n string) resolver { 16 return func() mapper { 17 m := r() 18 m.TableCol = n 19 return m 20 } 21 } 22 23 func Column(v string) resolver { 24 return func() mapper { 25 return Mapper(v, v, nil, nil, nil) 26 } 27 } 28 29 func (r resolver) Group(v string) resolver { 30 return func() mapper { 31 g := r() 32 z := tables.Xtensor{g.valueType} 33 x := g 34 x.TableCol = v 35 x.group = true 36 x.valueType = z.Type() 37 x.convert = func(value string, field *reflect.Value, index, width int) (_ bool, err error) { 38 err = z.ConvertElm(value, field, index, width) 39 return 40 } 41 return x 42 } 43 } 44 45 func Tensor32f(v string) resolver { 46 return func() mapper { 47 x := tables.Xtensor{fu.Float32} 48 return Mapper(v, v, x.Type(), x.Convert, x.Format) 49 } 50 } 51 52 func Tensor64f(v string) resolver { 53 return func() mapper { 54 x := tables.Xtensor{fu.Float64} 55 return Mapper(v, v, x.Type(), x.Convert, x.Format) 56 } 57 } 58 59 func Tensor8u(v string) resolver { 60 return func() mapper { 61 x := tables.Xtensor{fu.Byte} 62 return Mapper(v, v, x.Type(), x.Convert, x.Format) 63 } 64 } 65 66 func Tensor8f(v string) resolver { 67 return func() mapper { 68 x := tables.Xtensor{fu.Fixed8Type} 69 return Mapper(v, v, x.Type(), x.Convert, x.Format) 70 } 71 } 72 73 func Meta(x tables.Meta, v string) resolver { 74 return func() mapper { 75 return Mapper(v, v, x.Type(), x.Convert, x.Format) 76 } 77 } 78 79 func String(v string) resolver { 80 return func() mapper { 81 return Mapper(v, v, fu.String, nil, nil) 82 } 83 } 84 85 func Int(v string) resolver { 86 return func() mapper { 87 return Mapper(v, v, fu.Int, converti, nil) 88 } 89 } 90 91 func converti(s string, value *reflect.Value, _, _ int) (na bool, err error) { 92 if s == "" { 93 *value = fu.IntZero 94 return true, nil 95 } 96 v, err := strconv.ParseInt(s, 10, 64) 97 *value = reflect.ValueOf(int(v)) 98 return 99 } 100 101 func Fixed8(v string) resolver { 102 return func() mapper { 103 return Mapper(v, v, fu.Fixed8Type, convert8f, nil) 104 } 105 } 106 107 func convert8f(s string, value *reflect.Value, _, _ int) (na bool, err error) { 108 if s == "" { 109 *value = fu.Fixed8Zero 110 return true, nil 111 } 112 f, err := fu.Fast8f(s) 113 *value = reflect.ValueOf(f) 114 return 115 } 116 117 func Float32(v string) resolver { 118 return func() mapper { 119 return Mapper(v, v, fu.Float32, convert32f, nil) 120 } 121 } 122 123 func convert32f(s string, value *reflect.Value, _, _ int) (na bool, err error) { 124 if s == "" { 125 *value = fu.Float32Zero 126 return true, nil 127 } 128 f, err := fu.Fast32f(s) 129 *value = reflect.ValueOf(f) 130 return 131 } 132 133 func Float64(v string) resolver { 134 return func() mapper { 135 return Mapper(v, v, fu.Float64, convert64f, nil) 136 } 137 } 138 139 func convert64f(s string, value *reflect.Value, _, _ int) (na bool, err error) { 140 if s == "" { 141 *value = fu.Float64Zero 142 return true, nil 143 } 144 v, err := strconv.ParseFloat(s, 32) 145 *value = reflect.ValueOf(v) 146 return 147 } 148 149 func Time(v string, layout ...string) resolver { 150 l := time.RFC3339 151 if len(layout) > 0 { 152 l = layout[0] 153 } 154 return func() mapper { 155 return Mapper(v, v, fu.Ts, 156 func(s string, value *reflect.Value, _, _ int) (bool, error) { 157 return convertts(s, l, value) 158 }, nil) 159 } 160 } 161 162 func convertts(s string, layout string, value *reflect.Value) (na bool, err error) { 163 if s == "" { 164 *value = fu.TsZero 165 return true, nil 166 } 167 v, err := strconv.ParseFloat(s, 32) 168 *value = reflect.ValueOf(v) 169 return 170 } 171 172 func (r resolver) Round(n ...int) resolver { 173 return func() mapper { 174 m := r() 175 xf := m.format 176 m.format = func(v reflect.Value, na bool) string { 177 if !na { 178 if v.Kind() == reflect.Float64 || v.Kind() == reflect.Float32 { 179 if len(n) > 0 && n[0] > 0 { 180 v = reflect.ValueOf(fu.Round64(v.Float(), n[0])) 181 } else { 182 v = reflect.ValueOf(math.Round(v.Float())) 183 } 184 } 185 } 186 return format(v, na, xf) 187 } 188 return m 189 } 190 } 191 192 func format(v reflect.Value, na bool, xf func(reflect.Value, bool) string) string { 193 if xf != nil { 194 return xf(v, na) 195 } 196 if na { 197 return "" 198 } else { 199 return fmt.Sprint(v.Interface()) 200 } 201 }