Skip to content

Commit deaff0d

Browse files
authored
feat: auto flexible type with trait (#35)
* feat: auto flexible type by trait * Update documents
1 parent 16b2278 commit deaff0d

File tree

5 files changed

+64
-9
lines changed

5 files changed

+64
-9
lines changed

Package.swift

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// swift-tools-version: 6.0
1+
// swift-tools-version: 6.1
22
// The swift-tools-version declares the minimum version of Swift required to build this package.
33

44
import PackageDescription
@@ -15,31 +15,29 @@ let package = Package(
1515
.visionOS(.v1)
1616
],
1717
products: [
18-
// Products define the executables and libraries a package produces, making them visible to other packages.
1918
.library(
2019
name: "ReerCodable",
2120
targets: ["ReerCodable"]
2221
)
2322
],
23+
traits: [
24+
.trait(
25+
name: "AutoFlexibleType",
26+
description: "Enable automatic type conversion for all @Codable/@Decodable types"
27+
),
28+
],
2429
dependencies: [
2530
.package(url: "https://github.com/swiftlang/swift-syntax", from: "600.0.0"),
2631
],
2732
targets: [
28-
// Targets are the basic building blocks of a package, defining a module or a test suite.
29-
// Targets can depend on other targets in this package and products from dependencies.
30-
// Macro implementation that performs the source transformation of a macro.
3133
.macro(
3234
name: "ReerCodableMacros",
3335
dependencies: [
3436
.product(name: "SwiftSyntaxMacros", package: "swift-syntax"),
3537
.product(name: "SwiftCompilerPlugin", package: "swift-syntax")
3638
]
3739
),
38-
39-
// Library that exposes a macro as part of its API, which is used in client programs.
4040
.target(name: "ReerCodable", dependencies: ["ReerCodableMacros"]),
41-
42-
// A test target used to develop the macro implementation.
4341
.testTarget(
4442
name: "ReerCodableTests",
4543
dependencies: [

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,25 @@ struct Settings {
729729
}
730730
```
731731

732+
#### AutoFlexibleType Trait (Swift 6.1+)
733+
734+
If you prefer all types automatically support flexible type conversion without explicit `@FlexibleType` annotation, you can enable the `AutoFlexibleType` trait when adding the package dependency:
735+
736+
```swift
737+
// In your Package.swift
738+
.package(
739+
url: "https://github.com/reers/ReerCodable.git",
740+
from: "1.6.0",
741+
traits: ["AutoFlexibleType"]
742+
)
743+
```
744+
745+
When this trait is enabled, all `@Codable` and `@Decodable` types will automatically support flexible type conversion, just like having `@FlexibleType` applied to every type. This is useful for projects that rely on backend APIs with inconsistent data types.
746+
747+
> **Note:** This feature requires Swift 6.1+ and swift-tools-version: 6.1 in your Package.swift.
748+
749+
> **Important:** After changing traits, you must **delete DerivedData/YourProject** and **restart Xcode** for the changes to take effect.
750+
732751
### 18. AnyCodable Support
733752

734753
Implement encoding/decoding of `Any` type through `AnyCodable`:

README_CN.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,25 @@ struct Settings {
724724
}
725725
```
726726

727+
#### AutoFlexibleType Trait (Swift 6.1+)
728+
729+
如果你希望所有类型自动支持灵活类型转换而无需显式标注 `@FlexibleType`,可以在添加包依赖时启用 `AutoFlexibleType` trait:
730+
731+
```swift
732+
// 在你的 Package.swift 中
733+
.package(
734+
url: "https://github.com/reers/ReerCodable.git",
735+
from: "1.6.0",
736+
traits: ["AutoFlexibleType"]
737+
)
738+
```
739+
740+
启用此 trait 后,所有 `@Codable``@Decodable` 类型将自动支持灵活类型转换,就像每个类型都应用了 `@FlexibleType` 一样。这对于依赖后端 API 数据类型不一致的项目非常有用。
741+
742+
> **注意:** 此功能需要 Swift 6.1+ 并且你的 Package.swift 中需要设置 swift-tools-version: 6.1。
743+
744+
> **重要:** 修改 traits 后,必须**删除 DerivedData/YourProject****重启 Xcode** 才能使更改生效。
745+
727746
### 18. AnyCodable 支持
728747

729748
通过 `AnyCodable` 实现对 `Any` 类型的编解码:

Sources/ReerCodable/MacroDeclarations/FlexibleType.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,5 +48,20 @@
4848
/// ```
4949
///
5050
/// The supported type conversions are defined in the `TypeConvertible` protocol implementations.
51+
///
52+
/// ## AutoFlexibleType Trait (Swift 6.1+)
53+
///
54+
/// If you prefer automatic type conversion for all types without explicit annotation,
55+
/// you can enable the `AutoFlexibleType` trait when adding the package dependency:
56+
///
57+
/// ```swift
58+
/// .package(
59+
/// url: "https://github.com/reers/ReerCodable.git",
60+
/// from: "1.6.0",
61+
/// traits: ["AutoFlexibleType"]
62+
/// )
63+
/// ```
64+
///
65+
/// - Important: After changing traits, you must delete DerivedData/YourProject and restart Xcode for the changes to take effect.
5166
@attached(peer)
5267
public macro FlexibleType() = #externalMacro(module: "ReerCodableMacros", type: "FlexibleType")

Sources/ReerCodableMacros/TypeInfo.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,10 @@ struct TypeInfo {
246246
if decl.attributes.containsAttribute(named: "FlexibleType") {
247247
isFlexibleType = true
248248
}
249+
#if AutoFlexibleType
250+
// When AutoFlexibleType trait is enabled, all types default to flexible type conversion
251+
isFlexibleType = true
252+
#endif
249253
// Check if the class inherits from NSObject
250254
if let classDecl = decl.as(ClassDeclSyntax.self),
251255
let inheritedTypes = classDecl.inheritanceClause?.inheritedTypes {

0 commit comments

Comments
 (0)