A type safe swift ResultBuilder DSL for structured directories
0

Configure Feed

Select the types of activity you want to include in your feed.

swift-file-tree / Sources / FileTree / Conversions / RawRepresentable.swift
3.6 kB 104 lines
1extension Conversion { 2 /// A conversion from a given raw representable type's raw value to itself. 3 /// 4 /// This conversion is useful for mapping the output of a more primitive parser-printer into a 5 /// raw representable value. 6 /// 7 /// For example, you may have a raw representable type that wraps a more primitive type for the 8 /// purpose of strengthening type requirements in your APIs. One example is an identifier type 9 /// that wraps an integer: 10 /// 11 /// ```swift 12 /// struct UserID: RawRepresentable { 13 /// var rawValue: Int 14 /// } 15 /// ``` 16 /// 17 /// You can transform an `Int` parser into a `UserID` parser by invoking ``Parser/map(_:)-18m9d`` 18 /// with this conversion: 19 /// 20 /// ```swift 21 /// let userID = Int.parser().map(.representing(UserID.self)) 22 /// ``` 23 /// 24 /// See ``representing(_:)-swift.method`` for a fluent version of this interface that transforms 25 /// an existing conversion. This fluent API is particularly useful when mapping string raw values 26 /// directly from parsers of substrings and UTF-8 views, which require first transforming the 27 /// parsed substring or UTF-8 view into a string via the ``string-swift.type.property-9owth`` and 28 /// ``string-swift.type.property-3u2b5`` conversions. 29 /// 30 /// ```swift 31 /// struct EmailAddress: RawRepresentable { 32 /// var rawValue: String 33 /// } 34 /// 35 /// let emailAddress = Parse(.string.representing(EmailAddress.self)) { 36 /// Consumed { 37 /// PrefixUpTo("@") 38 /// "@" 39 /// Rest() 40 /// } 41 /// } 42 /// ``` 43 /// 44 /// - Parameter type: A type that conforms to `RawRepresentable`. 45 /// - Returns: A conversion from a raw value to the given type. 46 @inlinable 47 public static func representing<NewOutput>( 48 _ type: NewOutput.Type 49 ) -> Self where Self == Conversions.FromRawValue<NewOutput> { 50 .init() 51 } 52 53 /// Transforms this conversion to a raw value into a conversion to the given raw representable 54 /// type. 55 /// 56 /// A fluent version of ``Conversion/representing(_:)-swift.type.method``. Equivalent to calling 57 /// ``map(_:)`` with ``Conversion/representing(_:)-swift.type.method``: 58 /// 59 /// ```swift 60 /// stringConversion.representing(EmailAddress.self) 61 /// // = 62 /// stringConversion.map(.representing(EmailAddress.self) 63 /// ``` 64 /// 65 /// - Parameter type: A type that conforms to `RawRepresentable`. 66 /// - Returns: A conversion from a raw value to the given type. 67 @inlinable 68 public func representing<NewOutput>( 69 _ type: NewOutput.Type 70 ) -> Conversions.Map<Self, Conversions.FromRawValue<NewOutput>> { 71 self.map(.representing(NewOutput.self)) 72 } 73} 74 75extension Conversions { 76 /// A conversion from a raw value to a raw representable type. 77 /// 78 /// You will not typically need to interact with this type directly. Instead you will usually use 79 /// the ``Conversion/representing(_:)-swift.type.method`` operation, which constructs this type. 80 public struct FromRawValue<Output: RawRepresentable>: Conversion { 81 @inlinable 82 public init() {} 83 84 @inlinable 85 public func apply(_ input: Output.RawValue) throws -> Output { 86 guard let output = Output(rawValue: input) 87 else { 88 var debugDescription = "" 89 debugPrint(input, to: &debugDescription) 90 throw ConvertingError( 91 """ 92 representing: Failed to convert \(debugDescription) to \(Output.self). 93 """ 94 ) 95 } 96 return output 97 } 98 99 @inlinable 100 public func unapply(_ output: Output) -> Output.RawValue { 101 output.rawValue 102 } 103 } 104}