From 0aa9050cb228eaa8d2e09be1457a1dec003fb43b Mon Sep 17 00:00:00 2001 From: Thomas Mellenthin Date: Thu, 9 Mar 2023 17:06:58 +0100 Subject: [PATCH] TypePathConvertible: add a simple type path extension (#46) --- .../Utils/TypePathConvertible.swift | 24 +++++++++++++++ .../TypePathConvertibleTests.swift | 30 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 Sources/FoundationExtensions/Utils/TypePathConvertible.swift create mode 100644 Tests/FoundationExtensionsTests/TypePathConvertibleTests.swift diff --git a/Sources/FoundationExtensions/Utils/TypePathConvertible.swift b/Sources/FoundationExtensions/Utils/TypePathConvertible.swift new file mode 100644 index 0000000..c5eba9b --- /dev/null +++ b/Sources/FoundationExtensions/Utils/TypePathConvertible.swift @@ -0,0 +1,24 @@ +// Copyright © 2023 Lautsprecher Teufel GmbH. All rights reserved. + +import Foundation + +/// Allows to turn the Type-hierarchy into a string, i.e. "`Superclass.Subclass`". +public protocol TypePathConvertible { + var typePath: String { get } +} + +extension TypePathConvertible { + public var typePath: String { + let reflectionString = String(reflecting: self) + + // Regex: "\.\([^\)]*\)" matches .("anything but a closing brace") + guard let regex = try? NSRegularExpression(pattern: "\\.\\([^\\)]*\\)", options: NSRegularExpression.Options.caseInsensitive) else { + return String(describing: self) + } + // Remove anonymous types that appear in unit testing, i.e. "A.B.C.(unknown context at $1071608c4).(unknown context at $107160918).yak" + return regex.stringByReplacingMatches(in: reflectionString, + options: [], + range: NSMakeRange(0, reflectionString.count), + withTemplate: "") + } +} diff --git a/Tests/FoundationExtensionsTests/TypePathConvertibleTests.swift b/Tests/FoundationExtensionsTests/TypePathConvertibleTests.swift new file mode 100644 index 0000000..33e9fca --- /dev/null +++ b/Tests/FoundationExtensionsTests/TypePathConvertibleTests.swift @@ -0,0 +1,30 @@ +// Copyright © 2023 Lautsprecher Teufel GmbH. All rights reserved. + +import Foundation +import FoundationExtensions +import XCTest + +class TypePathConvertibleTests: XCTestCase { + + func testTypePath() { + // given + enum A: TypePathConvertible { + enum B: TypePathConvertible { + case foo + case bar + + enum C: TypePathConvertible { + case yik + case yak + } + } + } + let sut = A.B.C.yak + + // when + let result = sut.typePath + + // then + XCTAssertEqual(result, "FoundationExtensionsTests.TypePathConvertibleTests.A.B.C.yak") + } +}