Add `@minValue` and `@maxValue` decorators for numeric types
This commit is contained in:
Родитель
05482edfa7
Коммит
6cf505ac71
|
@ -112,6 +112,55 @@ export function getMaxLength(target: Type): number | undefined {
|
|||
return maxLengthValues.get(target);
|
||||
}
|
||||
|
||||
// -- @minValue decorator ---------------------
|
||||
|
||||
const minValues = new Map<Type, number>();
|
||||
|
||||
export function isNumericType(target: Type): boolean {
|
||||
const intrinsicType = getIntrinsicType(target);
|
||||
return (
|
||||
intrinsicType !== undefined && ["int32", "int64", "float32", "float64"].includes(intrinsicType)
|
||||
);
|
||||
}
|
||||
|
||||
export function minValue(program: Program, target: Type, minValue: number) {
|
||||
if (target.kind === "Model" || target.kind === "ModelProperty") {
|
||||
// Is it ultimately a numeric type?
|
||||
if (isNumericType(target)) {
|
||||
minValues.set(target, minValue);
|
||||
} else {
|
||||
throw new Error("Cannot apply @minValue to a non-numeric type");
|
||||
}
|
||||
} else {
|
||||
throw new Error("Cannot apply @minValue to anything that isn't a Model or ModelProperty");
|
||||
}
|
||||
}
|
||||
|
||||
export function getMinValue(target: Type): number | undefined {
|
||||
return minValues.get(target);
|
||||
}
|
||||
|
||||
// -- @maxValue decorator ---------------------
|
||||
|
||||
const maxValues = new Map<Type, number>();
|
||||
|
||||
export function maxValue(program: Program, target: Type, maxValue: number) {
|
||||
if (target.kind === "Model" || target.kind === "ModelProperty") {
|
||||
// Is it ultimately a numeric type?
|
||||
if (isNumericType(target)) {
|
||||
maxValues.set(target, maxValue);
|
||||
} else {
|
||||
throw new Error("Cannot apply @maxValue to a non-numeric type");
|
||||
}
|
||||
} else {
|
||||
throw new Error("Cannot apply @maxValue to anything that isn't a Model or ModelProperty");
|
||||
}
|
||||
}
|
||||
|
||||
export function getMaxValue(target: Type): number | undefined {
|
||||
return maxValues.get(target);
|
||||
}
|
||||
|
||||
// -- @secret decorator ---------------------
|
||||
|
||||
const secretTypes = new Map<Type, boolean>();
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
import { strictEqual, ok } from "assert";
|
||||
import { ModelType, Type } from "../../compiler/types.js";
|
||||
import { createTestHost, TestHost } from "../test-host.js";
|
||||
import { getMinValue, getMaxValue } from "../../lib/decorators.js";
|
||||
|
||||
describe("range limiting decorators", () => {
|
||||
let testHost: TestHost;
|
||||
|
||||
beforeEach(async () => {
|
||||
testHost = await createTestHost();
|
||||
});
|
||||
|
||||
it("applies @minimum and @maximum decorators", async () => {
|
||||
testHost.addAdlFile(
|
||||
"a.adl",
|
||||
`
|
||||
@test model A { @minValue 15 foo: int32; @maxValue 55 boo: float32; }
|
||||
@test model B { @maxValue 20 bar: int64; @minValue 23 car: float64; }
|
||||
`
|
||||
);
|
||||
|
||||
const { A, B } = (await testHost.compile("./")) as { A: ModelType; B: ModelType };
|
||||
|
||||
strictEqual(getMinValue(A.properties.get("foo")!), 15);
|
||||
strictEqual(getMaxValue(A.properties.get("boo")!), 55);
|
||||
strictEqual(getMaxValue(B.properties.get("bar")!), 20);
|
||||
strictEqual(getMinValue(B.properties.get("car")!), 23);
|
||||
});
|
||||
});
|
Загрузка…
Ссылка в новой задаче