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  }