In the past, some implementations I needed could only be achieved by customizing official codecs such as JSONDecoder/JSONEncoder. I want to make a small contribution to the improvement of this project. For example, the following features provide discussion.
1. Default value by InitializerClauseSyntax
Provide default value by InitializerClauseSyntax (decl.binding.initializer?.value).
Example:
struct Example {
@Default(10)
let int: Int /// defaul value is 10
var int2: Int = 10 /// default value is 10
@Default(10)
var int3: Int = 20 /// default value is 10 when apply `Default` attribute
var int4: Int = 4, int5: Int = 5 /// `int4` default value is 4, `int5` default value is 5
}
2. Add GroupedDefault for multiple bindings
I add a GroupedDefault member attribute like Default but attach to multiple bindings:
@attached(peer)
@available(swift 5.9)
public macro GroupedDefault<each T>(_ defaults: repeat each T) =
#externalMacro(module: "MacroPlugin", type: "GroupedDefault")
Using Example:
struct Student {
@GroupedDefault("Simon", 22)
let name: String, age: Int
@Default(60)
let grade: Int
}
3. We can infer some types like Int, Bool, String, Float, Double with var age = 10, var string = "hello"refer to MemberwiseInit project.
struct SomeInferTest {
var int = 10 /// Int
var float = 0.1 as Float /// Float
var double = 0.11 /// Double
var string = "hello" /// String
var bool = Bool() /// Bool
var date = Date() /// Date
}
So we can add default value like this:
struct Student {
var name = "unknown", age = 0
var grade = 60
}
Same as:
struct Student {
var name: String = "unknown", age: Int = 0
var grade: Int = 60
}
and
struct Student {
@GroupedDefault("unknown", 0)
let name: String, age: Int
@Default(60)
let grade: Int
}
4.Just generate one init function.
@MemberInit
struct Student {
let name: String, age: Int
@Default(60)
let grade: Int
var isBoy: Bool = false
var isGirl: Bool = true
}
Generate 4 init function in past like this:
init(name: String, age: Int, grade: Int = 60) {
self.name = name
self.age = age
self.grade = grade
}
init(name: String, age: Int, grade: Int = 60, isBoy: Bool) {
self.name = name
self.age = age
self.grade = grade
self.isBoy = isBoy
}
init(name: String, age: Int, grade: Int = 60, isGirl: Bool) {
self.name = name
self.age = age
self.grade = grade
self.isGirl = isGirl
}
init(name: String, age: Int, grade: Int = 60, isBoy: Bool, isGirl: Bool) {
self.name = name
self.age = age
self.grade = grade
self.isBoy = isBoy
self.isGirl = isGirl
}
Thanks @SouHanaQiao for this contribution. Please create separate PRs for each feature contribution, this will help in reviewing PRs and also auto changelog generation happens per PR.
This is an amazing project about swift macros.
In the past, some implementations I needed could only be achieved by customizing official codecs such as JSONDecoder/JSONEncoder. I want to make a small contribution to the improvement of this project. For example, the following features provide discussion.
1. Default value by InitializerClauseSyntax
Provide default value by
InitializerClauseSyntax
(decl.binding.initializer?.value).Example:
2. Add
GroupedDefault
for multiple bindingsI add a
GroupedDefault
member attribute likeDefault
but attach to multiple bindings:Using Example:
3. We can infer some types like
Int
,Bool
,String
,Float
,Double
withvar age = 10
,var string = "hello"
refer to MemberwiseInit project.So we can add default value like this:
Same as:
and
4.Just generate one init function.
Generate 4 init function in past like this:
But now expand 1 init function like this: