Skip to content

Instantly share code, notes, and snippets.

@WhiteHyun
Created August 10, 2024 23:39
Show Gist options
  • Select an option

  • Save WhiteHyun/368c56ccca57dda5ccc70a59378e7fec to your computer and use it in GitHub Desktop.

Select an option

Save WhiteHyun/368c56ccca57dda5ccc70a59378e7fec to your computer and use it in GitHub Desktop.
DTO 매크로
public struct DTOMacro: MemberMacro {
public static func expansion(
of node: AttributeSyntax,
providingMembersOf declaration: some DeclGroupSyntax,
in context: some MacroExpansionContext
) throws -> [DeclSyntax] {
guard let structDecl = declaration as? StructDeclSyntax
else {
return []
}
let properties = structDecl.memberBlock.members.compactMap { member -> (name: String, key: String)? in
guard let variable = member.decl.as(VariableDeclSyntax.self),
let pattern = variable.bindings.first?.pattern.as(IdentifierPatternSyntax.self)
else {
return nil
}
let name = pattern.identifier.text
let key = variable.attributes.compactMap { attr -> String? in
guard let attr = attr.as(AttributeSyntax.self),
attr.attributeName.description == "Property",
let arguments = attr.arguments?.as(LabeledExprListSyntax.self),
let keyArg = arguments.first(where: { $0.label?.text == "key" }),
let stringLiteral = keyArg.expression.as(StringLiteralExprSyntax.self) else {
return nil
}
return stringLiteral.segments.description
}.first ?? name
return (name: name, key: key)
}
let codingKeySyntax = try EnumDeclSyntax("enum CodingKeys: String, CodingKey") {
for property in properties {
if property.name == property.key {
try EnumCaseDeclSyntax("case \(raw: property.name)")
} else {
try EnumCaseDeclSyntax("case \(raw: property.name) = \(literal: property.key)")
}
}
}
return [DeclSyntax(codingKeySyntax)]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment