summary refs log tree commit diff
path: root/dist/util/BitField.js
blob: 97d76f3af3b200d3a83cc551b55160a3ec982e99 (plain) (blame)
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
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BitField = void 0;
/**
 * Data structure that makes it easy to interact with a bitfield.
 */
class BitField {
    constructor(bits = 0) {
        this.bitfield = BigInt(0);
        this.bitfield = BitField.resolve(bits);
    }
    /**
     * Checks whether the bitfield has a bit, or any of multiple bits.
     */
    any(bit) {
        return (this.bitfield & BitField.resolve(bit)) !== 0n;
    }
    /**
     * Checks if this bitfield equals another
     */
    equals(bit) {
        return this.bitfield === BitField.resolve(bit);
    }
    /**
     * Checks whether the bitfield has a bit, or multiple bits.
     */
    has(bit) {
        if (Array.isArray(bit))
            return bit.every((p) => this.has(p));
        const BIT = BitField.resolve(bit);
        return (this.bitfield & BIT) === BIT;
    }
    /**
     * Gets all given bits that are missing from the bitfield.
     */
    missing(bits) {
        if (!Array.isArray(bits))
            bits = new BitField(bits).toArray();
        return bits.filter((p) => !this.has(p));
    }
    /**
     * Freezes these bits, making them immutable.
     */
    freeze() {
        return Object.freeze(this);
    }
    /**
     * Adds bits to these ones.
     * @param {...BitFieldResolvable} [bits] Bits to add
     * @returns {BitField} These bits or new BitField if the instance is frozen.
     */
    add(...bits) {
        let total = 0n;
        for (const bit of bits) {
            total |= BitField.resolve(bit);
        }
        if (Object.isFrozen(this))
            return new BitField(this.bitfield | total);
        this.bitfield |= total;
        return this;
    }
    /**
     * Removes bits from these.
     * @param {...BitFieldResolvable} [bits] Bits to remove
     */
    remove(...bits) {
        let total = 0n;
        for (const bit of bits) {
            total |= BitField.resolve(bit);
        }
        if (Object.isFrozen(this))
            return new BitField(this.bitfield & ~total);
        this.bitfield &= ~total;
        return this;
    }
    /**
     * Gets an object mapping field names to a {@link boolean} indicating whether the
     * bit is available.
     * @param {...*} hasParams Additional parameters for the has method, if any
     */
    serialize() {
        const serialized = {};
        for (const [flag, bit] of Object.entries(BitField.FLAGS))
            serialized[flag] = this.has(bit);
        return serialized;
    }
    /**
     * Gets an {@link Array} of bitfield names based on the bits available.
     */
    toArray() {
        return Object.keys(BitField.FLAGS).filter((bit) => this.has(bit));
    }
    toJSON() {
        return this.bitfield;
    }
    valueOf() {
        return this.bitfield;
    }
    *[Symbol.iterator]() {
        yield* this.toArray();
    }
    /**
     * Data that can be resolved to give a bitfield. This can be:
     * * A bit number (this can be a number literal or a value taken from {@link BitField.FLAGS})
     * * An instance of BitField
     * * An Array of BitFieldResolvable
     * @typedef {number|BitField|BitFieldResolvable[]} BitFieldResolvable
     */
    /**
     * Resolves bitfields to their numeric form.
     * @param {BitFieldResolvable} [bit=0] - bit(s) to resolve
     * @returns {number}
     */
    static resolve(bit = 0n) {
        if ((typeof bit === "number" || typeof bit === "bigint") && bit >= 0n)
            return BigInt(bit);
        if (bit instanceof BitField)
            return bit.bitfield;
        if (Array.isArray(bit))
            return bit.map((p) => this.resolve(p)).reduce((prev, p) => BigInt(prev) | BigInt(p), 0n);
        if (typeof bit === "string" && typeof this.FLAGS[bit] !== "undefined")
            return this.FLAGS[bit];
        throw new RangeError("BITFIELD_INVALID: " + bit);
    }
}
exports.BitField = BitField;
//# sourceMappingURL=BitField.js.map