diff --git a/Sources/PluginCore/Variables/Enum/Switcher/TaggedEnumSwitcherVariable.swift b/Sources/PluginCore/Variables/Enum/Switcher/TaggedEnumSwitcherVariable.swift index 4d8d33f60..c0e029cf9 100644 --- a/Sources/PluginCore/Variables/Enum/Switcher/TaggedEnumSwitcherVariable.swift +++ b/Sources/PluginCore/Variables/Enum/Switcher/TaggedEnumSwitcherVariable.swift @@ -150,6 +150,7 @@ extension EnumSwitcherVariable { generatedCode } } else { + preSyntax("\(values.first!)") "break" } } diff --git a/Tests/MetaCodableTests/CodedAt/CodedAtEnumTests.swift b/Tests/MetaCodableTests/CodedAt/CodedAtEnumTests.swift index 6e9a8b19b..d5e523cb3 100644 --- a/Tests/MetaCodableTests/CodedAt/CodedAtEnumTests.swift +++ b/Tests/MetaCodableTests/CodedAt/CodedAtEnumTests.swift @@ -802,4 +802,103 @@ struct CodedAtEnumTests { #expect(json["int"] as? Int == 42) } } + + struct WithoutAssociatedVariables { + @Codable + @CodedAt("type") + enum Foo { + case foo + } + + @Test + func expansion() throws { + assertMacroExpansion( + """ + @Codable + @CodedAt("type") + enum Foo { + case foo + } + """, + expandedSource: + """ + enum Foo { + case foo + } + + extension Foo: Decodable { + init(from decoder: any Decoder) throws { + var typeContainer: KeyedDecodingContainer? + let container = try? decoder.container(keyedBy: CodingKeys.self) + if let container = container { + typeContainer = container + } else { + typeContainer = nil + } + if let typeContainer = typeContainer { + let typeString: String? + do { + typeString = try typeContainer.decodeIfPresent(String.self, forKey: CodingKeys.type) ?? nil + } catch { + typeString = nil + } + if let typeString = typeString { + switch typeString { + case "foo": + self = .foo + return + default: + break + } + } + } + let context = DecodingError.Context( + codingPath: decoder.codingPath, + debugDescription: "Couldn't match any cases." + ) + throw DecodingError.typeMismatch(Self.self, context) + } + } + + extension Foo: Encodable { + func encode(to encoder: any Encoder) throws { + let container = encoder.container(keyedBy: CodingKeys.self) + var typeContainer = container + switch self { + case .foo: + try typeContainer.encode("foo", forKey: CodingKeys.type) + break + } + } + } + + extension Foo { + enum CodingKeys: String, CodingKey { + case type = "type" + } + } + """ + ) + } + + @Test + func decodingFromJSON() throws { + let jsonStr = """ + { + "type": "foo" + } + """ + let jsonData = try #require(jsonStr.data(using: .utf8)) + let decoded = try JSONDecoder().decode(Foo.self, from: jsonData) + #expect(decoded == Foo.foo) + } + + @Test + func encodingToJSON() throws { + let original = Foo.foo + let encoded = try JSONEncoder().encode(original) + let json = try JSONSerialization.jsonObject(with: encoded) as? [String: Any] + #expect(json?["type"] as? String == "foo") + } + } }