Skip to content

idolize/enum-names-macro

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

EnumNames

A Swift macro that generates a convenient enumName method for enum types, returning the case name as a string with optional associated values.

Installation

Add this package to your project using Swift Package Manager. In Xcode, go to File > Add Package Dependencies and enter:

https://github.com/idolize/enum-names-macro.git

Or add it to your Package.swift:

dependencies: [
    .package(url: "https://github.com/idolize/enum-names-macro.git", from: "1.0.1")
]

Usage

Import the module and apply the @NamedEnum macro to your enum:

import EnumNames

@NamedEnum
enum NetworkError {
    case timeout
    case invalidURL(String)
    case serverError(code: Int, message: String)
}

This generates an enumName method that returns the case name as a string:

let error1 = NetworkError.timeout
let error2 = NetworkError.invalidURL("https://example.com")
let error3 = NetworkError.serverError(code: 404, message: "Not Found")

// Without values (default)
print(error1.enumName()) // ".timeout"
print(error2.enumName()) // ".invalidURL"
print(error3.enumName()) // ".serverError"

// With all associated values included
print(error2.enumName(includeValues: .all)) // ".invalidURL(\"https://example.com\")"
print(error3.enumName(includeValues: .all)) // ".serverError(404, \"Not Found\")"

// With only enum-named values included (useful for nested enums)
print(error2.enumName(includeValues: .enumNamesOnly)) // ".invalidURL" (string isn't an enum)
print(error3.enumName(includeValues: .enumNamesOnly)) // ".serverError" (numbers aren't enums)

Features

  • ✅ Works with simple enum cases (no associated values)
  • ✅ Works with enum cases that have associated values
  • ✅ Optional includeValues parameter to control output format
  • ✅ Handles multiple associated values
  • ✅ Preserves parameter labels in the output
  • ✅ Automatic protocol conformance for polymorphic usage
  • ✅ Zero runtime dependencies

Protocol Conformance

Enums with the @NamedEnum macro automatically conform to the EnumNameProviding protocol, allowing for polymorphic usage:

@NamedEnum
enum UserAction {
    case login
    case logout
}

@NamedEnum  
enum NetworkError {
    case timeout
    case serverError(Int)
}

// Use different enum types polymorphically
let actions: [EnumNameProviding] = [
    UserAction.login,
    NetworkError.serverError(500)
]

for action in actions {
    print(action.enumName(includeValues: .all))
}
// Output:
// .login
// .serverError(500)

Generated Code

The macro generates:

  1. An enumName method with this signature:

    func enumName(includeValues: EnumNameIncludeValues = .none) -> String
  2. An extension that adds EnumNameProviding protocol conformance:

    extension YourEnum: EnumNameProviding {
    }

The includeValues parameter controls what gets included:

  • .none (default): Returns just the case name like ".caseName"
  • .all: Includes all associated values like ".caseName(value1, value2)"
  • .enumNamesOnly: Only includes associated values that conform to EnumNameProviding (useful for nested enums)

Nested Enum Example

@NamedEnum
enum UserAction {
    case login(String)
    case logout
}

@NamedEnum
enum AppEvent {
    case userAction(UserAction)
    case networkRequest(String, Int)
}

let event = AppEvent.userAction(.login("username")
print(event.enumName(includeValues: .none))             // ".userAction"
print(event.enumName(includeValues: .enumNamesOnly))    // ".userAction(.login)"
print(event.enumName(includeValues: .all))              // ".userAction(.login(\"username\"))"

let networkEvent = AppEvent.networkRequest("api", 443)
print(networkEvent.enumName(includeValues: .none))          // ".networkRequest"
print(networkEvent.enumName(includeValues: .enumNamesOnly)) // ".networkRequest"
print(networkEvent.enumName(includeValues: .all))           // ".networkRequest(api, 443)"

Requirements

  • Swift 5.9+
  • Xcode 15.0+

License

This project is available under the MIT license.