effect
effect copied to clipboard
S.firstOfArray to extract the first element of an array to match a given schema
I found myself needing to extract the first element of an array from api request that matched a given schema and I suspect that something similar might be useful as part of the core lib. Actually, similar utility fns might be useful in general.
import * as S from "@effect/schema/Schema";
import * as PR from "@effect/schema/ParseResult";
import * as RA from "@effect/data/ReadonlyArray";
/**
* Finds the first el in an array that matches the schema.
*/
const firstOfArray = <I, A>(schema: S.Schema<I, A>) => {
const is = S.is(schema);
const encodeSync = S.encodeSync(schema);
const decodeSync = S.decodeSync(schema);
return S.transformResult(
S.array(S.unknown),
schema,
(s) => {
const res = RA.findFirst(s, is);
if (res._tag === "Some") {
return PR.success(encodeSync(res.value));
} else return PR.failure(PR.type(schema.ast, s));
},
(s) => PR.success([decodeSync(s)])
);
};
// example use
const s = S.struct({
descriptions: firstOfArray(
S.struct({
lang: S.literal("en"),
description: S.string,
})
),
});
const res = S.parseSync(s)({
descriptions: [
{ lang: "fr", description: "des" },
{ lang: "en", description: "des" }
],
});
console.log(res); // { descriptions: { lang: 'en', description: 'des' } }