Skip to content

Commit

Permalink
Add support for Enums in Record, closes #2811 (#2814)
Browse files Browse the repository at this point in the history
  • Loading branch information
gcanti authored May 22, 2024
1 parent e313a01 commit f8038ca
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 10 deletions.
5 changes: 5 additions & 0 deletions .changeset/eleven-pens-kick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@effect/schema": patch
---

Add support for Enums in Record, closes #2811
6 changes: 6 additions & 0 deletions packages/schema/src/AST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2005,6 +2005,12 @@ export const record = (key: AST, value: AST): {
)
}
break
case "Enums": {
for (const [_, name] of key.enums) {
propertySignatures.push(new PropertySignature(name, value, false, true))
}
break
}
case "UniqueSymbol":
propertySignatures.push(new PropertySignature(key.symbol, value, false, true))
break
Expand Down
55 changes: 45 additions & 10 deletions packages/schema/test/Schema/Record/Record.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,48 @@ describe("record", () => {
})

describe("decoding", () => {
it("record(never, number)", async () => {
it("Record(enum, number)", async () => {
enum Abc {
A = 1,
B = "b",
C = "c"
}
const AbcSchema = S.Enums(Abc)
const schema = S.Record(AbcSchema, S.String)
await Util.expectDecodeUnknownSuccess(schema, { [Abc.A]: "A", [Abc.B]: "B", [Abc.C]: "C" })
await Util.expectDecodeUnknownSuccess(schema, { [1]: "A", b: "B", c: "C" })
await Util.expectDecodeUnknownSuccess(schema, { "1": "A", b: "B", c: "C" })

await Util.expectDecodeUnknownFailure(
schema,
{ [Abc.B]: "B", [Abc.C]: "C" },
`{ readonly 1: string; readonly b: string; readonly c: string }
└─ [1]
└─ is missing`
)
await Util.expectDecodeUnknownFailure(
schema,
{ [Abc.A]: "A", [Abc.B]: "B" },
`{ readonly 1: string; readonly b: string; readonly c: string }
└─ ["c"]
└─ is missing`
)
await Util.expectDecodeUnknownFailure(
schema,
{ [Abc.A]: null, [Abc.B]: "B", [Abc.C]: "C" },
`{ readonly 1: string; readonly b: string; readonly c: string }
└─ [1]
└─ Expected a string, actual null`
)
})

it("Record(never, number)", async () => {
const schema = S.Record(S.Never, S.Number)
await Util.expectDecodeUnknownSuccess(schema, {})
await Util.expectDecodeUnknownSuccess(schema, { a: 1 })
})

it("record(string, number)", async () => {
it("Record(string, number)", async () => {
const schema = S.Record(S.String, S.Number)
await Util.expectDecodeUnknownSuccess(schema, {})
await Util.expectDecodeUnknownSuccess(schema, { a: 1 })
Expand Down Expand Up @@ -81,7 +116,7 @@ describe("record", () => {
)
})

it("record(symbol, number)", async () => {
it("Record(symbol, number)", async () => {
const a = Symbol.for("@effect/schema/test/a")
const schema = S.Record(S.SymbolFromSelf, S.Number)
await Util.expectDecodeUnknownSuccess(schema, {})
Expand Down Expand Up @@ -114,7 +149,7 @@ describe("record", () => {
)
})

it("record('a' | 'b', number)", async () => {
it("Record('a' | 'b', number)", async () => {
const schema = S.Record(S.Union(S.Literal("a"), S.Literal("b")), S.Number)
await Util.expectDecodeUnknownSuccess(schema, { a: 1, b: 2 })

Expand All @@ -141,7 +176,7 @@ describe("record", () => {
)
})

it("record('a' | `prefix-${string}`, number)", async () => {
it("Record('a' | `prefix-${string}`, number)", async () => {
const schema = S.Record(
S.Union(S.Literal("a"), S.TemplateLiteral(S.Literal("prefix-"), S.String)),
S.Number
Expand All @@ -165,7 +200,7 @@ describe("record", () => {
)
})

it("record(keyof struct({ a, b }), number)", async () => {
it("Record(keyof struct({ a, b }), number)", async () => {
const schema = S.Record(S.keyof(S.Struct({ a: S.String, b: S.String })), S.Number)
await Util.expectDecodeUnknownSuccess(schema, { a: 1, b: 2 })

Expand Down Expand Up @@ -199,7 +234,7 @@ describe("record", () => {
)
})

it("record(Symbol('a') | Symbol('b'), number)", async () => {
it("Record(Symbol('a') | Symbol('b'), number)", async () => {
const a = Symbol.for("@effect/schema/test/a")
const b = Symbol.for("@effect/schema/test/b")
const schema = S.Record(S.Union(S.UniqueSymbolFromSelf(a), S.UniqueSymbolFromSelf(b)), S.Number)
Expand Down Expand Up @@ -228,7 +263,7 @@ describe("record", () => {
)
})

it("record(${string}-${string}, number)", async () => {
it("Record(${string}-${string}, number)", async () => {
const schema = S.Record(S.TemplateLiteral(S.String, S.Literal("-"), S.String), S.Number)
await Util.expectDecodeUnknownSuccess(schema, {})
await Util.expectDecodeUnknownSuccess(schema, { "-": 1 })
Expand Down Expand Up @@ -278,7 +313,7 @@ describe("record", () => {
)
})

it("record(minLength(2), number)", async () => {
it("Record(minLength(2), number)", async () => {
const schema = S.Record(S.String.pipe(S.minLength(2)), S.Number)
await Util.expectDecodeUnknownSuccess(schema, {})
await Util.expectDecodeUnknownSuccess(schema, { "a": 1 }, {})
Expand All @@ -303,7 +338,7 @@ describe("record", () => {
)
})

it("record(${string}-${string}, number) & record(string, string | number)", async () => {
it("Record(${string}-${string}, number) & record(string, string | number)", async () => {
const schema = S.Struct(
{},
S.Record(S.TemplateLiteral(S.String, S.Literal("-"), S.String), S.Number),
Expand Down

0 comments on commit f8038ca

Please sign in to comment.