Add `@minValue` and `@maxValue` decorators for numeric types

This commit is contained in:
David Wilson 2021-03-25 11:23:03 -07:00
Родитель 05482edfa7
Коммит 6cf505ac71
2 изменённых файлов: 78 добавлений и 0 удалений

Просмотреть файл

@ -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);
});
});