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  }