export const makeEnglishPolicy = Effect.fn("makeEnglishPolicy")(
function* (options: {
readonly id: string;
readonly rules: readonly EnglishRule[];
readonly provider: DecisionProvider;
readonly settings: unknown;
readonly fixedRuleIds?: readonly string[];
}): Effect.fn.Return<MessageMiddleware, CheckInputError> {
const settings = yield* decodeFrozen(
EnglishPolicySettings,
options.settings,
).pipe(
Effect.catchTag("ParseError", () =>
Effect.fail(new CheckInputError({ reason: "settings" })),
),
);
const { id, rules } = yield* decodeFrozen(
Schema.Struct({
id: Schema.NonEmptyTrimmedString,
rules: Schema.NonEmptyArray(EnglishRule),
}),
{ id: options.id, rules: options.rules },
).pipe(
Effect.catchTag("ParseError", () =>
Effect.fail(new CheckInputError({ reason: "registration" })),
),
);
if (new Set(rules.map((rule) => rule.id)).size !== rules.length) {
return yield* new CheckInputError({ reason: "registration" });
}
const descriptions = yield* ruleDescriptions(rules);
const revision = englishRevision(rules, settings);
const provider = Object.freeze({
decide: options.provider.decide.bind(options.provider),
});
return Object.freeze({
id,
revision,
rules: descriptions,
provenance: englishProvenance(
rules,
settings,
options.provider,
options.fixedRuleIds,
),
check: (input: MiddlewareInput) =>
checkEnglish(input, { rules, revision }, provider, settings),
});
},
)