swift-codable-macro

提供 Swift 宏,用于自动生成可定制的 Codable 协议实现。

简介

当我们将自定义类型遵循 Codable 协议时,Swift 编译器已经提供了自动实现。当您负责定义编码/解码格式时,这很好,但不幸的是,情况并非总是如此。当格式由其他人定义时,我们可能需要使用奇怪的属性名称,甚至自己实现 encode(to:)init(:from)

当使用某些第三方提供的 REST API 时,通常会发生此类问题。例如,我们可能期望一个 Person 结构体如下所示

public struct Person: Codable {
    var id: String
    var name: String 
    var age: Int
}

但是,由于某些原因,REST API 的响应主体可能如下所示

{
    "data": {
        "id": "9F6E1D7A-EF6A-4F7A-A1E0-46105DD31F3E",
        "meta": {
            "name": "Serika",
            "age": 15
        }
    }
}

在这种情况下,我们必须自己实现对 Codable 的遵循。

为了以更“Swift 式”的方式处理这种情况,swift-codable-macro 可以提供帮助。对于上面的例子,我们可以这样声明 Person 结构体

@Codable
public struct Person {
    @CodingField("data", "id")
    var id: String
    @CodingField("data", "meta", "name")
    var name: String 
    @CodingField("data", "meta", "age")
    var age: Int
}

完成!Codable 的遵循以及 encode(to:)init(from:) 的实现将自动生成!无需其他额外的实现代码!

这还不是此软件包的全部功能。以下代码简要概述了它可以做什么。

@Codable
struct Person {
    @CodingField("data", "id")
    @DecodeTransform(source: String.self, with: { UUID(uuidString: $0)! })
    @EncodeTransform(source: UUID.self, with: \.uuidString)
    var id: UUID
    @CodingField("data", "meta", "name")
    @CodingValidate(source: String.self, with: { !$0.isEmpty })
    @CodingValidate(source: String.self, with: { !$0.contains(where: { $0.isNumber }) })
    var name: String 
    @CodingIgnore
	var habit: String = "writing Swift Macro"
}

@SingleValueCodable
struct FilePath {
    @SingleValueCodableDelegate
    var storage: String
    var isDir: Bool = false 
}

提供的宏

Codable

注释一个类或结构体,使其自动遵循 Codable 协议。它将查找类型定义中的所有存储属性,并基于找到的任何自定义项生成实现。

CodingField(_:default:)

为存储属性指定自定义编码路径和默认值。如果未提供编码路径,将使用属性的名称。不需要使用 default 参数设置默认值,您还可以为属性提供标准初始化器或使用可选类型。该宏能够考虑到这一点。

CodingIgnore

使存储属性在进行编码/解码时被忽略。它要求该属性是可选的或具有标准初始化器。

DecodeTransform(source:with:)

为属性的解码指定自定义转换。它将首先尝试将值解码为提供的 sourceType,然后使用提供的转换来转换它。

EncodeTransform(source:with:)

为属性的编码指定自定义转换。它将首先使用提供的转换来转换该值,然后对转换后的值进行编码。

CodingValidate(source:with:)

为属性的解码指定验证规则。

SingleValueCodable

注释一个类或结构体,使其自动遵循 Codable 协议,通过提供的规则将一个实例从/转换为另一个符合 Codable 的类型的实例。

可以通过以下方式提供规则:

SingleValueCodableDelegate

SingleValueCodable 一起使用,将属性标记为编码和解码的唯一目标。

安装

Package.swift 中,将以下行添加到您的依赖项中

.package(url: "https://github.com/Star-Lord-PHB/swift-codable-macro.git", from: "2.0.0")

CodableMacro 添加为目标的依赖项

.target(
    name: "Target", 
    dependencies: [
        .product(name: "CodableMacro", package: "swift-codable-macro"),
    ]
)

在您的源代码中添加 import CodableMacro