squiggle/packages/components/src/lib/plotParser.ts

73 lines
1.8 KiB
TypeScript
Raw Normal View History

2022-08-19 11:17:31 +00:00
import * as yup from "yup";
2022-07-13 05:54:45 +00:00
import { Distribution, result, squiggleExpression } from "@quri/squiggle-lang";
export type LabeledDistribution = {
name: string;
distribution: Distribution;
color?: string;
};
2022-07-13 05:54:45 +00:00
export type Plot = {
distributions: LabeledDistribution[];
};
function error<a, b>(err: b): result<a, b> {
return { tag: "Error", value: err };
}
function ok<a, b>(x: a): result<a, b> {
return { tag: "Ok", value: x };
}
2022-08-19 11:17:31 +00:00
const schema = yup
.object()
.strict()
.noUnknown()
.shape({
distributions: yup.object().shape({
tag: yup.mixed().oneOf(["array"]),
value: yup
.array()
.of(
yup.object().shape({
tag: yup.mixed().oneOf(["record"]),
value: yup.object({
2022-08-19 11:17:31 +00:00
name: yup.object().shape({
tag: yup.mixed().oneOf(["string"]),
value: yup.string().required(),
}),
// color: yup
// .object({
// tag: yup.mixed().oneOf(["string"]),
// value: yup.string().required(),
// })
// .default(undefined),
distribution: yup.object({
2022-08-19 11:17:31 +00:00
tag: yup.mixed().oneOf(["distribution"]),
value: yup.mixed(),
}),
}),
})
)
.required(),
}),
});
2022-07-13 05:54:45 +00:00
export function parsePlot(record: {
[key: string]: squiggleExpression;
}): result<Plot, string> {
2022-08-19 11:17:31 +00:00
try {
const plotRecord = schema.validateSync(record);
return ok({
distributions: plotRecord.distributions.value.map((x) => ({
name: x.value.name.value,
// color: x.value.color?.value, // not supported yet
2022-08-19 11:17:31 +00:00
distribution: x.value.distribution.value,
})),
});
} catch (e) {
const message = e instanceof Error ? e.message : "Unknown error";
return error(message);
}
2022-07-13 05:54:45 +00:00
}