All files / src/chain float.ts

63.04% Statements 29/46
50% Branches 8/16
72.22% Functions 13/18
63.04% Lines 29/46

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142                    1x           2x     2x 2x       2x           5x                                   7x     7x                 2x 2x       2x       2x           1x 1x     1x           1x 1x         1x 1x     1x     1x 1x   1x       1x                       2x     2x                 1x         1x       1x      
import {ABISerializableObject} from '../serializer/serializable'
import {ABIDecoder} from '../serializer/decoder'
import {ABIEncoder} from '../serializer/encoder'
import {isInstanceOf, secureRandom} from '../utils'
 
import {Bytes, BytesType} from '../'
 
type FloatType = Float | number | string
 
class Float implements ABISerializableObject {
    static abiName = '__float'
    static byteWidth: number
 
    static from<T extends typeof Float>(this: T, value: FloatType): InstanceType<T>
    static from(value: FloatType): unknown
    static from(value: FloatType) {
        Iif (isInstanceOf(value, this)) {
            return value
        }
        Eif (typeof value === 'string') {
            value = Number.parseFloat(value)
        } else if (isInstanceOf(value, Float)) {
            value = value.value
        }
        return new this(value)
    }
 
    static fromABI<T extends typeof Float>(this: T, decoder: ABIDecoder): InstanceType<T>
    static fromABI(decoder: ABIDecoder): unknown
    static fromABI(decoder: ABIDecoder) {
        return new this(decoder.readFloat(this.byteWidth))
    }
 
    static abiDefault() {
        return this.from(0)
    }
 
    static random<T extends typeof Float>(this: T): InstanceType<T>
    static random(): unknown
    static random() {
        const bytes = secureRandom(this.byteWidth)
        const decoder = new ABIDecoder(bytes)
        return this.fromABI(decoder)
    }
 
    value: number
 
    constructor(value: number) {
        Iif (!Number.isFinite(value)) {
            throw new Error('Invalid number')
        }
        this.value = value
    }
 
    equals(other: FloatType) {
        const self = this.constructor as typeof Float
        return this.value === self.from(other).value
    }
 
    toABI(encoder: ABIEncoder) {
        const self = this.constructor as typeof Float
        encoder.writeFloat(this.value, self.byteWidth)
    }
 
    toString() {
        return this.value.toString()
    }
 
    toJSON() {
        return this.toString()
    }
}
 
export type Float32Type = Float32 | FloatType
export class Float32 extends Float {
    static abiName = 'float32'
    static byteWidth = 4
 
    toString() {
        return this.value.toFixed(7)
    }
}
 
export type Float64Type = Float64 | FloatType
export class Float64 extends Float {
    static abiName = 'float64'
    static byteWidth = 8
}
 
export type Float128Type = Float128 | BytesType
export class Float128 implements ABISerializableObject {
    static abiName = 'float128'
    static byteWidth = 16
 
    static from(value: Float128Type) {
        Iif (isInstanceOf(value, this)) {
            return value
        }
        Eif (typeof value === 'string' && value.startsWith('0x')) {
            value = value.slice(2)
        }
        return new this(Bytes.from(value))
    }
 
    static fromABI(decoder: ABIDecoder) {
        return new this(new Bytes(decoder.readArray(this.byteWidth)))
    }
 
    static random() {
        const bytes = secureRandom(16)
        const decoder = new ABIDecoder(bytes)
        return this.fromABI(decoder)
    }
 
    data: Bytes
 
    constructor(data: Bytes) {
        Iif (data.array.length !== 16) {
            throw new Error('Invalid float128')
        }
        this.data = data
    }
 
    equals(other: Float128Type) {
        const self = this.constructor as typeof Float128
        return this.data.equals(self.from(other).data)
    }
 
    toABI(encoder: ABIEncoder) {
        encoder.writeArray(this.data.array)
    }
 
    toString() {
        // float128 uses 0x prefixed hex strings as opposed to everywhere else in where there is no prefix ¯\_(ツ)_/¯
        return '0x' + this.data.hexString
    }
 
    toJSON() {
        return this.toString()
    }
}