-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #6 from mkj-is/feature/resultbuilder
Swift 5.4 result builder
- Loading branch information
Showing
14 changed files
with
136 additions
and
86 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import SwiftUI | ||
|
||
extension Array: PathComponent where Element == PathComponent { | ||
public func add(to path: inout Path) { | ||
for component in self { | ||
component.add(to: &path) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import SwiftUI | ||
|
||
/// Convenience empty path component. | ||
public struct EmptySubpath: PathComponent { | ||
/// Initializes an empty path component. | ||
public init() {} | ||
|
||
public func add(to path: inout Path) {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,23 @@ | ||
import SwiftUI | ||
|
||
/// Appends components to path iterating over supplied sequence and building path for each element. | ||
public struct Loop: PathComponent { | ||
private let components: [PathComponent] | ||
public struct Loop<S: Sequence>: PathComponent { | ||
private let sequence: S | ||
private let builder: (S.Element) -> Path | ||
|
||
/// Creates path component which appends components to path | ||
/// iterating over supplied sequence and building path for each element. | ||
/// - Parameters: | ||
/// - sequence: Sequence of elements which will be used for building path components. | ||
/// - builder: PathBuilder closure receiving each element and creating path component from them. | ||
public init<S: Sequence>(sequence: S, @PathBuilder _ builder: (S.Element) -> PathComponent) { | ||
self.components = sequence.map(builder) | ||
public init(sequence: S, @PathBuilder _ builder: @escaping (S.Element) -> Path) { | ||
self.sequence = sequence | ||
self.builder = builder | ||
} | ||
|
||
public func add(to path: inout Path) { | ||
for component in components { | ||
component.add(to: &path) | ||
for element in sequence { | ||
path.addPath(builder(element)) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,8 @@ | ||
import SwiftUI | ||
|
||
public extension Path { | ||
/// Initializes path using custom attribtue path builder. | ||
init(@PathBuilder _ builder: () -> PathComponent) { | ||
self.init { path in | ||
builder().add(to: &path) | ||
} | ||
} | ||
} | ||
|
||
extension Path: PathComponent { | ||
public func add(to path: inout Path) { | ||
path.addPath(self) | ||
/// Initializes path using custom attribute path builder. | ||
init(@PathBuilder _ builder: () -> Path) { | ||
self = builder() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,29 +1,50 @@ | ||
import SwiftUI | ||
|
||
/// A custom parameter attribute that constructs paths from closures. | ||
@_functionBuilder | ||
/// A custom result builder which constructs Paths from closures. | ||
@resultBuilder | ||
public struct PathBuilder { | ||
|
||
/// Enables support for 'for..in' loops by combining the | ||
/// results of all iterations into a single result. | ||
public static func buildArray(_ components: [PathComponent]) -> PathComponent { | ||
components | ||
} | ||
|
||
/// Required by every result builder to build combined results from | ||
/// statement blocks. | ||
public static func buildBlock(_ components: PathComponent...) -> PathComponent { | ||
return Subpath(path: Path { path in | ||
for component in components { | ||
component.add(to: &path) | ||
} | ||
}) | ||
components | ||
} | ||
|
||
/// Provides support for “if” statements in multi-statement closures, producing an optional path component that is added only when the condition evaluates to true. | ||
public static func buildIf(_ component: PathComponent?) -> PathComponent { | ||
return component.flatMap { component in | ||
Subpath { component } | ||
} ?? Subpath() | ||
/// Enables support for `if` statements that do not have an `else`. | ||
public static func buildOptional(_ component: PathComponent?) -> PathComponent { | ||
component ?? EmptySubpath() | ||
} | ||
|
||
/// With buildEither(second:), enables support for 'if-else' and 'switch' | ||
/// statements by folding conditional results into a single result. | ||
public static func buildEither(first: PathComponent) -> PathComponent { | ||
return first | ||
first | ||
} | ||
|
||
/// With buildEither(first:), enables support for 'if-else' and 'switch' | ||
/// statements by folding conditional results into a single result. | ||
public static func buildEither(second: PathComponent) -> PathComponent { | ||
return second | ||
second | ||
} | ||
|
||
/// This will be called on the partial result of an 'if | ||
/// #available' block to allow the result builder to erase type | ||
/// information. | ||
public static func buildLimitedAvailability(_ component: PathComponent) -> PathComponent { | ||
component | ||
} | ||
|
||
/// This will be called on the partial result from the outermost | ||
/// block statement to produce the final returned result Path. | ||
public static func buildFinalResult(_ component: PathComponent) -> Path { | ||
Path { path in | ||
component.add(to: &path) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters