github.com/friesencr/pop/v6@v6.1.6/slices/float.go (about) 1 package slices 2 3 import ( 4 "database/sql/driver" 5 "fmt" 6 "strconv" 7 "strings" 8 ) 9 10 // Float is a slice of float64. 11 type Float []float64 12 13 // Interface implements the nulls.nullable interface. 14 func (f Float) Interface() interface{} { 15 return []float64(f) 16 } 17 18 // Scan implements the sql.Scanner interface. 19 // It allows to read the float slice from the database value. 20 func (f *Float) Scan(src interface{}) error { 21 var str string 22 switch t := src.(type) { 23 case []byte: 24 str = string(t) 25 case string: 26 str = t 27 default: 28 return fmt.Errorf("scan source was not []byte nor string but %T", src) 29 } 30 v, err := strToFloat(str) 31 *f = v 32 return err 33 } 34 35 // Value implements the driver.Valuer interface. 36 // It allows to convert the float slice to a driver.value. 37 func (f Float) Value() (driver.Value, error) { 38 sa := make([]string, len(f)) 39 for x, i := range f { 40 sa[x] = strconv.FormatFloat(i, 'f', -1, 64) 41 } 42 return fmt.Sprintf("{%s}", strings.Join(sa, ",")), nil 43 } 44 45 // UnmarshalText will unmarshall text value into 46 // the float slice representation of this value. 47 func (f *Float) UnmarshalText(text []byte) error { 48 var ss []float64 49 for _, x := range strings.Split(string(text), ",") { 50 f, err := strconv.ParseFloat(x, 64) 51 if err != nil { 52 return err 53 } 54 ss = append(ss, f) 55 } 56 *f = ss 57 return nil 58 } 59 60 func strToFloat(s string) ([]float64, error) { 61 r := strings.Trim(s, "{}") 62 a := make([]float64, 0, 10) 63 64 elems := strings.Split(r, ",") 65 if len(elems) == 1 && elems[0] == "" { 66 return a, nil 67 } 68 69 for _, t := range elems { 70 f, err := strconv.ParseFloat(t, 64) 71 if err != nil { 72 return nil, err 73 } 74 a = append(a, f) 75 } 76 77 return a, nil 78 }