Generate boilerplate for Swift phantom types
swift-tagged-macro
Provides a Swift macro wrapping some type declaration boilerplate in swift-tagged.
Example
import TaggedMacro
import Tagged
struct Person {
#tagged(UUID.self, "ID")
let id: ID
}
➡️ becomes:
struct Person {
enum ID_Tag {
}
typealias ID = Tagged<ID_Tag, UUID>
let id: ID
}
Motivation
swift-tagged is a framework from the PointFree folks which aims to increase the type safety of your Swift codebase. It’s a handy tool, but once you need to wrap the same raw value twice within the same context, you will need to disambiguate your Tagged
type via some additional boilerplate. The motivation behind this macro is to eliminate that little bit of boilerplate, to make it that much more appealing to adopt this layer of type safety in your project.
Usage
The macro declaration takes 2 to 3 parameters:
public macro tagged<T>(
_ taggedType: T.Type,
_ typeName: String,
access accessLevel: AccessLevel? = nil
)
where:
taggedType
is the name of the underlying raw type – commonlyString
,UUID
orInt
,typeName
is the name of the new generated type,- and
accessLevel
is an optional access level modifier for the generated type – such aspublic
,internal
orprivate
.
Gotchas
- Swift macros that introduce arbitrary names, like this one, cannot be introduced at the global scope. Of course, you can still declare those
Tagged
types manually.