Class Generation with Swift Macros

Aug 2, 2024

The Goal

@Model
final class NewEntity: Identifiable, Equatable {
    @Attribute(.unique)
    var id: String
    
    init(
        id: String
    ) {
        self.id = id
    }
}

class NewEntityDAO: EntityDAO {
    typealias Entity = NewEntity

    let persistencyContainer: DataPersistencyContainer

    init(persistencyContainer: DataPersistencyContainer) {
        self.persistencyContainer = persistencyContainer
    }

    func predicate(for id: Entity.ID) -> Predicate<Entity> {
        return #Predicate<Entity> {
            $0.id == id
        }
    }
}


The Macro

public struct DAOMacro: PeerMacro {
    public static func expansion(
        of node: AttributeSyntax,
        providingPeersOf declaration: some DeclSyntaxProtocol,
        in context: some MacroExpansionContext
    ) throws -> [DeclSyntax] {
        guard let classDecl = declaration.as(ClassDeclSyntax.self) else {
            return []
        }
        
        let entityClassName = classDecl.name.text
        
        return [
"""
class \(raw: entityClassName)DAO: EntityDAO {
    typealias Entity = \(raw: entityClassName)
    
    let persistencyContainer: DataPersistencyContainer
    
    init(persistencyContainer: DataPersistencyContainer) {
        self.persistencyContainer = persistencyContainer
    }

    func predicate(for id: Entity.ID) -> Predicate<Entity> {
        return #Predicate<Entity> { 
            $0.id == id
        }
    }
}
"""
        ]
    }
}

© Houwert Consultancy | 2024

LinkedIn

Email

© Houwert Consultancy | 2024

LinkedIn

Email

© Houwert Consultancy | 2024

LinkedIn

Email