66//
77
88extension Parser where Input == String {
9+ /// Decodes all matches found in `string` into an array of `T`.
10+ @inlinable
911 public func decode< T> ( _ type: [ T ] . Type, from string: String ) throws -> [ T ] where T: Decodable {
1012 try matches ( in: string) . map { try $0. decode ( type. Element. self, from: string) }
1113 }
1214
15+ /// Decodes the first match found in `string` into a value of type `type`.
16+ @inlinable
1317 public func decodeFirst< T> ( _ type: T . Type , from string: String ) throws -> T ? where T: Decodable {
1418 try match ( in: string, at: string. startIndex) . map { try $0. decode ( type. self, from: string) }
1519 }
1620}
1721
1822extension Parser . Match where Input == String {
23+ /// Decodes this match found in `string` into a value of type `type`.
24+ @inlinable
1925 public func decode< T> ( _ type: T . Type , from string: String ) throws -> T where T: Decodable {
20- return try type. init ( from: MatchDecoder ( match: self , string: string) )
26+ try type. init ( from: MatchDecoder ( match: self , string: string) )
2127 }
2228
2329 public struct MatchDecoder : Decoder {
30+ @usableFromInline
2431 let match : Parser . Match
32+ @usableFromInline
2533 let string : String
2634
2735 public let codingPath : [ CodingKey ]
2836 public var userInfo : [ CodingUserInfoKey : Any ] { [ : ] }
2937
38+ @inlinable
3039 init ( match: Parser . Match , string: String , codingPath: [ CodingKey ] = [ ] ) {
3140 let namePrefix = codingPath. first. map { $0. stringValue }
3241 let captures = namePrefix. map { namePrefix in
@@ -40,52 +49,77 @@ extension Parser.Match where Input == String {
4049 self . codingPath = codingPath
4150 }
4251
52+ @inlinable
4353 public func container< Key> ( keyedBy _: Key . Type ) throws -> KeyedDecodingContainer < Key > where Key: CodingKey {
44- return KeyedDecodingContainer ( KDC ( codingPath: codingPath, matchDecoder: self ) )
54+ KeyedDecodingContainer ( KDC ( codingPath: codingPath, matchDecoder: self ) )
4555 }
4656
57+ @inlinable
4758 public func unkeyedContainer( ) throws -> UnkeyedDecodingContainer {
4859 UDC ( codingPath: codingPath, values: match. captures. map { $0. range } , string: string)
4960 }
5061
62+ @inlinable
5163 public func singleValueContainer( ) throws -> SingleValueDecodingContainer {
5264 guard match. captures. count < 2 else {
65+ let property = codingPath. map { " \( $0. stringValue) " } . joined ( separator: " . " )
5366 throw DecodingError . dataCorrupted ( DecodingError . Context ( codingPath: codingPath, debugDescription:
54- " Property ' \( codingPath . map { " \( $0 . stringValue ) " } . joined ( separator : " . " ) ) ' needs a single value, but multiple captures exists. " ) )
67+ " Property ' \( property ) ' needs a single value, but multiple captures exists. " ) )
5568 }
5669 let range = match. captures. first? . range ?? match. endIndex ..< match. endIndex
5770 return StringDecoder ( string: String ( string [ range] ) , codingPath: codingPath)
5871 }
5972
73+ @usableFromInline
6074 struct UDC : UnkeyedDecodingContainer {
75+ @usableFromInline
6176 var codingPath : [ CodingKey ]
77+ @usableFromInline
6278 let values : [ Range < Pattern . Input . Index > ]
79+ @usableFromInline
6380 let string : String
6481
82+ @usableFromInline
83+ init ( codingPath: [ CodingKey ] , values: [ Range < Pattern . Input . Index > ] , string: String ) {
84+ self . codingPath = codingPath
85+ self . values = values
86+ self . string = string
87+ }
88+
89+ @usableFromInline
6590 var count : Int ? { values. count }
91+ @usableFromInline
6692 var isAtEnd : Bool { currentIndex >= values. endIndex }
93+ @usableFromInline
6794 var currentIndex : Int = 0
6895
96+ @usableFromInline
6997 mutating func decodeNil( ) throws -> Bool { false }
7098
71- mutating func nestedContainer< NestedKey> ( keyedBy type: NestedKey . Type ) throws -> KeyedDecodingContainer < NestedKey > where NestedKey: CodingKey {
99+ @usableFromInline
100+ mutating func nestedContainer< NestedKey> ( keyedBy type: NestedKey . Type )
101+ throws -> KeyedDecodingContainer < NestedKey > where NestedKey: CodingKey {
72102 fatalError ( " Not implemented yet. If you want to help with that, go to https://github.com/kareman/Patterns " )
73103 }
74104
105+ @usableFromInline
75106 mutating func nestedUnkeyedContainer( ) throws -> UnkeyedDecodingContainer {
76107 fatalError ( " Not implemented yet. If you want to help with that, go to https://github.com/kareman/Patterns " )
77108 }
78109
110+ @usableFromInline
79111 mutating func superDecoder( ) throws -> Decoder {
80112 fatalError ( " Not implemented yet. If you want to help with that, go to https://github.com/kareman/Patterns " )
81113 }
82114
115+ @usableFromInline
83116 mutating func decode< T> ( _ type: T . Type ) throws -> T where T: Decodable {
84117 defer { currentIndex += 1 }
85118 let text = String ( string [ values [ currentIndex] ] )
86119 return try type. init ( from: StringDecoder ( string: text, codingPath: codingPath) )
87120 }
88121
122+ @usableFromInline
89123 mutating func decode< T> ( _ type: T . Type ) throws -> T where T: Decodable & LosslessStringConvertible {
90124 guard let value = type. init ( String ( string [ values [ currentIndex] ] ) ) else {
91125 throw DecodingError . typeMismatch ( type, DecodingError . Context ( codingPath: codingPath, debugDescription: " " ) )
@@ -95,82 +129,118 @@ extension Parser.Match where Input == String {
95129 }
96130 }
97131
132+ @usableFromInline
98133 struct KDC < Key: CodingKey > : KeyedDecodingContainerProtocol {
134+ @usableFromInline
99135 var codingPath : [ CodingKey ] = [ ]
136+ @usableFromInline
100137 var allKeys : [ Key ] {
101138 matchDecoder. match. names. compactMap ( Key . init ( stringValue: ) )
102139 }
103140
141+ @usableFromInline
104142 let matchDecoder : MatchDecoder
105143
144+ @usableFromInline
145+ init ( codingPath: [ CodingKey ] = [ ] , matchDecoder: MatchDecoder ) {
146+ self . codingPath = codingPath
147+ self . matchDecoder = matchDecoder
148+ }
149+
150+ @usableFromInline
106151 func capture( for key: CodingKey ) throws -> String {
107152 guard let range = matchDecoder. match [ one: key. stringValue] else {
108153 throw DecodingError . keyNotFound ( key, DecodingError . Context ( codingPath: codingPath, debugDescription: " " ) )
109154 }
110155 return String ( matchDecoder. string [ range] )
111156 }
112157
158+ @usableFromInline
113159 func contains( _ key: Key ) -> Bool {
114160 matchDecoder. match [ one: key. stringValue] == nil
115161 }
116162
163+ @usableFromInline
117164 func decodeNil( forKey key: Key ) throws -> Bool {
118165 contains ( key)
119166 }
120167
168+ @usableFromInline
121169 func decode< T> ( _ type: T . Type , forKey key: Key ) throws -> T where T: Decodable {
122- return try type. init ( from: MatchDecoder ( match: matchDecoder. match, string: matchDecoder. string, codingPath: codingPath + [ key] ) )
170+ return try type. init ( from:
171+ MatchDecoder ( match: matchDecoder. match, string: matchDecoder. string, codingPath: codingPath + [ key] ) )
123172 }
124173
174+ @usableFromInline
125175 func decode< T> ( _ type: T . Type , forKey key: Key ) throws -> T where T: Decodable & LosslessStringConvertible {
126176 guard let value = type. init ( try capture ( for: key) ) else {
127177 throw DecodingError . typeMismatch ( type, DecodingError . Context ( codingPath: [ key] , debugDescription: " " ) )
128178 }
129179 return value
130180 }
131181
132- func nestedContainer< NestedKey> ( keyedBy _: NestedKey . Type , forKey _: Key ) throws -> KeyedDecodingContainer < NestedKey > where NestedKey: CodingKey {
182+ @usableFromInline
183+ func nestedContainer< NestedKey> ( keyedBy _: NestedKey . Type , forKey _: Key )
184+ throws -> KeyedDecodingContainer < NestedKey > where NestedKey: CodingKey {
133185 fatalError ( " Not implemented yet. If you want to help with that, go to https://github.com/kareman/Patterns " )
134186 }
135187
188+ @usableFromInline
136189 func nestedUnkeyedContainer( forKey _: Key ) throws -> UnkeyedDecodingContainer {
137190 fatalError ( " Not implemented yet. If you want to help with that, go to https://github.com/kareman/Patterns " )
138191 }
139192
193+ @usableFromInline
140194 func superDecoder( ) throws -> Decoder {
141195 fatalError ( " Not implemented yet. If you want to help with that, go to https://github.com/kareman/Patterns " )
142196 }
143197
198+ @usableFromInline
144199 func superDecoder( forKey _: Key ) throws -> Decoder {
145200 fatalError ( " Not implemented yet. If you want to help with that, go to https://github.com/kareman/Patterns " )
146201 }
147202 }
148203 }
149204}
150205
206+ @usableFromInline
151207struct StringDecoder : Decoder , SingleValueDecodingContainer {
208+ @usableFromInline
152209 let string : String
210+ @usableFromInline
153211 let codingPath : [ CodingKey ]
212+ @usableFromInline
154213 var userInfo : [ CodingUserInfoKey : Any ] = [ : ]
155214
215+ @usableFromInline
216+ init ( string: String , codingPath: [ CodingKey ] , userInfo: [ CodingUserInfoKey : Any ] = [ : ] ) {
217+ self . string = string
218+ self . codingPath = codingPath
219+ self . userInfo = userInfo
220+ }
221+
222+ @usableFromInline
156223 func container< Key> ( keyedBy type: Key . Type ) throws -> KeyedDecodingContainer < Key > where Key: CodingKey {
157224 fatalError ( " Not implemented yet. If you want to help with that, go to https://github.com/kareman/Patterns " )
158225 }
159226
227+ @usableFromInline
160228 func unkeyedContainer( ) throws -> UnkeyedDecodingContainer {
161229 fatalError ( " Not implemented yet. If you want to help with that, go to https://github.com/kareman/Patterns " )
162230 }
163231
164- func singleValueContainer( ) throws -> SingleValueDecodingContainer {
165- self
166- }
232+ @usableFromInline
233+ func singleValueContainer( ) throws -> SingleValueDecodingContainer { self }
167234
235+ @usableFromInline
168236 func decodeNil( ) -> Bool { false }
169237
238+ @usableFromInline
170239 func decode< T> ( _ type: T . Type ) throws -> T where T: Decodable {
171240 fatalError ( " Not implemented yet. If you want to help with that, go to https://github.com/kareman/Patterns " )
172241 }
173242
243+ @usableFromInline
174244 func decode< T> ( _ type: T . Type ) throws -> T where T: Decodable & LosslessStringConvertible {
175245 guard let value = type. init ( string) else {
176246 throw DecodingError . typeMismatch ( type, DecodingError . Context ( codingPath: codingPath, debugDescription: " " ) )
0 commit comments