I have an associated value enum
:
enum Message {
case simple(String)
}
How do I print the name Message.simple
?
I have an associated value enum
:
enum Message {
case simple(String)
}
How do I print the name Message.simple
?
enum Message {
case simple(String)
}
let message = Message.simple("Hello")
let m = Mirror(reflecting: message).children.first!
print("\(type(of: message)).\(m.label!)(\"\(m.value)\")")
// prints: Message.simple("Hello")
A generalised version that supports cases with no associated values.
protocol HasEnumCaseName {
var caseName: String { get }
}
extension HasEnumCaseName {
var caseName: String {
Mirror(reflecting: self).children.first?.label ?? "\(self)"
}
}
// example:
enum Message: HasEnumCaseName {
case simple(String)
case noAssocValue
}
print(Message.simple("Hello").caseName) // simple
print(Message.noAssocValue.caseName) // noAssocValue
if you need the type as well – add it separately with type(of: xxx)
.
Those answers are good, but assume that you have an instance of Message
.
Do you?
Because the simplest answer to your question is
print("Message.simple")
Otherwise, without using a protocol, you can filter non-enums. subjectType
is available too.
extension String {
init?(droppingAssociatedValue enum: some Any) {
let mirror = Mirror(reflecting: `enum`)
guard mirror.displayStyle == .enum else { return nil }
self = """
\(mirror.subjectType).\
\(mirror.children.first?.label ?? "\(`enum`)")
"""
}
}
Actually, I don't...
Here's what's happening, I have messages of different types say:
enum Message {
case simple(String)
case other(String)
}
And I'm doing some unit tests like this:
//arrange
let message = "...."
//act
let parser = Parser()
let message: Message = parser.parser()
/// assert
guard case .simple(_) = message else {
XCTFail("Message is of type \(type(of: message)) when it should have been of type \("???")") // <--- Here's the "thing"
}
I have no idea if that's possible without two instances.
guard case .simple = message else {
return XCTFail(
nonMatchingEnumCaseMessage(message, exampleMatch: .simple(""))
)
}
XCTest
's standard formatting is like this, though:
extension XCTestCase {
func nonMatchingEnumCaseMessage<Enum>(
_ nonMatch: Enum,
exampleMatch: Enum
) -> String {
func caseLabel(_ instance: Enum) -> String {
Mirror(reflecting: instance).children.first?.label ?? "\(instance)"
}
return """
\(Enum.self) is case \
("\(caseLabel(nonMatch))") \
when it should have been \
("\(caseLabel(exampleMatch))")
"""
}
}