98 lines
2.4 KiB
TypeScript
98 lines
2.4 KiB
TypeScript
import Joi from "joi";
|
|
import { NullOr } from "../../../../utilities";
|
|
import { RuleValidator } from "../RuleValidator";
|
|
import {
|
|
INullableValueObjectOptions,
|
|
NullableValueObject,
|
|
} from "./NullableValueObject";
|
|
import { Result } from "./Result";
|
|
|
|
export interface IQuantityOptions extends INullableValueObjectOptions {}
|
|
|
|
export class Quantity extends NullableValueObject<number> {
|
|
protected static validate(
|
|
value: NullOr<number | string>,
|
|
options: IQuantityOptions = {},
|
|
) {
|
|
const ruleNull = RuleValidator.RULE_ALLOW_NULL_OR_UNDEFINED.default(null);
|
|
|
|
const ruleNumber = RuleValidator.RULE_IS_TYPE_NUMBER.label(
|
|
options.label ? options.label : "quantity",
|
|
);
|
|
|
|
const ruleString = RuleValidator.RULE_IS_TYPE_STRING.regex(
|
|
/^[-]?\d+$/,
|
|
).label(options.label ? options.label : "quantity");
|
|
|
|
const rules = Joi.alternatives(ruleNull, ruleNumber, ruleString);
|
|
|
|
return RuleValidator.validate<NullOr<number>>(rules, value);
|
|
}
|
|
|
|
public static create(
|
|
value: NullOr<number | string>,
|
|
options: IQuantityOptions = {},
|
|
) {
|
|
const _options = {
|
|
label: "quantity",
|
|
...options,
|
|
};
|
|
|
|
const validationResult = Quantity.validate(value, _options);
|
|
|
|
if (validationResult.isFailure) {
|
|
return Result.fail(validationResult.error);
|
|
}
|
|
|
|
let _value: NullOr<number> = null;
|
|
|
|
if (typeof validationResult.object === "string") {
|
|
_value = parseInt(validationResult.object, 10);
|
|
} else {
|
|
_value = validationResult.object;
|
|
}
|
|
|
|
return Result.ok<Quantity>(new Quantity(_value));
|
|
}
|
|
|
|
public toNumber(): number {
|
|
return this.isNull() ? 0 : Number(this.value);
|
|
}
|
|
|
|
public toString(): string {
|
|
return this.isNull() ? "" : String(this.value);
|
|
}
|
|
|
|
public toPrimitive(): number {
|
|
return this.toNumber();
|
|
}
|
|
|
|
public increment(amount: number = 1) {
|
|
const validationResult = Quantity.validate(amount);
|
|
|
|
if (validationResult.isFailure) {
|
|
return Result.fail(validationResult.error);
|
|
}
|
|
|
|
if (this.value === null) {
|
|
return Quantity.create(amount);
|
|
}
|
|
|
|
return Quantity.create(this.value + amount);
|
|
}
|
|
|
|
public decrement(amount: number = 1) {
|
|
const validationResult = Quantity.validate(amount);
|
|
|
|
if (validationResult.isFailure) {
|
|
return Result.fail(validationResult.error);
|
|
}
|
|
|
|
if (this.value === null) {
|
|
return Quantity.create(amount);
|
|
}
|
|
|
|
return Quantity.create(this.value - amount);
|
|
}
|
|
}
|