···66//
7788import Foundation
99-import IssueReporting
1091110public struct File: FileTreeReader, Sendable {
1211 let fileName: StaticString
···8786 }
88878988 public func write(_ data: [FileContent<Data>], to url: URL) throws {
9090- guard writingToEmptyDirectory
9191- else {
9292- reportIssue("""
9393- Writing an array of files to a directory that may already have contents currently unsupported.
9494-9595- This is because of the circumstance where a file exists in the directory, but not in the array
9696- It is difficult to determine if the file should be deleted, or if it exists outside of the purview of the `Files` block and should be left alone.
9797-9898- The semantics of Many may need to be tweaked to make this determination more clear.
9999-100100- To allow writing to the directory, use:
101101-102102- ```
103103- $writingToEmptyDirectory.withValue(true) {
104104- Files(withExtension: .text).write([Data(), Data(), Data()]))
105105- }
106106- ```
107107-108108- which will naively write all the contents to the directory, and not delete anything that is already there.
109109- """)
110110- return
111111- }
8989+// guard writingToEmptyDirectory
9090+// else {
9191+// reportIssue("""
9292+// Writing an array of files to a directory that may already have contents currently unsupported.
9393+//
9494+// This is because of the circumstance where a file exists in the directory, but not in the array
9595+// It is difficult to determine if the file should be deleted, or if it exists outside of the purview of the `Files` block and should be left alone.
9696+//
9797+// The semantics of Many may need to be tweaked to make this determination more clear.
9898+//
9999+// To allow writing to the directory, use:
100100+//
101101+// ```
102102+// $writingToEmptyDirectory.withValue(true) {
103103+// Files(withExtension: .text).write([Data(), Data(), Data()]))
104104+// }
105105+// ```
106106+//
107107+// which will naively write all the contents to the directory, and not delete anything that is already there.
108108+// """)
109109+// return
110110+// }
112111113112 for fileContent in data {
114113
···11+import Foundation
22+33+extension Conversion where Self == Conversions.FixedWidthIntegerToBinaryFloatingPoint<Int, Double> {
44+ /// A conversion from an `Int` to a `Double`.
55+ ///
66+ /// This conversion can be used to transform a ``ParserPrinter``'s integer output into a double
77+ /// output:
88+ ///
99+ /// ```swift
1010+ /// Digits().map(.double).parse("123") // ✅ 123.0
1111+ ///
1212+ /// Digits().map(.double).parse("123.0") // ❌
1313+ /// // error: unexpected input
1414+ /// // --> input:1:4
1515+ /// // 1 | 123.0
1616+ /// // | ^ expected end of input
1717+ /// ```
1818+ @inlinable
1919+ public static var double: Self { .init() }
2020+}
2121+2222+extension Conversion where Output == Int {
2323+ /// Transforms this conversion to `Int` into a conversion to `Double`.
2424+ ///
2525+ /// A fluent version of ``Conversion/double-swift.type.property``. Equivalent to calling
2626+ /// ``map(_:)`` with ``Conversion/double-swift.type.property``:
2727+ ///
2828+ /// ```swift
2929+ /// intConversion.double
3030+ /// // =
3131+ /// intConversion.map(.double)
3232+ /// ```
3333+ @inlinable
3434+ public var double:
3535+ Conversions.Map<
3636+ Self, Conversions.FixedWidthIntegerToBinaryFloatingPoint<Int, Double>
3737+ >
3838+ { self.map(.double) }
3939+}
4040+4141+extension Conversions {
4242+ /// A conversion from an `Int` to a `Double`.
4343+ ///
4444+ /// You will not typically need to interact with this type directly. Instead you will usually use
4545+ /// the ``Conversion/double-swift.type.property`` operation, which constructs this type.
4646+ public struct FixedWidthIntegerToBinaryFloatingPoint<
4747+ Input: FixedWidthInteger, Output: BinaryFloatingPoint
4848+ >: Conversion {
4949+ @usableFromInline
5050+ init() {}
5151+5252+ @inlinable
5353+ public func apply(_ input: Input) -> Output {
5454+ .init(input)
5555+ }
5656+5757+ @inlinable
5858+ public func unapply(_ output: Output) -> Input {
5959+ .init(output)
6060+ }
6161+ }
6262+}
···11+extension Conversion {
22+ /// A conversion that invokes the given apply and unapply functions.
33+ ///
44+ /// Useful for experimenting with conversions in a lightweight manner, without the ceremony of
55+ /// defining a dedicated type.
66+ ///
77+ /// ```swift
88+ /// struct Amount {
99+ /// var cents: Int
1010+ /// }
1111+ ///
1212+ /// let amount = Parse(
1313+ /// .convert(
1414+ /// apply: { dollars, cents in Amount(cents: dollars * 100 + cents) },
1515+ /// unapply: { amount in amount.cents.quotientAndRemainder(dividingBy: 100) }
1616+ /// )
1717+ /// ) {
1818+ /// Digits()
1919+ /// "."
2020+ /// Digits(2)
2121+ /// }
2222+ /// ```
2323+ ///
2424+ /// If performance is a concern, you should define a custom type that conforms to ``Conversion``
2525+ /// instead, which avoids the overhead of escaping closures, gives the compiler the ability to
2626+ /// better optimize, and puts your in a better position to test the conversion.
2727+ ///
2828+ /// ```swift
2929+ /// struct AmountConversion: Conversion {
3030+ /// func apply(_ dollarsAndCents: (Int, Int)) -> Amount {
3131+ /// return Amount(cents: dollarsAndCents.0 * 100 + dollarsAndCents.1)
3232+ /// }
3333+ ///
3434+ /// func unapply(_ amount: Amount) -> (Int, Int) {
3535+ /// amount.cents.quotientAndRemainder(dividingBy: 100)
3636+ /// }
3737+ /// }
3838+ ///
3939+ /// let amount = Parse(AmountConversion()) {
4040+ /// Digits()
4141+ /// "."
4242+ /// Digits(2)
4343+ /// }
4444+ /// ```
4545+ ///
4646+ /// - Parameters:
4747+ /// - apply: A closure that attempts to convert an input into an output. `apply` is executed
4848+ /// each time the ``apply(_:)`` method is called on the resulting conversion. If the closure
4949+ /// returns `nil`, an error is thrown. Otherwise, the value is unwrapped.
5050+ /// - unapply: A closure that attempts to convert an output into an input. `unapply` is executed
5151+ /// each time the ``unapply(_:)`` method is called on the resulting conversion. If the closure
5252+ /// returns `nil`, an error is thrown. Otherwise, the value is unwrapped.
5353+ /// - Returns: A conversion that invokes the given apply and unapply functions.
5454+ @inlinable
5555+ public static func convert<Input, Output>(
5656+ apply: @escaping @Sendable (Input) -> Output?,
5757+ unapply: @escaping @Sendable (Output) -> Input?
5858+ ) -> Self where Self == AnyConversion<Input, Output> {
5959+ .init(apply: apply, unapply: unapply)
6060+ }
6161+}
6262+6363+/// A type-erased ``Conversion``.
6464+///
6565+/// This conversion forwards its ``apply(_:)`` and ``unapply(_:)`` methods to an arbitrary
6666+/// underlying conversion having the same `Input` and `Output` types, hiding the specifics of the
6767+/// underlying ``Conversion``.
6868+///
6969+/// Use `AnyConversion` to wrap a conversion whose type has details you don't want to expose across
7070+/// API boundaries, such as different modules. When you use type erasure this way, you can change
7171+/// the underlying conversion over time without affecting existing clients.
7272+///
7373+/// `AnyConversion` can also be useful for experimenting with ad hoc conversions in a lightweight
7474+/// manner. One can avoid the upfront ceremony of defining a whole new type and instead create a
7575+/// "conformance" inline by specifying the `apply` and `unapply` functions directly
7676+///
7777+/// ```swift
7878+/// Prefix { $0.isNumber }
7979+/// .map(
8080+/// AnyConversion(
8181+/// apply: { Int(String($0)) },
8282+/// unapply: { String($0)[...] {
8383+/// )
8484+/// )
8585+///
8686+/// // vs.
8787+///
8888+/// struct SubstringToInt: Conversion {
8989+/// func apply(_ input: Substring) throws -> Int {
9090+/// guard let int = Int(String(input)) else {
9191+/// struct ConvertingError: Error {}
9292+/// throw ConvertingError()
9393+/// }
9494+/// return int
9595+/// }
9696+///
9797+/// func unapply(_ output: Int) -> Substring {
9898+/// String(output)[...]
9999+/// }
100100+/// }
101101+///
102102+/// Prefix { $0.isNumber }
103103+/// .map(SubstringToInt())
104104+/// ```
105105+///
106106+/// If performance is a consideration of your parser-printer, you should avoid `AnyConversion` and
107107+/// instead create custom types that conform to the ``Conversion`` protocol.
108108+public struct AnyConversion<Input, Output>: Conversion {
109109+ @usableFromInline
110110+ let _apply: @Sendable (Input) throws -> Output
111111+112112+ @usableFromInline
113113+ let _unapply: @Sendable (Output) throws -> Input
114114+115115+ /// Creates a type-erasing conversion to wrap the given conversion.
116116+ ///
117117+ /// - Parameter conversion: A conversion to wrap with a type eraser.
118118+ @inlinable
119119+ public init<C: Conversion>(_ conversion: C) where C.Input == Input, C.Output == Output {
120120+ self._apply = conversion.apply
121121+ self._unapply = conversion.unapply
122122+ }
123123+124124+ /// Creates a conversion that wraps the given closures in its ``apply(_:)`` and ``unapply(_:)``
125125+ /// methods
126126+ ///
127127+ /// - Parameters:
128128+ /// - apply: A closure that attempts to convert an input into an output. `apply` is executed
129129+ /// each time the ``apply(_:)`` method is called on the resulting conversion
130130+ /// - unapply: A closure that attempts to convert an output into an input. `unapply` is executed
131131+ /// each time the ``unapply(_:)`` method is called on the resulting conversion.
132132+ @inlinable
133133+ public init(
134134+ apply: @escaping @Sendable (Input) throws -> Output,
135135+ unapply: @escaping @Sendable (Output) throws -> Input
136136+ ) {
137137+ self._apply = apply
138138+ self._unapply = unapply
139139+ }
140140+141141+ /// Creates a conversion that wraps the given closures in its ``apply(_:)`` and ``unapply(_:)``
142142+ /// methods, throwing an error when `nil` is returned.
143143+ ///
144144+ /// - Parameters:
145145+ /// - apply: A closure that attempts to convert an input into an output. `apply` is executed
146146+ /// each time the ``apply(_:)`` method is called on the resulting conversion. If the closure
147147+ /// returns `nil`, an error is thrown. Otherwise, the value is unwrapped.
148148+ /// - unapply: A closure that attempts to convert an output into an input. `unapply` is executed
149149+ /// each time the ``unapply(_:)`` method is called on the resulting conversion. If the closure
150150+ /// returns `nil`, an error is thrown. Otherwise, the value is unwrapped.
151151+ @inlinable
152152+ public init(
153153+ apply: @escaping @Sendable (Input) -> Output?,
154154+ unapply: @escaping @Sendable (Output) -> Input?
155155+ ) {
156156+ self._apply = {
157157+ guard let value = apply($0)
158158+ else { throw ConvertingError() }
159159+ return value
160160+ }
161161+ self._unapply = {
162162+ guard let value = unapply($0)
163163+ else { throw ConvertingError() }
164164+ return value
165165+ }
166166+ }
167167+168168+ @inlinable
169169+ public func apply(_ input: Input) throws -> Output {
170170+ try self._apply(input)
171171+ }
172172+173173+ @inlinable
174174+ public func unapply(_ output: Output) throws -> Input {
175175+ try self._unapply(output)
176176+ }
177177+}
···11+/// Declares a type that can asynchronously transform an `Input` value into an `Output` value *and* transform an
22+/// `Output` value back into an `Input` value.
33+///
44+/// Useful in bidirectionally tranforming types, like when writing something to the disk.
55+/// printability via ``Parser/map(_:)-18m9d``.
66+@rethrows public protocol Conversion<Input, Output>: Sendable {
77+ // The type of values this conversion converts from.
88+ associatedtype Input
99+1010+ // The type of values this conversion converts to.
1111+ associatedtype Output
1212+1313+ associatedtype Body
1414+1515+ /// Attempts to asynchronously transform an input into an output.
1616+ ///
1717+ /// See ``Conversion/apply(_:)`` for the reverse process.
1818+ ///
1919+ /// - Parameter input: An input value.
2020+ /// - Returns: A transformed output value.
2121+ @Sendable func apply(_ input: Input) throws -> Output
2222+2323+ /// Attempts to asynchronously transform an output back into an input.
2424+ ///
2525+ /// The reverse process of ``Conversion/apply(_:)``.
2626+ ///
2727+ /// - Parameter output: An output value.
2828+ /// - Returns: An "un"-transformed input value.
2929+ @Sendable func unapply(_ input: Output) throws -> Input
3030+3131+ @ConversionBuilder
3232+ var body: Body { get }
3333+}
3434+3535+extension Conversion
3636+where Body: Conversion, Body.Input == Input, Body.Output == Output {
3737+ public func apply(_ input: Input) throws -> Output {
3838+ try self.body.apply(input)
3939+ }
4040+4141+ public func unapply(_ output: Output) throws -> Input {
4242+ try self.body.unapply(output)
4343+ }
4444+}
4545+4646+extension Conversion where Body == Never {
4747+ public var body: Body {
4848+ return fatalError("Body of \(Self.self) should never be called")
4949+ }
5050+}
5151+5252+/// A namespace for types that serve as conversions.
5353+///
5454+/// The various operators defined as extensions on ``Conversion`` implement their functionality as
5555+/// classes or structures that extend this enumeration. For example, the ``Conversion/map(_:)``
5656+/// operator returns a ``Map`` conversion.
5757+public enum Conversions {}
···11+extension Conversion {
22+ /// Returns a conversion that transforms the output of this conversion with a given downstream
33+ /// conversion.
44+ ///
55+ /// When provided with a conversion from this conversion's output type to some new output type,
66+ /// this method can return a new conversion from this conversion's input type to the given
77+ /// conversion's output type by calling their ``apply(_:)`` functions and ``unapply(_:)``
88+ /// functions one after the other.
99+ ///
1010+ /// This method is similar to `Sequence.map`, `Optional.map`, and `Result.map` in the Swift
1111+ /// standard library, as well as `Publisher.map` in the Combine framework. This method is also
1212+ /// similar to the `map` functions on ``Parser`` and ``ParserPrinter``, especially
1313+ /// ``Parser/map(_:)-18m9d``, which takes a conversion.
1414+ ///
1515+ /// - Parameter downstream: A conversion that transforms the output of this conversion into some
1616+ /// new output.
1717+ /// - Returns: A conversion that transforms the input of this conversion into the output of the
1818+ /// given conversion.
1919+ @inlinable
2020+ public func map<C>(_ downstream: C) -> Conversions.Map<Self, C> {
2121+ .init(upstream: self, downstream: downstream)
2222+ }
2323+}
2424+2525+extension Conversions {
2626+ /// A conversion that composes two conversions together by composing their
2727+ /// ``Conversion/apply(_:)`` functions and ``Conversion/unapply(_:)`` functions together.
2828+ ///
2929+ /// You will not typically need to interact with this type directly. Instead you will usually use
3030+ /// the ``Conversion/map(_:)`` operation, which constructs this type.
3131+ public struct Map<Upstream: Conversion, Downstream: Conversion>: Conversion
3232+ where Upstream.Output == Downstream.Input {
3333+ public let upstream: Upstream
3434+ public let downstream: Downstream
3535+3636+ @usableFromInline
3737+ init(upstream: Upstream, downstream: Downstream) {
3838+ self.upstream = upstream
3939+ self.downstream = downstream
4040+ }
4141+4242+ @inlinable
4343+ @inline(__always)
4444+ public func apply(_ input: Upstream.Input) rethrows -> Downstream.Output {
4545+ try self.downstream.apply(self.upstream.apply(input))
4646+ }
4747+4848+ @inlinable
4949+ @inline(__always)
5050+ public func unapply(_ output: Downstream.Output) rethrows -> Upstream.Input {
5151+ try self.upstream.unapply(self.downstream.unapply(output))
5252+ }
5353+ }
5454+}
···11+import Foundation
22+33+extension Conversion where Self == Conversions.BytesToData<Substring.UTF8View> {
44+ /// A conversion from `Substring.UTF8View` to `Data`.
55+ @inlinable
66+ public static var data: Self { .init() }
77+}
88+99+extension Conversion where Output == Substring.UTF8View {
1010+ /// Transforms this conversion to `Substring.UTF8View` into a conversion to `Data`.
1111+ ///
1212+ /// A fluent version of ``Conversion/data-swift.type.property-8z7qz``.
1313+ @inlinable
1414+ public var data: Conversions.Map<Self, Conversions.BytesToData<Output>> {
1515+ self.map(.data)
1616+ }
1717+}
1818+1919+extension Conversion where Self == Conversions.BytesToData<ArraySlice<UInt8>> {
2020+ /// A conversion from `ArraySlice<UInt8>` to `Data`.
2121+ @inlinable
2222+ public static var data: Self { .init() }
2323+}
2424+2525+extension Conversion where Output == ArraySlice<UInt8> {
2626+ /// Transforms this conversion to `ArraySlice<UInt8>` into a conversion to `Data`.
2727+ ///
2828+ /// A fluent version of ``Conversion/data-swift.type.property-7g9sj``.
2929+ @inlinable
3030+ public var data: Conversions.Map<Self, Conversions.BytesToData<Output>> {
3131+ self.map(.data)
3232+ }
3333+}
3434+3535+extension Conversions {
3636+ /// A conversion from a ``PrependableCollection`` of UTF-8 bytes to `Data`.
3737+ ///
3838+ /// You will not typically need to interact with this type directly. Instead you will usually use
3939+ /// the ``Conversion/data-swift.type.property-8z7qz`` and
4040+ /// ``Conversion/data-swift.type.property-7g9sj`` operations, which constructs this type.
4141+ public struct BytesToData<Input: PrependableCollection>: Conversion where Input.Element == UInt8 {
4242+ @usableFromInline
4343+ init() {}
4444+4545+ @inlinable
4646+ public func apply(_ input: Input) -> Data {
4747+ .init(input)
4848+ }
4949+5050+ @inlinable
5151+ public func unapply(_ output: Data) -> Input {
5252+ .init(output)
5353+ }
5454+ }
5555+}
···11+extension Conversion where Self == Conversions.BinaryFloatingPointToFixedWidthInteger<Double, Int> {
22+ /// A conversion from a `Double` to an `Int`.
33+ ///
44+ /// This conversion can be used to transform a ``ParserPrinter``'s double output into an integer
55+ /// output, rounding toward zero.
66+ ///
77+ /// ```swift
88+ /// Double.parser().map(.int).parse("123.45") // 123
99+ /// ```
1010+ @inlinable
1111+ public static var int: Self { .init() }
1212+}
1313+1414+extension Conversion where Output == Double {
1515+ /// Transforms this conversion to `Double` into a conversion to `Int`.
1616+ ///
1717+ /// A fluent version of ``Conversion/int-swift.type.property``. Equivalent to calling ``map(_:)``
1818+ /// with ``Conversion/int-swift.type.property``:
1919+ ///
2020+ /// ```swift
2121+ /// doubleConversion.int
2222+ /// // =
2323+ /// doubleConversion.map(.int)
2424+ /// ```
2525+ @inlinable
2626+ public var int:
2727+ Conversions.Map<
2828+ Self, Conversions.BinaryFloatingPointToFixedWidthInteger<Double, Int>
2929+ >
3030+ { self.map(.int) }
3131+}
3232+3333+extension Conversions {
3434+ /// A conversion from a `Double` to an `Int`.
3535+ ///
3636+ /// You will not typically need to interact with this type directly. Instead you will usually use
3737+ /// the ``Conversion/int-swift.type.property`` operation, which constructs this type.
3838+ public struct BinaryFloatingPointToFixedWidthInteger<
3939+ Input: BinaryFloatingPoint, Output: FixedWidthInteger
4040+ >: Conversion {
4141+ @usableFromInline
4242+ init() {}
4343+4444+ @inlinable
4545+ public func apply(_ input: Input) -> Output {
4646+ .init(input)
4747+ }
4848+4949+ @inlinable
5050+ public func unapply(_ output: Output) -> Input {
5151+ .init(output)
5252+ }
5353+ }
5454+}
···11+import Foundation
22+33+extension Conversion {
44+ /// A conversion from `Data` to the given codable type.
55+ ///
66+ /// See ``json(_:decoder:encoder:)-swift.method`` for a fluent version of this interface that
77+ /// transforms an existing conversion.
88+ ///
99+ /// - Parameters:
1010+ /// - type: A type that conforms to `Codable`.
1111+ /// - decoder: An optional JSON decoder that handles decoding.
1212+ /// - encoder: An optional JSON encoder that handles encoding.
1313+ /// - Returns: A conversion from `Data` to the given codable type.
1414+ @inlinable
1515+ public static func json<Value>(
1616+ _ type: Value.Type,
1717+ decoder: JSONDecoder = .init(),
1818+ encoder: JSONEncoder = .init()
1919+ ) -> Self where Self == Conversions.JSON<Value> {
2020+ .init(type, decoder: decoder, encoder: encoder)
2121+ }
2222+2323+ /// Transforms this conversion to `Data` into a conversion to the given codable type.
2424+ ///
2525+ /// A fluent version of ``Conversion/json(_:decoder:encoder:)-swift.type.method``. Equivalent to
2626+ /// calling ``map(_:)`` with ``Conversion/json(_:decoder:encoder:)-swift.type.method``:
2727+ ///
2828+ /// ```swift
2929+ /// Parse(.data.json(User.self))
3030+ /// // =
3131+ /// Parse(.data.map(.json(User.self)))
3232+ /// ```
3333+ ///
3434+ /// - Parameters:
3535+ /// - type: A type that conforms to `Codable`.
3636+ /// - decoder: An optional JSON decoder that handles decoding.
3737+ /// - encoder: An optional JSON encoder that handles encoding.
3838+ /// - Returns: A conversion from this conversion's input to the given codable type.
3939+ @inlinable
4040+ public func json<Value>(
4141+ _ type: Value.Type,
4242+ decoder: JSONDecoder = .init(),
4343+ encoder: JSONEncoder = .init()
4444+ ) -> Conversions.Map<Self, Conversions.JSON<Value>> {
4545+ self.map(.json(type, decoder: decoder, encoder: encoder))
4646+ }
4747+}
4848+4949+extension Conversions {
5050+ /// A conversion from `Data` to some codable type.
5151+ ///
5252+ /// You will not typically need to interact with this type directly. Instead you will usually use
5353+ /// the ``Conversion/json(_:decoder:encoder:)-swift.type.method`` operation, which constructs this
5454+ /// type.
5555+ public struct JSON<Value: Codable>: Conversion {
5656+ @usableFromInline
5757+ let decoder: JSONDecoder
5858+5959+ @usableFromInline
6060+ let encoder: JSONEncoder
6161+6262+ @inlinable
6363+ public init(
6464+ _ type: Value.Type,
6565+ decoder: JSONDecoder = .init(),
6666+ encoder: JSONEncoder = .init()
6767+ ) {
6868+ self.decoder = decoder
6969+ self.encoder = encoder
7070+ }
7171+7272+ @inlinable
7373+ public func apply(_ input: Data) throws -> Value {
7474+ try self.decoder.decode(Value.self, from: input)
7575+ }
7676+7777+ @inlinable
7878+ public func unapply(_ output: Value) throws -> Data {
7979+ try self.encoder.encode(output)
8080+ }
8181+ }
8282+}
···11+extension Conversion {
22+ /// A conversion from a string to a lossless string-convertible type.
33+ ///
44+ /// See ``lossless(_:)-swift.method`` for a fluent version of this interface that transforms an
55+ /// existing conversion.
66+ ///
77+ /// - Parameter type: A type that conforms to `LosslessStringConvertible`.
88+ /// - Returns: A conversion from a string to the given type.
99+ @inlinable
1010+ public static func lossless<NewOutput>(
1111+ _ type: NewOutput.Type
1212+ ) -> Self where Self == Conversions.FromLosslessString<NewOutput> {
1313+ .init()
1414+ }
1515+1616+ /// Transforms this conversion to a string into a conversion to the given lossless
1717+ /// string-convertible type.
1818+ ///
1919+ /// A fluent version of ``Conversion/lossless(_:)-swift.type.method``. Equivalent to calling
2020+ /// ``map(_:)`` with ``Conversion/lossless(_:)-swift.type.method``:
2121+ ///
2222+ /// ```swift
2323+ /// stringConversion.lossless(NewOutput.self)
2424+ /// // =
2525+ /// stringConversion.map(.lossless(NewOutput.self))
2626+ /// ```
2727+ ///
2828+ /// - Parameter type: A type that conforms to `LosslessStringConvertible`.
2929+ /// - Returns: A conversion from a string to the given type.
3030+ @inlinable
3131+ public func lossless<NewOutput>(
3232+ _ type: NewOutput.Type
3333+ ) -> Conversions.Map<Self, Conversions.FromLosslessString<NewOutput>> {
3434+ self.map(.lossless(NewOutput.self))
3535+ }
3636+}
3737+3838+extension Conversions {
3939+ /// A conversion from a string to a lossless string-convertible type.
4040+ ///
4141+ /// You will not typically need to interact with this type directly. Instead you will usually use
4242+ /// the ``Conversion/lossless(_:)-swift.type.method`` operation, which constructs this type.
4343+ public struct FromLosslessString<Output: LosslessStringConvertible>: Conversion {
4444+ @usableFromInline
4545+ init() {}
4646+4747+ @inlinable
4848+ public func apply(_ input: String) throws -> Output {
4949+ guard let output = Output(input)
5050+ else {
5151+ throw ConvertingError(
5252+ """
5353+ lossless: Failed to convert \(input.debugDescription) to \(Output.self).
5454+ """
5555+ )
5656+ }
5757+5858+ return output
5959+ }
6060+6161+ @inlinable
6262+ public func unapply(_ output: Output) -> String {
6363+ output.description
6464+ }
6565+ }
6666+}
···11+extension Conversion {
22+ /// A conversion from a tuple of values into a struct and a struct into a tuple of values, using a
33+ /// memberwise initializer.
44+ ///
55+ /// Useful for transforming the output of a ``ParserPrinter`` into a struct.
66+ ///
77+ /// For example, given a simple `Coordinate` struct, we can build a parser-printer using
88+ /// ``memberwise(_:)``:
99+ ///
1010+ /// ```swift
1111+ /// struct Coordinate {
1212+ /// var x: Double
1313+ /// var y: Double
1414+ /// }
1515+ ///
1616+ /// let coord = ParsePrint(.memberwise(Coordinate.init(x:y:))) {
1717+ /// "("
1818+ /// Double.parser()
1919+ /// ","
2020+ /// Double.parser()
2121+ /// ")"
2222+ /// }
2323+ ///
2424+ /// try coord.parse("(1,-2)") // Coordinate(x: 1.0, y: -2.0)
2525+ /// coord.print(.init(x: -5, y: 10)) // "(-5.0,10.0)"
2626+ /// ```
2727+ ///
2828+ /// To transform the output of a ``ParserPrinter`` into an enum, see ``Conversion/case(_:)-4j2n7``.
2929+ ///
3030+ /// ## Careful usage
3131+ ///
3232+ /// This conversion works by using the memberwise initializer you supply to ``memberwise(_:)`` in
3333+ /// order to turn tuples into a struct, and it uses `unsafeBitcast` to turn the struct back into
3434+ /// a tuple. Because of this, it is _not_ valid to use ``memberwise(_:)`` with anything other than
3535+ /// the default synthesized memberwise initializer that structs are given for free by the compiler
3636+ /// as that function most correctly maps the data inside a struct to its tuple representation,
3737+ /// even enforcing the order of the fields.
3838+ ///
3939+ /// If you alter the initializer in any way you run the risk of introducing subtle bugs into
4040+ /// your parser-printer and potentially causing crashes.
4141+ ///
4242+ /// For example, suppose we provided an alternative initializer to `Coordinate` above that
4343+ /// allowed you to create a coordinate from a radius and angle measured in degrees:
4444+ ///
4545+ /// ```swift
4646+ /// extension Coordinate {
4747+ /// init(radius: Double, angle: Double) {
4848+ /// self.x = radius * cos(angle * Double.pi / 180)
4949+ /// self.y = radius * sin(angle * Double.pi / 180)
5050+ /// }
5151+ /// }
5252+ /// ```
5353+ ///
5454+ /// This may seem innocent enough, but it is _not_ safe to use this initializer with
5555+ /// ``memberwise(_:)``. The following parser-printer will correctly parse a radius and angle into
5656+ /// an x/y coordinate:
5757+ ///
5858+ /// ```swift
5959+ /// let coord = ParserPrint(.memberwise(Coordinate.init(radius:angle:))) {
6060+ /// Double.parser()
6161+ /// " @ "
6262+ /// Double.parser()
6363+ /// "°"
6464+ /// }
6565+ ///
6666+ /// try coord.parse("1 @ 90°") // (x: 0, y: 1)
6767+ /// ```
6868+ ///
6969+ /// However, printing a coordinate will _not_ convert it back into a radius and angle, and
7070+ /// instead will erroneously use (0, 1) as the radius and angle:
7171+ ///
7272+ /// ```swift
7373+ /// try coord.print(.init(x: 0, y: 1)) // "0 @ 1°"
7474+ /// ```
7575+ ///
7676+ /// This means this parser-printer does not round trip (see <doc:Roundtripping>), _i.e._ if we
7777+ /// parse and input and then print that output we do not get back the original input we started
7878+ /// with:
7979+ ///
8080+ /// ```swift
8181+ /// try coord.print(try coord.parse("1 @ 90°")) == "1 @ 90°" // ❌
8282+ /// ```
8383+ ///
8484+ /// Further, it is possible to provide a custom initializer for a type that either re-orders the
8585+ /// fields or add/removes fields, both of which will cause the underlying `unsafeBitCast` to
8686+ /// crash. For example, we could have a `User` struct that holds onto a string for the bio and an
8787+ /// integer for the id, and provide a custom initializer so that the id is provided first:
8888+ ///
8989+ /// ```swift
9090+ /// struct User {
9191+ /// let bio: String
9292+ /// let id: Int
9393+ /// init(id: Int, bio: String) {
9494+ /// self.bio = bio
9595+ /// self.id = id
9696+ /// }
9797+ /// }
9898+ /// ```
9999+ ///
100100+ /// However, using this initializer with ``memberwise(_:)`` will cause printing to crash because
101101+ /// it will try to bitcast a `(String, Int)` struct into a `(Int, String)` tuple:
102102+ ///
103103+ /// ```swift
104104+ /// let user = ParsePrint(.memberwise(User.init(id:bio:))) {
105105+ /// Int.parser()
106106+ /// ","
107107+ /// Rest()
108108+ /// }
109109+ ///
110110+ /// try user.print(.init(id: 42, bio: "Hello world!")) // ❌
111111+ /// ```
112112+ ///
113113+ /// - Parameter initializer: A memberwise initializer where `Values` directly maps to the memory
114114+ /// layout of `Root`, for example the internal, default initializer that is automatically
115115+ /// synthesized for structs.
116116+ /// - Returns: A conversion that can embed a tuple of values into a struct, and destructure a
117117+ /// struct back into a tuple of values.
118118+ @inlinable
119119+ public static func memberwise<Values, Struct>(
120120+ _ initializer: @escaping @Sendable (Values) -> Struct
121121+ ) -> Self where Self == Conversions.Memberwise<Values, Struct> {
122122+ .init(initializer: initializer)
123123+ }
124124+}
125125+126126+extension Conversions {
127127+ public struct Memberwise<Values, Struct>: Conversion {
128128+ @usableFromInline
129129+ let initializer: @Sendable (Values) -> Struct
130130+131131+ @usableFromInline
132132+ init(initializer: @escaping @Sendable (Values) -> Struct) {
133133+ self.initializer = initializer
134134+ }
135135+136136+ @inlinable
137137+ public func apply(_ input: Values) -> Struct {
138138+ self.initializer(input)
139139+ }
140140+141141+ @inlinable
142142+ public func unapply(_ output: Struct) throws -> Values {
143143+ let ptr = unsafeBitCast(Struct.self as Any.Type, to: UnsafeRawPointer.self)
144144+ guard ptr.load(as: Int.self) == 512
145145+ else {
146146+ throw ConvertingError(
147147+ """
148148+ memberwise: Can't convert \(Values.self) to non-struct type \(Struct.self). This \
149149+ conversion should only be used with a memberwise initializer matching the memory layout \
150150+ of the struct. The "memberwise" initializer is the internal, compiler-generated \
151151+ initializer that specifies its arguments in the same order as the struct specifies its \
152152+ properties.
153153+ """
154154+ )
155155+ }
156156+ guard
157157+ MemoryLayout<Struct>.alignment == MemoryLayout<Values>.alignment,
158158+ MemoryLayout<Struct>.size == MemoryLayout<Values>.size
159159+ else {
160160+ throw ConvertingError(
161161+ """
162162+ memberwise: Can't convert \(Values.self) type \(Struct.self) as their memory layouts \
163163+ differ. This conversion should only be used with a memberwise initializer matching the \
164164+ memory layout of the struct. The "memberwise" initializer is the internal, \
165165+ compiler-generated initializer that specifies its arguments in the same order as the \
166166+ struct specifies its properties.
167167+ """
168168+ )
169169+ }
170170+ return unsafeBitCast(output, to: Values.self)
171171+ }
172172+ }
173173+}
···11+//#if os(iOS) || os(macOS) || os(tvOS) || os(watchOS)
22+// import Foundation
33+//
44+// @available(iOS 15, macOS 12, tvOS 15, watchOS 8, *)
55+// extension Conversion {
66+// /// A conversion that wraps a parseable format style.
77+// ///
88+// /// This conversion forwards its ``apply(_:)`` and ``unapply(_:)`` methods to the underlying
99+// /// `ParseableFormatStyle` by invoking its parse strategy's `parse` method and its `format`
1010+// /// method.
1111+// ///
1212+// /// See ``formatted(_:)-swift.method`` for a fluent version of this interface that transforms an
1313+// /// existing conversion.
1414+// ///
1515+// /// - Parameter style: A parseable format style.
1616+// /// - Returns: A conversion from a string to the given type.
1717+// public static func formatted<Style>(
1818+// _ style: Style
1919+// ) -> Self where Self == Conversions.ParseableFormat<Style> {
2020+// .init(style: style)
2121+// }
2222+//
2323+// /// Transforms this conversion to a parseable format style's parse input into a conversion to
2424+// /// the parseable format style's parse output.
2525+// ///
2626+// /// A fluent version of ``Conversion/formatted(_:)-swift.type.method``. Equivalent to calling
2727+// /// ``map(_:)`` with ``Conversion/formatted(_:)-swift.type.method``:
2828+// ///
2929+// /// ```swift
3030+// /// Parse(.string.formatted(.currency("USD")))
3131+// /// // =
3232+// /// Parse(.string.map(.formatted(.currency("USD"))))
3333+// /// ```
3434+// ///
3535+// /// - Parameter type: A type that conforms to `LosslessStringConvertible`.
3636+// /// - Returns: A conversion from a string to the given type.
3737+// public func formatted<Style>(
3838+// _ style: Style
3939+// ) -> Conversions.Map<Self, Conversions.ParseableFormat<Style>> {
4040+// self.map(.formatted(style))
4141+// }
4242+// }
4343+//
4444+// extension Conversions {
4545+// /// A conversion for a parseable format style.
4646+// ///
4747+// /// You will not typically need to interact with this type directly. Instead you will usually
4848+// /// use the ``Conversion/formatted(_:)-swift.type.method`` operation, which constructs this
4949+// /// type.
5050+// @available(iOS 15, macOS 12, tvOS 15, watchOS 8, *)
5151+// public struct ParseableFormat<Style>: Conversion where Style: ParseableFormatStyle {
5252+// public let style: Style
5353+//
5454+// @inlinable
5555+// public func apply(_ input: Style.Strategy.ParseInput) throws -> Style.Strategy.ParseOutput {
5656+// try style.parseStrategy.parse(input)
5757+// }
5858+//
5959+// @inlinable
6060+// public func unapply(_ output: Style.FormatInput) -> Style.FormatOutput {
6161+// self.style.format(output)
6262+// }
6363+// }
6464+// }
6565+//#endif
···11+import Foundation
22+33+/// A collection that supports empty initialization and the ability to prepend a sequence of
44+/// elements of elements to itself.
55+///
66+/// `PrependableCollection` is a specialized subset of `RangeReplaceableCollection` that is tuned
77+/// to incremental printing.
88+///
99+/// In fact, any `RangeReplaceableCollection` can get a conformance for free:
1010+///
1111+/// ```swift
1212+/// extension MyRangeReplaceableCollection: PrependableCollection {}
1313+/// ```
1414+///
1515+/// Because it is also less strict than `RangeReplaceableCollection`, it is an appropriate
1616+/// protocol to conform to for types that cannot and should not conform to
1717+/// `RangeReplaceableCollection` directly.
1818+///
1919+/// For example, `Substring.UTF8View` is a common input for string parsers to parse from, but it
2020+/// does not conform to `RangeReplaceableCollection`. It does, however, conform to
2121+/// `PrependableCollection` by validating and prepending the given UTF-8 bytes to its underlying
2222+/// substring. So in order to write a parser against generic sequences of UTF-8 bytes, you would
2323+/// constrain its input against `PrependableCollection`.
2424+///
2525+/// For example the following `Digits` parser is generic over an `Collection` of bytes, and its
2626+/// printer conformance further constraints its input to be prependable.
2727+///
2828+/// ```swift
2929+/// struct Digits<Input: Collection>: Parser
3030+/// where
3131+/// Input.Element == UTF8.CodeUnit, // Required for working with a collection of bytes
3232+/// Input.SubSequence == Input // Required for the parser to consume from input
3333+/// {
3434+/// func parse(_ input: inout Input) throws -> Int {
3535+/// // Collect all bytes between ASCII "0" and "9"
3636+/// let prefix = input.prefix(while: { $0 >= .init(ascii: "0") && $0 <= .init(ascii: "9") })
3737+///
3838+/// // Attempt to convert to an `Int`
3939+/// guard let int = Int(prefix) else {
4040+/// struct ParseError: Error {}
4141+/// throw ParseError()
4242+/// }
4343+///
4444+/// // Incrementally consume bytes from input
4545+/// input.removeFirst(prefix.count)
4646+///
4747+/// return int
4848+/// }
4949+/// }
5050+///
5151+/// extension Digits: ParserPrinter where Input: PrependableCollection {
5252+/// func print(_ output: Int, into input: inout Input) {
5353+/// // Convert `Int` to string's underlying bytes
5454+/// let bytes = String(output).utf8
5555+///
5656+/// // Prepend bytes using `PrependableCollection` conformance.
5757+/// input.prepend(contentsOf: bytes)
5858+/// }
5959+/// }
6060+/// ```
6161+///
6262+/// The `Digits` parser-printer now works on any collection of UTF-8 code units, including
6363+/// `UTF8View` and `ArraySlice<UInt8>`:
6464+///
6565+/// ```swift
6666+/// var input = "123"[...].utf8
6767+/// try Digits().parse(&input) // 123
6868+/// try Digits().print(123, into: &input)
6969+/// Substring(input) // "123"
7070+/// ```
7171+///
7272+/// ```swift
7373+/// var input = ArraySlice("123"[...].utf8)
7474+/// try Digits().parse(&input) // 123
7575+/// try Digits().print(123, into: &input)
7676+/// Substring(decoding: input, as: UTF8.self) // "123"
7777+/// ```
7878+public protocol PrependableCollection<Element>: Collection, _EmptyInitializable {
7979+ /// Inserts the elements of a sequence or collection to the beginning of this collection.
8080+ ///
8181+ /// The collection being prepended to allocates any additional necessary storage to hold the new
8282+ /// elements.
8383+ ///
8484+ /// - Parameter newElements: The elements to append to the collection.
8585+ mutating func prepend<S: Sequence>(contentsOf newElements: S) where S.Element == Element
8686+}
8787+8888+extension PrependableCollection {
8989+ /// Creates a new instance of a collection containing the elements of a sequence.
9090+ ///
9191+ /// - Parameter elements: The sequence of elements for the new collection. `elements` must be
9292+ /// finite.
9393+ @inlinable
9494+ public init<S: Collection>(_ elements: S) where S.Element == Element {
9595+ var collection = Self()
9696+ collection.prepend(contentsOf: elements)
9797+ self = collection
9898+ }
9999+100100+ /// Adds an element to the beginning of the collection.
101101+ ///
102102+ /// - Parameter newElement: The element to prepend to the collection.
103103+ @inlinable
104104+ public mutating func prepend(_ newElement: Element) {
105105+ self.prepend(contentsOf: CollectionOfOne(newElement))
106106+ }
107107+}
108108+109109+extension RangeReplaceableCollection {
110110+ @inlinable
111111+ public mutating func prepend<S: Sequence>(contentsOf newElements: S)
112112+ where S.Element == Element {
113113+ var newSelf = Self()
114114+ newSelf.append(contentsOf: newElements)
115115+ newSelf.append(contentsOf: self)
116116+ self = newSelf
117117+ }
118118+}
119119+120120+extension Array: PrependableCollection {}
121121+extension ArraySlice: PrependableCollection {}
122122+extension ContiguousArray: PrependableCollection {}
123123+extension Data: PrependableCollection {}
124124+extension Slice: PrependableCollection, _EmptyInitializable
125125+where Base: RangeReplaceableCollection {}
126126+extension String: PrependableCollection {}
127127+extension String.UnicodeScalarView: PrependableCollection {}
128128+extension Substring: PrependableCollection {}
129129+extension Substring.UnicodeScalarView: PrependableCollection {}
130130+131131+extension String.UTF8View: PrependableCollection {
132132+ @inlinable
133133+ public init() {
134134+ self = "".utf8
135135+ }
136136+137137+ @inlinable
138138+ public mutating func prepend<S: Sequence>(contentsOf elements: S)
139139+ where S.Element == Element {
140140+ var str = String(self)
141141+ defer { self = str.utf8 }
142142+143143+ switch elements {
144144+ case let elements as String.UTF8View:
145145+ str.prepend(contentsOf: String(elements))
146146+ case let elements as Substring.UTF8View:
147147+ str.prepend(contentsOf: Substring(elements))
148148+ default:
149149+ str.prepend(contentsOf: Substring(decoding: Array(elements), as: UTF8.self))
150150+ }
151151+ }
152152+}
153153+154154+extension Substring.UTF8View: PrependableCollection {
155155+ @inlinable
156156+ public init() {
157157+ self = ""[...].utf8
158158+ }
159159+160160+ @inlinable
161161+ public mutating func prepend<S: Sequence>(contentsOf elements: S)
162162+ where S.Element == Element {
163163+ var str = Substring(self)
164164+ defer { self = str.utf8 }
165165+166166+ switch elements {
167167+ case let elements as String.UTF8View:
168168+ str.prepend(contentsOf: String(elements))
169169+ case let elements as Substring.UTF8View:
170170+ str.prepend(contentsOf: Substring(elements))
171171+ default:
172172+ str.prepend(contentsOf: Substring(decoding: Array(elements), as: UTF8.self))
173173+ }
174174+ }
175175+}
···11+extension Conversion {
22+ /// A conversion from a given raw representable type's raw value to itself.
33+ ///
44+ /// This conversion is useful for mapping the output of a more primitive parser-printer into a
55+ /// raw representable value.
66+ ///
77+ /// For example, you may have a raw representable type that wraps a more primitive type for the
88+ /// purpose of strengthening type requirements in your APIs. One example is an identifier type
99+ /// that wraps an integer:
1010+ ///
1111+ /// ```swift
1212+ /// struct UserID: RawRepresentable {
1313+ /// var rawValue: Int
1414+ /// }
1515+ /// ```
1616+ ///
1717+ /// You can transform an `Int` parser into a `UserID` parser by invoking ``Parser/map(_:)-18m9d``
1818+ /// with this conversion:
1919+ ///
2020+ /// ```swift
2121+ /// let userID = Int.parser().map(.representing(UserID.self))
2222+ /// ```
2323+ ///
2424+ /// See ``representing(_:)-swift.method`` for a fluent version of this interface that transforms
2525+ /// an existing conversion. This fluent API is particularly useful when mapping string raw values
2626+ /// directly from parsers of substrings and UTF-8 views, which require first transforming the
2727+ /// parsed substring or UTF-8 view into a string via the ``string-swift.type.property-9owth`` and
2828+ /// ``string-swift.type.property-3u2b5`` conversions.
2929+ ///
3030+ /// ```swift
3131+ /// struct EmailAddress: RawRepresentable {
3232+ /// var rawValue: String
3333+ /// }
3434+ ///
3535+ /// let emailAddress = Parse(.string.representing(EmailAddress.self)) {
3636+ /// Consumed {
3737+ /// PrefixUpTo("@")
3838+ /// "@"
3939+ /// Rest()
4040+ /// }
4141+ /// }
4242+ /// ```
4343+ ///
4444+ /// - Parameter type: A type that conforms to `RawRepresentable`.
4545+ /// - Returns: A conversion from a raw value to the given type.
4646+ @inlinable
4747+ public static func representing<NewOutput>(
4848+ _ type: NewOutput.Type
4949+ ) -> Self where Self == Conversions.FromRawValue<NewOutput> {
5050+ .init()
5151+ }
5252+5353+ /// Transforms this conversion to a raw value into a conversion to the given raw representable
5454+ /// type.
5555+ ///
5656+ /// A fluent version of ``Conversion/representing(_:)-swift.type.method``. Equivalent to calling
5757+ /// ``map(_:)`` with ``Conversion/representing(_:)-swift.type.method``:
5858+ ///
5959+ /// ```swift
6060+ /// stringConversion.representing(EmailAddress.self)
6161+ /// // =
6262+ /// stringConversion.map(.representing(EmailAddress.self)
6363+ /// ```
6464+ ///
6565+ /// - Parameter type: A type that conforms to `RawRepresentable`.
6666+ /// - Returns: A conversion from a raw value to the given type.
6767+ @inlinable
6868+ public func representing<NewOutput>(
6969+ _ type: NewOutput.Type
7070+ ) -> Conversions.Map<Self, Conversions.FromRawValue<NewOutput>> {
7171+ self.map(.representing(NewOutput.self))
7272+ }
7373+}
7474+7575+extension Conversions {
7676+ /// A conversion from a raw value to a raw representable type.
7777+ ///
7878+ /// You will not typically need to interact with this type directly. Instead you will usually use
7979+ /// the ``Conversion/representing(_:)-swift.type.method`` operation, which constructs this type.
8080+ public struct FromRawValue<Output: RawRepresentable>: Conversion {
8181+ @inlinable
8282+ public init() {}
8383+8484+ @inlinable
8585+ public func apply(_ input: Output.RawValue) throws -> Output {
8686+ guard let output = Output(rawValue: input)
8787+ else {
8888+ var debugDescription = ""
8989+ debugPrint(input, to: &debugDescription)
9090+ throw ConvertingError(
9191+ """
9292+ representing: Failed to convert \(debugDescription) to \(Output.self).
9393+ """
9494+ )
9595+ }
9696+ return output
9797+ }
9898+9999+ @inlinable
100100+ public func unapply(_ output: Output) -> Output.RawValue {
101101+ output.rawValue
102102+ }
103103+ }
104104+}
···11+extension Conversion where Self == Conversions.SubstringToString {
22+ /// A conversion from `Substring` to `String`.
33+ ///
44+ /// Useful for transforming a ``ParserPrinter``'s substring output into a more general-purpose
55+ /// string.
66+ ///
77+ /// ```swift
88+ /// let line = Prefix { $0 != "\n" }.map(.string)
99+ /// ```
1010+ @inlinable
1111+ public static var string: Self { .init() }
1212+}
1313+1414+extension Conversion where Output == Substring {
1515+ /// Transforms this conversion to `Substring` into a conversion to `String`.
1616+ ///
1717+ /// A fluent version of ``Conversion/string-swift.type.property-3u2b5``.
1818+ @inlinable
1919+ public var string: Conversions.Map<Self, Conversions.SubstringToString> { self.map(.string) }
2020+}
2121+2222+extension Conversion where Self == Conversions.BytesToString<Substring.UTF8View> {
2323+ /// A conversion from `Substring.UTF8View` to `String`.
2424+ ///
2525+ /// Useful for transforming a ``ParserPrinter``'s UTF-8 output into a more general-purpose string.
2626+ ///
2727+ /// ```swift
2828+ /// let line = Prefix { $0 != .init(ascii: "\n") }.map(.string)
2929+ /// ```
3030+ @inlinable
3131+ public static var string: Self { .init() }
3232+}
3333+3434+extension Conversion where Output == Substring.UTF8View {
3535+ /// Transforms this conversion to `Substring.UTF8View` into a conversion to `String`.
3636+ ///
3737+ /// A fluent version of ``Conversion/string-swift.type.property-9owth``.
3838+ @inlinable
3939+ public var string: Conversions.Map<Self, Conversions.BytesToString<Output>> { self.map(.string) }
4040+}
4141+4242+extension Conversions {
4343+ /// A conversion from a substring to a string.
4444+ ///
4545+ /// You will not typically need to interact with this type directly. Instead you will usually use
4646+ /// the ``Conversion/string-swift.type.property-3u2b5`` operation, which constructs this type.
4747+ public struct SubstringToString: Conversion {
4848+ @inlinable
4949+ public init() {}
5050+5151+ @inlinable
5252+ public func apply(_ input: Substring) -> String {
5353+ String(input)
5454+ }
5555+5656+ @inlinable
5757+ public func unapply(_ output: String) -> Substring {
5858+ Substring(output)
5959+ }
6060+ }
6161+6262+ /// A conversion from a ``PrependableCollection`` of UTF-8 bytes to a string.
6363+ ///
6464+ /// You will not typically need to interact with this type directly. Instead you will usually use
6565+ /// the ``Conversion/string-swift.type.property-9owth`` operation, which constructs this type.
6666+ public struct BytesToString<Input: PrependableCollection>: Conversion
6767+ where
6868+ Input.SubSequence == Input,
6969+ Input.Element == UTF8.CodeUnit
7070+ {
7171+ @inlinable
7272+ public init() {}
7373+7474+ @inlinable
7575+ public func apply(_ input: Input) -> String {
7676+ String(decoding: input, as: UTF8.self)
7777+ }
7878+7979+ @inlinable
8080+ public func unapply(_ output: String) -> Input {
8181+ .init(output.utf8)
8282+ }
8383+ }
8484+}
···11+extension Conversion where Self == Conversions.UnicodeScalarViewToSubstring {
22+ /// A conversion from `Substring.UnicodeScalarView` to `Substring`.
33+ ///
44+ /// Useful when used with the ``From`` parser-printer to integrate a substring parser into a
55+ /// parser on unicode scalars.
66+ @inlinable
77+ public static var substring: Self { .init() }
88+}
99+1010+extension Conversion where Output == Substring.UnicodeScalarView {
1111+ /// Transforms this conversion to `Substring.UnicodeScalarView` into a conversion to `Substring`.
1212+ ///
1313+ /// A fluent version of ``Conversion/substring-swift.type.property-4r1aj``.
1414+ @inlinable
1515+ public var substring: Conversions.Map<Self, Conversions.UnicodeScalarViewToSubstring> {
1616+ self.map(.substring)
1717+ }
1818+}
1919+2020+extension Conversion where Self == Conversions.UTF8ViewToSubstring {
2121+ /// A conversion from `Substring.UTF8View` to `Substring`.
2222+ ///
2323+ /// Useful when used with the ``From`` parser-printer to integrate a substring parser into a
2424+ /// parser on UTF-8 bytes.
2525+ ///
2626+ /// For example:
2727+ ///
2828+ /// ```swift
2929+ /// Parse {
3030+ /// "caf".utf8
3131+ /// From(.substring) {
3232+ /// "é"
3333+ /// }
3434+ /// }
3535+ /// ```
3636+ @inlinable
3737+ public static var substring: Self { .init() }
3838+}
3939+4040+extension Conversion where Output == Substring.UTF8View {
4141+ /// Transforms this conversion to `Substring.UTF8View` into a conversion to `Substring`.
4242+ ///
4343+ /// A fluent version of ``Conversion/substring-swift.type.property-1y3u3``.
4444+ @inlinable
4545+ public var substring: Conversions.Map<Self, Conversions.UTF8ViewToSubstring> {
4646+ self.map(.substring)
4747+ }
4848+}
4949+5050+extension Conversions {
5151+ /// A conversion from a unicode scalar view to its substring.
5252+ ///
5353+ /// You will not typically need to interact with this type directly. Instead you will usually use
5454+ /// the ``Conversion/substring-swift.type.property-1y3u3`` and operation, which constructs this
5555+ /// type under the hood.
5656+ public struct UnicodeScalarViewToSubstring: Conversion {
5757+ @inlinable
5858+ public init() {}
5959+6060+ @inlinable
6161+ public func apply(_ input: Substring.UnicodeScalarView) -> Substring {
6262+ Substring(input)
6363+ }
6464+6565+ @inlinable
6666+ public func unapply(_ output: Substring) -> Substring.UnicodeScalarView {
6767+ output.unicodeScalars
6868+ }
6969+ }
7070+7171+ /// A conversion from a UTF-8 view to its substring.
7272+ ///
7373+ /// You will not typically need to interact with this type directly. Instead you will usually use
7474+ /// the ``Conversion/substring-swift.type.property-4r1aj`` operation, which constructs this type.
7575+ public struct UTF8ViewToSubstring: Conversion {
7676+ @inlinable
7777+ public init() {}
7878+7979+ @inlinable
8080+ public func apply(_ input: Substring.UTF8View) -> Substring {
8181+ Substring(input)
8282+ }
8383+8484+ @inlinable
8585+ public func unapply(_ output: Substring) -> Substring.UTF8View {
8686+ output.utf8
8787+ }
8888+ }
8989+}
···11+extension Conversion where Self == Conversions.SubstringToUTF8View {
22+ /// A conversion from `Substring` to `Substring.UTF8View`.
33+ ///
44+ /// Useful when used with the ``From`` parser-printer to integrate a UTF-8 parser into a substring
55+ /// parser.
66+ @inlinable
77+ public static var utf8: Self { .init() }
88+}
99+1010+extension Conversion where Output == Substring {
1111+ /// Transforms this conversion to `Substring` into a conversion to `Substring.UTF8View`.
1212+ ///
1313+ /// A fluent version of ``Conversion/utf8-swift.type.property``.
1414+ @inlinable
1515+ public var utf8: Conversions.Map<Self, Conversions.SubstringToUTF8View> { self.map(.utf8) }
1616+}
1717+1818+extension Conversions {
1919+ /// A conversion from a substring to its UTF-8 view.
2020+ ///
2121+ /// You will not typically need to interact with this type directly. Instead you will usually use
2222+ /// the ``Conversion/utf8-swift.type.property`` operation, which constructs this type.
2323+ public struct SubstringToUTF8View: Conversion {
2424+ @inlinable
2525+ public init() {}
2626+2727+ @inlinable
2828+ public func apply(_ input: Substring) -> Substring.UTF8View {
2929+ input.utf8
3030+ }
3131+3232+ @inlinable
3333+ public func unapply(_ output: Substring.UTF8View) -> Substring {
3434+ Substring(output)
3535+ }
3636+ }
3737+}