Skip to content

UniquelyTypedID Swift Macro. Let the compiler confirm you're passing the right kind of ID

License

Notifications You must be signed in to change notification settings

DanielSincere/UniquelyTypedID

Repository files navigation

UniquelyTypedID Swift Macro

When passing around strings or integers as IDs, the compiler doesn't tell you if you pass a person ID where a blog post ID. Now with the UniquelyTypedID, the compiler will not let you pass the ID of a different model.

And with the power of ExpressibleByStringLiteral and ExpressibleByIntegerLiteral, very little code will need to change.

I've used this approach for typesafety of record IDs in my own projects, usually by manually copy-pasting. Now with Swift Macros in Swift 5.9, it's going to be so much easier.

Installation

In Package.swift, add the package to your dependencies.

.package(url: "https://github.com/FullQueueDeveloper/UniquelyTypedID.git", from: "1.0.0"),

And add "UniquelyTypedID" to the list of your target's dependencies.

When prompted by Xcode, trust the macro.

Usage

If you had a integer ID

struct BlogPost {
  let id: Int
  let text: String
}

then you can use this macro instead.

struct BlogPost {
  @UniquelyTypedId(Int.self) let id: ID
  let text: String
}

Where ID is the name you desire for your ID type. I tend to use simply ID, so that I can easily reference the type with BlogPost.ID

Features & supported types

Currently, Int, String, and UUID are supported. The macro defaults to UUID if no type is specified.

All generated IDs are Hashable.

All generated IDs are Codable, and they encode as single value containers, for maximum compatibility when upgrading from plain integer or string IDs.

Strings

String ID types generated by UniquelyTypedId are expressible by string literal. This makes hardcoded data entry easier.

struct Vegetable {
  @UniquelyTypedId(String.self) let scientificName: ScientificName
  let name: String
}

let chili = Vegetable(scientificName: "Capsicum annuum", name: "Chili")

And if we encode this chili to JSON we see

{
  "name" : "Chili",
  "scientificName" : "Capsicum annuum"
}

Integers

Integer ID types generated by UniquelyTypedId are expressible by string literal. This makes hardcoded data entry easier.

For example

struct Aubergine: Codable {
  @UniquelyTypedID(Int.self) let id: ID
  let name: String
}

let aubergineID: Aubergine.ID = 3
let aubergine = Aubergine(id: 9, name: "Fairy Tale")

Swift macros?

Introduced at WWDC '23, requiring Swift 5.9

License

BSD-3-Clause

About

UniquelyTypedID Swift Macro. Let the compiler confirm you're passing the right kind of ID

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages