package main import ( "fmt" "math" "strconv" "strings" ) var units []string = []string{"KB", "MB", "GB", "B"} // ByteSize represents a number of bytes type ByteSize struct { HumanRep string NumberRep int64 } // Byte size size suffixes. const ( B int64 = 1 KB int64 = 1 << (10 * iota) MB GB ) // Used to convert user input to ByteSize var unitMap = map[string]int64{ "B": B, "KB": KB, "MB": MB, "GB": GB, } func (b *ByteSize) parseFromString(s string) error { s = strings.TrimSpace(s) b.HumanRep = s var fragments []string unitFound := "" for _, unit := range units { fragments = strings.Split(s, unit) if len(fragments) == 2 { unitFound = unit break } } if len(unitFound) == 0 { return fmt.Errorf("unrecognized size suffix") } value, err := strconv.ParseFloat(fragments[0], 64) if err != nil { return err } unit, ok := unitMap[strings.ToUpper(unitFound)] if !ok { return fmt.Errorf("unrecognized size suffix %s", fragments[1]) } b.NumberRep = int64(value * float64(unit)) return nil } func (b *ByteSize) parseFromNumber(n int64) { b.NumberRep = n bf := float64(n) for _, unit := range []string{"", "K", "M", "G"} { if math.Abs(bf) < 1024.0 { b.HumanRep = fmt.Sprintf("%3.1f%sB", bf, unit) return } bf /= 1024.0 } b.HumanRep = fmt.Sprintf("%.1fTB", bf) }