@Bijection is a Swift macro that generates an initializer from a switch-case mapping of an enum’s cases to set of corresponding values. It is useful for generating roundtripping logic for things like binary encodings and string representations, in situations where relying on native raw value-backed enums is insufficient, experiences poor performance due to lack of inlining, or would interfere with other compiler features, such as synthesized Comparable.
The @Bijection library requires Swift 6.1 or later.
| Platform | Status | 
|---|---|
| 🐧 Linux | |
| 🍏 Darwin | 
Generate a plain, unlabeled initializer:
enum Enum: CaseIterable, Equatable {
    case a, b, c
    @Bijection
    var value: Unicode.Scalar {
        switch self {
        case .a: "a"
        case .b: "b"
        case .c: "c"
        }
    }
}
/* --- EXPANDS TO --- */
extension Enum {
    init?(_ $value: borrowing Unicode.Scalar) {
        switch $value {
        case "a":
            self = .a
        case "b":
            self = .b
        case "c":
            self = .c
        default:
            return nil
        }
    }
}Generate an initializer with a custom argument label:
extension Enum {
    @Bijection(label: "index")
    var index: Int {
        switch self {
        case .a: 1
        case .b: 2
        case .c: 3
        }
    }
}
/* --- EXPANDS TO --- */
extension Enum {
    init?(index $value: borrowing Int) {
        switch $value {
        case 1:
            self = .a
        case 2:
            self = .b
        case 3:
            self = .c
        default:
            return nil
        }
    }
}Generate an initializer from a getter in a property with multiple accessors:
extension Enum: LosslessStringConvertible {
    @Bijection
    var description: String {
        get {
            switch self {
            case .a: "A"
            case .b: "B"
            case .c: "C"
            }
        }
        set(value) {
            if let value: Self = .init(value) {
                self = value
            }
        }
    }
}
/* --- EXPANDS TO --- */
extension Enum {
    init?(_ $value: borrowing String) {
        switch $value {
        case "A":
            self = .a
        case "B":
            self = .b
        case "C":
            self = .c
        default:
            return nil
        }
    }
}The @Bijection macro will mirror the access control (and other modifiers, such as nonisolated) of the property it is applied to.
It will also copy the following attributes, if present:
- @available
- @backDeployed
- @inlinable
- @inline
- @usableFromInline