-
Notifications
You must be signed in to change notification settings - Fork 82
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
While we have some ideas to take Swift 5.7 even further, we need more time to let the details bake. Till then, we can still offer a quality-of-life improvement for folks using Swift 5.7, especially those working on Advent of Code 2022! Improving Parsing's builder limits ---------------------------------- This is perhaps the most notable improvement for now. Currently, Parsing's builders limits the number of parsers allowed in a block because of how many overloads need to be maintained and generated. Using Swift 5.7's new [`buildPartialBlock`][se-0348], we can greatly improve upon this limit: | Builder | Block limit `swift(<5.7)` | Block limit `swift(>=5.7)` | | ---------------- | ------------------------- | -------------------------- | | `OneOfBuilder` | 10 | ∞ | | `ParserBuilder` | 6 | 10–∞* | \* Up to 10 non-`Void` captures in a block, plus unlimited `Void` captures. This should make working with larger builders much easier. The limit of 10 captures is arbitrary and could be expanded. If you hit it, please [let us know][discussions]! [se-0348]: https://github.com/apple/swift-evolution/blob/main/proposals/0348-buildpartialblock.md [discussions]: https://github.com/pointfreeco/swift-parsing/discussions Adding primary associated types ------------------------------- We've added primary associated types to a number of protocols: * `Parser<Input, Output>` * `ParserPrinter<Intput, Output>` * `Conversion<Input, Output>` * `PrependableCollection<Element>` This will allow you to express and constrain these protocols in a more lightweight, natural manner. Formatter parser-printer support -------------------------------- We've added support for using formatters directly in your parser printers with the `Formatted` parser-printer: ```swift let total = ParsePrint { "TOTAL: " Formatted(.currency(code: "USD")) } try total.parse("TOTAL: $42.42") // 42.42 try total.print(99.95) // "TOTAL: $99.95" ``` `Formatted` takes any of the many formatters shipping in iOS 15 and more recently. --- We have more plans for Parsing in the coming months to take even greater advantage of modern Swift features, and we hope to explore them soon!
1 parent
4094025
commit 9ed8959
Showing
12 changed files
with
9,857 additions
and
9,182 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
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
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,28 +1,59 @@ | ||
/// Declares a type that can transform an `Input` value into an `Output` value *and* transform an | ||
/// `Output` value back into an `Input` value. | ||
/// | ||
/// Useful in transforming the output of a parser-printer into some new type while preserving | ||
/// printability via ``Parser/map(_:)-18m9d``. | ||
@rethrows public protocol Conversion { | ||
// The type of values this conversion converts from. | ||
associatedtype Input | ||
#if swift(>=5.7) | ||
/// Declares a type that can transform an `Input` value into an `Output` value *and* transform an | ||
/// `Output` value back into an `Input` value. | ||
/// | ||
/// Useful in transforming the output of a parser-printer into some new type while preserving | ||
/// printability via ``Parser/map(_:)-18m9d``. | ||
@rethrows public protocol Conversion<Input, Output> { | ||
// The type of values this conversion converts from. | ||
associatedtype Input | ||
|
||
// The type of values this conversion converts to. | ||
associatedtype Output | ||
// The type of values this conversion converts to. | ||
associatedtype Output | ||
|
||
/// Attempts to transform an input into an output. | ||
/// | ||
/// See ``Conversion/apply(_:)`` for the reverse process. | ||
/// | ||
/// - Parameter input: An input value. | ||
/// - Returns: A transformed output value. | ||
func apply(_ input: Input) throws -> Output | ||
/// Attempts to transform an input into an output. | ||
/// | ||
/// See ``Conversion/apply(_:)`` for the reverse process. | ||
/// | ||
/// - Parameter input: An input value. | ||
/// - Returns: A transformed output value. | ||
func apply(_ input: Input) throws -> Output | ||
|
||
/// Attempts to transform an output back into an input. | ||
/// | ||
/// The reverse process of ``Conversion/apply(_:)``. | ||
/// Attempts to transform an output back into an input. | ||
/// | ||
/// The reverse process of ``Conversion/apply(_:)``. | ||
/// | ||
/// - Parameter output: An output value. | ||
/// - Returns: An "un"-transformed input value. | ||
func unapply(_ output: Output) throws -> Input | ||
} | ||
#else | ||
/// Declares a type that can transform an `Input` value into an `Output` value *and* transform an | ||
/// `Output` value back into an `Input` value. | ||
/// | ||
/// - Parameter output: An output value. | ||
/// - Returns: An "un"-transformed input value. | ||
func unapply(_ output: Output) throws -> Input | ||
} | ||
/// Useful in transforming the output of a parser-printer into some new type while preserving | ||
/// printability via ``Parser/map(_:)-18m9d``. | ||
@rethrows public protocol Conversion { | ||
// The type of values this conversion converts from. | ||
associatedtype Input | ||
|
||
// The type of values this conversion converts to. | ||
associatedtype Output | ||
|
||
/// Attempts to transform an input into an output. | ||
/// | ||
/// See ``Conversion/apply(_:)`` for the reverse process. | ||
/// | ||
/// - Parameter input: An input value. | ||
/// - Returns: A transformed output value. | ||
func apply(_ input: Input) throws -> Output | ||
|
||
/// Attempts to transform an output back into an input. | ||
/// | ||
/// The reverse process of ``Conversion/apply(_:)``. | ||
/// | ||
/// - Parameter output: An output value. | ||
/// - Returns: An "un"-transformed input value. | ||
func unapply(_ output: Output) throws -> Input | ||
} | ||
#endif |
File renamed without changes.
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,36 @@ | ||
#if swift(>=5.7) && (os(iOS) || os(macOS) || os(tvOS) || os(watchOS)) | ||
import Foundation | ||
|
||
@available(iOS 16, macOS 13, tvOS 16, watchOS 9, *) | ||
public struct Formatted<Style: ParseableFormatStyle & RegexComponent>: ParserPrinter | ||
where | ||
Style.Strategy.ParseInput == String, | ||
Style.Strategy.ParseOutput == Style.RegexOutput | ||
{ | ||
@usableFromInline | ||
let style: Style | ||
|
||
@inlinable | ||
public init(_ style: Style) { | ||
self.style = style | ||
} | ||
|
||
@inlinable | ||
public func parse(_ input: inout Substring) throws -> Style.Strategy.ParseOutput { | ||
guard let match = input.prefixMatch(of: self.style.regex) | ||
else { | ||
throw ParsingError.failed( | ||
summary: "failed to process \"\(Output.self)\"", | ||
at: input | ||
) | ||
} | ||
input.removeFirst(input.distance(from: input.startIndex, to: input.endIndex)) | ||
return match.output | ||
} | ||
|
||
@inlinable | ||
public func print(_ output: Style.FormatInput, into input: inout Substring) { | ||
input.prepend(contentsOf: self.style.format(output)) | ||
} | ||
} | ||
#endif |
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,23 @@ | ||
#if swift(>=5.7) && (os(iOS) || os(macOS) || os(tvOS) || os(watchOS)) | ||
import Parsing | ||
import XCTest | ||
|
||
@available(iOS 16, macOS 13, tvOS 16, watchOS 9, *) | ||
final class ParseableFormatStyleTests: XCTestCase { | ||
func testFormatted() { | ||
let p = ParsePrint { | ||
"TOTAL: " | ||
Formatted(.currency(code: "USD")) | ||
} | ||
|
||
XCTAssertEqual( | ||
try p.parse("TOTAL: $42.42"), | ||
42.42 | ||
) | ||
XCTAssertEqual( | ||
try p.print(42.42), | ||
"TOTAL: $42.42" | ||
) | ||
} | ||
} | ||
#endif |