github.com/MontFerret/ferret@v0.18.0/pkg/runtime/values/int.go (about)

     1  package values
     2  
     3  import (
     4  	"encoding/binary"
     5  	"hash/fnv"
     6  	"strconv"
     7  
     8  	"github.com/wI2L/jettison"
     9  
    10  	"github.com/MontFerret/ferret/pkg/runtime/core"
    11  	"github.com/MontFerret/ferret/pkg/runtime/values/types"
    12  )
    13  
    14  type Int int64
    15  
    16  const ZeroInt = Int(0)
    17  
    18  func NewInt(input int) Int {
    19  	return Int(int64(input))
    20  }
    21  
    22  func ParseInt(input interface{}) (Int, error) {
    23  	if core.IsNil(input) {
    24  		return ZeroInt, nil
    25  	}
    26  
    27  	switch val := input.(type) {
    28  	case int:
    29  		return Int(val), nil
    30  	case int64:
    31  		return Int(val), nil
    32  	case int32:
    33  		return Int(val), nil
    34  	case int16:
    35  		return Int(val), nil
    36  	case int8:
    37  		return Int(val), nil
    38  	case string:
    39  		i, err := strconv.Atoi(val)
    40  
    41  		if err == nil {
    42  			if i == 0 {
    43  				return ZeroInt, nil
    44  			}
    45  
    46  			return Int(i), nil
    47  		}
    48  
    49  		return ZeroInt, err
    50  	default:
    51  		return ZeroInt, core.Error(core.ErrInvalidType, "expected 'int'")
    52  	}
    53  }
    54  
    55  func MustParseInt(input interface{}) Int {
    56  	res, err := ParseInt(input)
    57  
    58  	if err != nil {
    59  		panic(err)
    60  	}
    61  
    62  	return res
    63  }
    64  
    65  func (t Int) MarshalJSON() ([]byte, error) {
    66  	return jettison.MarshalOpts(int64(t), jettison.NoHTMLEscaping())
    67  }
    68  
    69  func (t Int) Type() core.Type {
    70  	return types.Int
    71  }
    72  
    73  func (t Int) String() string {
    74  	return strconv.Itoa(int(t))
    75  }
    76  
    77  func (t Int) Compare(other core.Value) int64 {
    78  	otherType := other.Type()
    79  
    80  	if otherType == types.Int {
    81  		i := other.(Int)
    82  
    83  		if t == i {
    84  			return 0
    85  		}
    86  
    87  		if t < i {
    88  			return -1
    89  		}
    90  
    91  		return +1
    92  	}
    93  
    94  	if otherType == types.Float {
    95  		f := other.(Float)
    96  		f2 := Float(t)
    97  
    98  		if f2 == f {
    99  			return 0
   100  		}
   101  
   102  		if f2 < f {
   103  			return -1
   104  		}
   105  
   106  		return +1
   107  	}
   108  
   109  	return types.Compare(types.Int, otherType)
   110  }
   111  
   112  func (t Int) Unwrap() interface{} {
   113  	return int(t)
   114  }
   115  
   116  func (t Int) Hash() uint64 {
   117  	h := fnv.New64a()
   118  
   119  	h.Write([]byte(t.Type().String()))
   120  	h.Write([]byte(":"))
   121  
   122  	bytes := make([]byte, 8)
   123  	binary.LittleEndian.PutUint64(bytes, uint64(t))
   124  	h.Write(bytes)
   125  
   126  	return h.Sum64()
   127  }
   128  
   129  func (t Int) Copy() core.Value {
   130  	return t
   131  }