Skip to content

Commit

Permalink
Merge pull request #3 from Ryu0118/feature/allkeypath-recursively
Browse files Browse the repository at this point in the history
Add feature to recursively get KeyPath of all properties
  • Loading branch information
Ryu0118 authored Jun 8, 2023
2 parents 197d9c3 + 4740397 commit f8756f5
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 0 deletions.
40 changes: 40 additions & 0 deletions Sources/KeyPathIterable/KeyPathIterable.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,43 @@
public protocol KeyPathIterable {
static var allKeyPaths: [PartialKeyPath<Self>] { get }
static var allAnyKeyPaths: [AnyKeyPath] { get }

var allKeyPaths: [PartialKeyPath<Self>] { get }
var allAnyKeyPaths: [AnyKeyPath] { get }

var recursivelyAllKeyPaths: [PartialKeyPath<Self>] { get }
var recursivelyAllAnyKeyPaths: [AnyKeyPath] { get }
}

public extension KeyPathIterable {
static var allAnyKeyPaths: [AnyKeyPath] {
allKeyPaths.map { $0 as AnyKeyPath }
}

var allKeyPaths: [PartialKeyPath<Self>] {
Self.allKeyPaths
}

var allAnyKeyPaths: [AnyKeyPath] {
allKeyPaths.map { $0 as AnyKeyPath }
}

var recursivelyAllKeyPaths: [PartialKeyPath<Self>] {
var recursivelyKeyPaths = [PartialKeyPath<Self>]()
for keyPath in allKeyPaths {
recursivelyKeyPaths.append(keyPath)
if let anyKeyPathIterable = self[keyPath: keyPath] as? any KeyPathIterable {
for childKeyPath in anyKeyPathIterable.recursivelyAllAnyKeyPaths {
if let appendedKeyPath = keyPath.appending(path: childKeyPath) {
recursivelyKeyPaths.append(appendedKeyPath)
}
}
}
}
return recursivelyKeyPaths
}

var recursivelyAllAnyKeyPaths: [AnyKeyPath] {
recursivelyAllKeyPaths.map { $0 as AnyKeyPath }
}
}
28 changes: 28 additions & 0 deletions Tests/KeyPathIterableTests/KeyPathIterableTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,22 @@ final class KeyPathIterableTests: XCTestCase {
XCTAssertEqual(count, 0)
}

func testRecursivelyAllKeyPaths() throws {
let recursivelyAllKeyPaths = Set(NestedStruct(hoge: .init(), fuga: .init()).recursivelyAllKeyPaths)

XCTAssertEqual(
recursivelyAllKeyPaths,
[
\.hoge,
\.hoge.hoge,
\.hoge.fuga,
\.hoge.foo,
\.fuga,
\.fuga.fuga,
\.fuga.hoge
]
)
}

@KeyPathIterable
struct StructHoge {
Expand All @@ -40,8 +56,14 @@ final class KeyPathIterableTests: XCTestCase {

@KeyPathIterable
enum EnumHoge {
case c1

var hoge: Int { 1 }
var fuga: Int { 2 }

init() {
self = .c1
}
}

@KeyPathIterable
Expand All @@ -58,4 +80,10 @@ final class KeyPathIterableTests: XCTestCase {
nonisolated var hoge: Int { 1 }
var fuga = 2
}

@KeyPathIterable
struct NestedStruct {
let hoge: StructHoge
let fuga: EnumHoge
}
}

0 comments on commit f8756f5

Please sign in to comment.