diff --git a/Sources/AnyLanguageModel/Generable.swift b/Sources/AnyLanguageModel/Generable.swift index 411abd3..1da4fac 100644 --- a/Sources/AnyLanguageModel/Generable.swift +++ b/Sources/AnyLanguageModel/Generable.swift @@ -42,6 +42,15 @@ public enum GeneratedContentConversionError: Error { // MARK: - Macros /// Conforms a type to ``Generable`` protocol. +/// +/// This macro synthesizes a memberwise initializer +/// and an `init(_ generatedContent: GeneratedContent)` initializer +/// for the annotated type. +/// +/// - Note: The synthesized memberwise initializer isn't visible inside other macro bodies, +/// such as `#Playground`. +/// As a workaround, use the `init(_ generatedContent:)` initializer +/// or define a factory method on the type. @attached(extension, conformances: Generable, names: named(init(_:)), named(generatedContent)) @attached(member, names: arbitrary) public macro Generable(description: String? = nil) = diff --git a/Tests/AnyLanguageModelTests/GenerableMacroTests.swift b/Tests/AnyLanguageModelTests/GenerableMacroTests.swift index 75e1229..3607b6c 100644 --- a/Tests/AnyLanguageModelTests/GenerableMacroTests.swift +++ b/Tests/AnyLanguageModelTests/GenerableMacroTests.swift @@ -141,3 +141,40 @@ struct GenerableMacroTests { #expect(args.asPartiallyGenerated().id == generationID) } } + +// MARK: - #Playground Usage + +// The `#Playground` macro doesn't see the memberwise initializer +// that `@Generable` expands. This is a limitation of how macros compose: +// one macro's expansion isn't visible within another macro's body. +// +// The following code demonstrates workarounds for this limitation. + +#if canImport(Playgrounds) + import Playgrounds + + // Use the `GeneratedContent` initializer explicitly. + #Playground { + let content = GeneratedContent(properties: [ + "name": "Alice", + "age": 30, + ]) + let _ = try TestArguments(content) + } + + // Define a factory method as an alternative to the memberwise initializer. + extension TestArguments { + static func create(name: String, age: Int) -> TestArguments { + try! TestArguments( + GeneratedContent(properties: [ + "name": name, + "age": age, + ]) + ) + } + } + + #Playground { + let _ = TestArguments.create(name: "Bob", age: 42) + } +#endif // canImport(Playgrounds)