Slide 21
Slide 21 text
©︎
Swift MacrosͰ҆શͳมΛࣗಈੜ͢Δ
@attached(member, names: arbitrary)
public macro DataSerialize() = #externalMacro(module: "SerializeMacros", type: "DataSerializeMacro")
public struct DataSerializeMacro: MemberMacro {
public static func expansion(
of node: AttributeSyntax,
providingMembersOf declaration: some DeclGroupSyntax,
in context: some MacroExpansionContext
) throws -> [DeclSyntax] {
let properties = declaration.memberBlock.members
.compactMap { $0.decl.as(VariableDeclSyntax.self) }
.map {
(
name: $0.bindings.first!.pattern.as(IdentifierPatternSyntax.self)!.identifier.text,
type: $0.bindings.first!.typeAnnotation!.type.as(IdentifierTypeSyntax.self)!.trimmedDescription
)
}
return [
"""
static func decode(_ data: Data) -> Self {
var offset = 0
func nextValue(_ pointer: UnsafeRawPointer, as: T.Type = T.self) -> T {
defer {
offset += MemoryLayout.size
}
return pointer.advanced(by: offset).load(as: T.self)
}
return data.withUnsafeBytes {
Self.init(
\(raw: properties.map { name, type in
"""
\(name): nextValue($0.baseAddress!)
"""
}.joined(separator: ",\n"))
)
}
}
""",
"""
mutating func encodeToData() -> Data {
\(raw: properties.enumerated().map {
let (index, (name, type)) = $0
return """
let d\(index) = Data(bytesNoCopy: &\(name), count: MemoryLayout<\(type)>.size, deallocator: .none)
"""
}.joined(separator: "\n"))
return \(raw: (0..