go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/common/data/text/units/units.go (about) 1 // Copyright 2015 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package units 16 17 import ( 18 "flag" 19 "fmt" 20 "strconv" 21 ) 22 23 var units = []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"} 24 25 // Size represents a size in bytes that knows how to print itself. 26 // 27 // Size implements flag.Value interface. 28 type Size int64 29 30 var _ flag.Value = (*Size)(nil) 31 32 // String returns pretty printed file size. 33 func (s Size) String() string { 34 return SizeToString(int64(s)) 35 } 36 37 // Set sets Size from a given flag args. 38 func (s *Size) Set(str string) error { 39 n, err := strconv.ParseInt(str, 10, 64) 40 if err != nil { 41 return err 42 } 43 *s = Size(n) 44 return nil 45 } 46 47 // SizeToString pretty prints file size (given as number of bytes). 48 func SizeToString(s int64) string { 49 v := float64(s) 50 i := 0 51 for ; i < len(units); i++ { 52 if v < 1024. { 53 break 54 } 55 v /= 1024. 56 } 57 if i == 0 { 58 return fmt.Sprintf("%d%s", s, units[i]) 59 } 60 if v >= 10 { 61 return fmt.Sprintf("%.1f%s", v, units[i]) 62 } 63 return fmt.Sprintf("%.2f%s", v, units[i]) 64 }