haimkastner / unitsnet-js

A better way to hold unit variables and easily convert to the destination unit
https://www.npmjs.com/package/unitsnet-js
MIT License
23 stars 8 forks source link

Introduce full operator overriding support #41

Closed yuval-po closed 4 months ago

yuval-po commented 4 months ago

Full operator overriding support (Breaking)

Previously, operator overriding only affected instance arithmetic methods, not constructor base conversion or static factory methods.

This P.R addresses this by generating hooked TypeScript code from each unit formula, allowing operators to overridden on all arithmetic operations conducted by all unit classes.

Change technical specification:

Final code looks like so:

    private convertFromBase(toUnit: ElectricChargeUnits): number {
        if (areAnyOperatorsOverridden())
            switch (toUnit) {
                case ElectricChargeUnits.Coulombs: return this.value;
                case ElectricChargeUnits.AmpereHours: return super.internalMultiply(this.value, 2.77777777777e-4);
                case ElectricChargeUnits.Picocoulombs: return super.internalDivide(this.value, 1e-12);
                case ElectricChargeUnits.Nanocoulombs: return super.internalDivide(this.value, 1e-9);
                case ElectricChargeUnits.Microcoulombs: return super.internalDivide(this.value, 0.000001);
                case ElectricChargeUnits.Millicoulombs: return super.internalDivide(this.value, 0.001);
                case ElectricChargeUnits.Kilocoulombs: return super.internalDivide(this.value, 1000);
                case ElectricChargeUnits.Megacoulombs: return super.internalDivide(this.value, 1000000);
                case ElectricChargeUnits.MilliampereHours: {
                    const v3 = super.internalMultiply(this.value, 2.77777777777e-4);
                    return super.internalDivide(v3, 0.001);
                }
                case ElectricChargeUnits.KiloampereHours: {
                    const v3 = super.internalMultiply(this.value, 2.77777777777e-4);
                    return super.internalDivide(v3, 1000);
                }
                case ElectricChargeUnits.MegaampereHours: {
                    const v3 = super.internalMultiply(this.value, 2.77777777777e-4);
                    return super.internalDivide(v3, 1000000);
                }
                default: return Number.NaN;
            }
        switch (toUnit) {
            case ElectricChargeUnits.Coulombs: return this.value;
            case ElectricChargeUnits.AmpereHours: return this.value * 2.77777777777e-4;
            case ElectricChargeUnits.Picocoulombs: return (this.value) / 1e-12;
            case ElectricChargeUnits.Nanocoulombs: return (this.value) / 1e-9;
            case ElectricChargeUnits.Microcoulombs: return (this.value) / 0.000001;
            case ElectricChargeUnits.Millicoulombs: return (this.value) / 0.001;
            case ElectricChargeUnits.Kilocoulombs: return (this.value) / 1000;
            case ElectricChargeUnits.Megacoulombs: return (this.value) / 1000000;
            case ElectricChargeUnits.MilliampereHours: return (this.value * 2.77777777777e-4) / 0.001;
            case ElectricChargeUnits.KiloampereHours: return (this.value * 2.77777777777e-4) / 1000;
            case ElectricChargeUnits.MegaampereHours: return (this.value * 2.77777777777e-4) / 1000000;
            default: return Number.NaN;
        }
    }

Changes include:

haimkastner commented 4 months ago

Full implementation for #33 to allow external arithmetic operator overriding for all internal conventions from/to base unit.

(#34 Implementation was only for the arithmetic operations between units instances).

Thank you @yuval-po it looks fantastic!!!