github.com/NVIDIA/aistore@v1.3.23-0.20240517131212-7df6609be51d/cmn/cos/quantity.go (about) 1 // Package cos provides common low-level types and utilities for all aistore projects 2 /* 3 * Copyright (c) 2018-2023, NVIDIA CORPORATION. All rights reserved. 4 */ 5 package cos 6 7 import ( 8 "fmt" 9 "strconv" 10 "strings" 11 "unicode" 12 ) 13 14 const ( 15 QuantityPercent = "percent" 16 QuantityBytes = "bytes" 17 ) 18 19 type ( 20 ParsedQuantity struct { 21 Type string 22 Value uint64 23 } 24 ) 25 26 /////////////////// 27 // ParseQuantity // 28 /////////////////// 29 30 func ParseQuantity(quantity string) (ParsedQuantity, error) { 31 var ( 32 idx int 33 number string 34 parsedQ ParsedQuantity 35 ) 36 quantity = strings.ReplaceAll(quantity, " ", "") 37 for ; idx < len(quantity) && unicode.IsDigit(rune(quantity[idx])); idx++ { 38 number += string(quantity[idx]) 39 } 40 41 value, err := strconv.Atoi(number) 42 if err != nil { 43 return parsedQ, ErrQuantityUsage 44 } 45 if value < 0 { 46 return parsedQ, errQuantityNonNegative 47 } 48 49 parsedQ.Value = uint64(value) 50 if len(quantity) <= idx { 51 return parsedQ, ErrQuantityUsage 52 } 53 54 suffix := quantity[idx:] 55 if suffix == "%" { 56 parsedQ.Type = QuantityPercent 57 if parsedQ.Value == 0 || parsedQ.Value >= 100 { 58 return parsedQ, ErrQuantityPercent 59 } 60 } else if value, err := ParseSize(quantity, UnitsIEC); err != nil { 61 return parsedQ, err 62 } else if value < 0 { 63 return parsedQ, ErrQuantityBytes 64 } else { 65 parsedQ.Type = QuantityBytes 66 parsedQ.Value = uint64(value) 67 } 68 69 return parsedQ, nil 70 } 71 72 func (pq ParsedQuantity) String() string { 73 switch pq.Type { 74 case QuantityPercent: 75 return fmt.Sprintf("%d%%", pq.Value) 76 case QuantityBytes: 77 return ToSizeIEC(int64(pq.Value), 2) 78 default: 79 AssertMsg(false, "Unknown quantity type: "+pq.Type) 80 return "" 81 } 82 }