go.temporal.io/server@v1.23.0/common/number/number.go (about)

     1  // The MIT License
     2  //
     3  // Copyright (c) 2020 Temporal Technologies Inc.  All rights reserved.
     4  //
     5  // Copyright (c) 2020 Uber Technologies, Inc.
     6  //
     7  // Permission is hereby granted, free of charge, to any person obtaining a copy
     8  // of this software and associated documentation files (the "Software"), to deal
     9  // in the Software without restriction, including without limitation the rights
    10  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    11  // copies of the Software, and to permit persons to whom the Software is
    12  // furnished to do so, subject to the following conditions:
    13  //
    14  // The above copyright notice and this permission notice shall be included in
    15  // all copies or substantial portions of the Software.
    16  //
    17  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    18  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    19  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    20  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    21  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    22  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    23  // THE SOFTWARE.
    24  
    25  package number
    26  
    27  import (
    28  	"fmt"
    29  )
    30  
    31  const (
    32  	TypeUnknown Type = iota
    33  	TypeFloat
    34  	TypeInt
    35  	TypeUint
    36  )
    37  
    38  type (
    39  	Type   int
    40  	Number struct {
    41  		numberType Type
    42  		value      interface{}
    43  	}
    44  )
    45  
    46  func NewNumber(
    47  	value interface{},
    48  ) Number {
    49  
    50  	var numberType Type
    51  	var number interface{}
    52  	switch n := value.(type) {
    53  	case int8:
    54  		numberType = TypeInt
    55  		number = int(n)
    56  	case int16:
    57  		numberType = TypeInt
    58  		number = int(n)
    59  	case int32:
    60  		numberType = TypeInt
    61  		number = int(n)
    62  	case int64:
    63  		numberType = TypeInt
    64  		number = int(n)
    65  	case int:
    66  		numberType = TypeInt
    67  		number = n
    68  
    69  	case uint8:
    70  		numberType = TypeUint
    71  		number = uint(n)
    72  	case uint16:
    73  		numberType = TypeUint
    74  		number = uint(n)
    75  	case uint32:
    76  		numberType = TypeUint
    77  		number = uint(n)
    78  	case uint64:
    79  		numberType = TypeUint
    80  		number = uint(n)
    81  	case uint:
    82  		numberType = TypeUint
    83  		number = n
    84  
    85  	case float32:
    86  		numberType = TypeFloat
    87  		number = float64(n)
    88  	case float64:
    89  		numberType = TypeFloat
    90  		number = n
    91  
    92  	default:
    93  		// DO NOT panic here
    94  		// the value is provided during runtime
    95  		// the logic cannot just panic if input is not a number
    96  		numberType = TypeUnknown
    97  		number = nil
    98  	}
    99  
   100  	return Number{
   101  		numberType: numberType,
   102  		value:      number,
   103  	}
   104  }
   105  
   106  func (n Number) GetIntOrDefault(
   107  	defaultValue int,
   108  ) int {
   109  	switch n.numberType {
   110  	case TypeFloat:
   111  		return int(n.value.(float64))
   112  	case TypeInt:
   113  		return n.value.(int)
   114  	case TypeUint:
   115  		return int(n.value.(uint))
   116  	case TypeUnknown:
   117  		return defaultValue
   118  	default:
   119  		panic(fmt.Sprintf("unknown number type: %v", n.numberType))
   120  	}
   121  }
   122  
   123  func (n Number) GetUintOrDefault(
   124  	defaultValue uint,
   125  ) uint {
   126  	switch n.numberType {
   127  	case TypeFloat:
   128  		return uint(n.value.(float64))
   129  	case TypeInt:
   130  		return uint(n.value.(int))
   131  	case TypeUint:
   132  		return n.value.(uint)
   133  	case TypeUnknown:
   134  		return defaultValue
   135  	default:
   136  		panic(fmt.Sprintf("unknown number type: %v", n.numberType))
   137  	}
   138  }
   139  
   140  func (n Number) GetFloatOrDefault(
   141  	defaultValue float64,
   142  ) float64 {
   143  	switch n.numberType {
   144  	case TypeFloat:
   145  		return n.value.(float64)
   146  	case TypeInt:
   147  		return float64(n.value.(int))
   148  	case TypeUint:
   149  		return float64(n.value.(uint))
   150  	case TypeUnknown:
   151  		return defaultValue
   152  	default:
   153  		panic(fmt.Sprintf("unknown number type: %v", n.numberType))
   154  	}
   155  }