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  }