@@ -19,6 +19,15 @@ public protocol ExpressibleByParsing {
19
19
}
20
20
21
21
extension ExpressibleByParsing {
22
+ @_alwaysEmitIntoClient
23
+ public init (
24
+ parsing data: some ParserSpanProvider
25
+ ) throws ( ThrownParsingError) {
26
+ self = try data. withParserSpan ( Self . init ( parsing: ) )
27
+ }
28
+
29
+ @_alwaysEmitIntoClient
30
+ @_disfavoredOverload
22
31
public init ( parsing data: some RandomAccessCollection < UInt8 > )
23
32
throws ( ThrownParsingError)
24
33
{
@@ -41,112 +50,112 @@ extension RandomAccessCollection<UInt8> {
41
50
) throws ( ThrownParsingError) -> T ? {
42
51
#if canImport(Foundation)
43
52
if let data = self as? Foundation . Data {
44
- do {
45
- return try data. withUnsafeBytes { buffer -> T in
46
- var span = ParserSpan ( _unsafeBytes: buffer)
47
- return try body ( & span)
48
- }
49
- } catch {
50
- // Workaround for lack of typed-throwing API on Data
51
- // swift-format-ignore: NeverForceUnwrap
52
- throw error as! ThrownParsingError
53
+ let result = data. withUnsafeBytes { buffer in
54
+ var span = ParserSpan ( _unsafeBytes: buffer)
55
+ return Result < T , ThrownParsingError > { try body ( & span) }
56
+ }
57
+ switch result {
58
+ case . success( let t) : return t
59
+ case . failure( let e) : throw e
53
60
}
54
61
}
55
62
#endif
56
- do {
57
- return try self . withContiguousStorageIfAvailable { buffer in
58
- let rawBuffer = UnsafeRawBufferPointer ( buffer)
59
- var span = ParserSpan ( _unsafeBytes: rawBuffer)
60
- return try body ( & span)
61
- }
62
- } catch {
63
- // Workaround for lack of typed-throwing API on Collection
64
- // swift-format-ignore: NeverForceUnwrap
65
- throw error as! ThrownParsingError
63
+
64
+ let result = self . withContiguousStorageIfAvailable { buffer in
65
+ let rawBuffer = UnsafeRawBufferPointer ( buffer)
66
+ var span = ParserSpan ( _unsafeBytes: rawBuffer)
67
+ return Result < T , ThrownParsingError > { try body ( & span) }
68
+ }
69
+ switch result {
70
+ case . success ( let t ) : return t
71
+ case . failure ( let e ) : throw e
72
+ case nil : return nil
66
73
}
67
74
}
68
75
}
69
76
70
77
// MARK: ParserSpanProvider
71
78
72
79
public protocol ParserSpanProvider {
73
- func withParserSpan< T> (
74
- _ body: ( inout ParserSpan ) throws ( ThrownParsingError ) -> T
75
- ) throws ( ThrownParsingError ) -> T
80
+ func withParserSpan< T, E > (
81
+ _ body: ( inout ParserSpan ) throws ( E ) -> T
82
+ ) throws ( E ) -> T
76
83
}
77
84
78
- #if canImport(Foundation)
79
- extension Data : ParserSpanProvider {
85
+ extension ParserSpanProvider {
86
+ #if !$Embedded
87
+ @_alwaysEmitIntoClient
80
88
@inlinable
81
89
public func withParserSpan< T> (
82
- _ body: ( inout ParserSpan ) throws ( ThrownParsingError ) -> T
83
- ) throws ( ThrownParsingError) -> T {
84
- do {
85
- return try withUnsafeBytes { buffer -> T in
86
- // FIXME: RawSpan getter
87
- // var span = ParserSpan(buffer.bytes)
88
- var span = ParserSpan ( _unsafeBytes: buffer)
89
- return try body ( & span)
90
- }
91
- } catch {
92
- // Workaround for lack of typed-throwing API on Data
93
- // swift-format-ignore: NeverForceUnwrap
94
- throw error as! ThrownParsingError
90
+ usingRange range: inout ParserRange ,
91
+ _ body: ( inout ParserSpan ) throws -> T
92
+ ) throws -> T {
93
+ try withParserSpan { span in
94
+ var subspan = try span. seeking ( toRange: range)
95
+ defer { range = subspan. parserRange }
96
+ return try body ( & subspan)
95
97
}
96
98
}
99
+ #endif
97
100
98
101
@_alwaysEmitIntoClient
99
102
@inlinable
100
103
public func withParserSpan< T> (
101
104
usingRange range: inout ParserRange ,
102
- _ body: ( inout ParserSpan ) throws ( ThrownParsingError ) -> T
103
- ) throws ( ThrownParsingError) -> T {
104
- do {
105
- return try withUnsafeBytes { ( buffer) throws ( ThrownParsingError) -> T in
106
- // FIXME: RawSpan getter
107
- // var span = try ParserSpan(buffer.bytes)
108
- var span = try ParserSpan ( _unsafeBytes: buffer)
109
- . seeking ( toRange: range)
110
- defer {
111
- range = span. parserRange
112
- }
113
- return try body ( & span)
114
- }
115
- } catch {
116
- // Workaround for lack of typed-throwing API on Data
117
- // swift-format-ignore: NeverForceUnwrap
118
- throw error as! ThrownParsingError
105
+ _ body: ( inout ParserSpan ) throws ( ParsingError ) -> T
106
+ ) throws ( ParsingError) -> T {
107
+ try withParserSpan { ( span) throws ( ParsingError) in
108
+ var subspan = try span. seeking ( toRange: range)
109
+ defer { range = subspan. parserRange }
110
+ return try body ( & subspan)
119
111
}
120
112
}
121
113
}
122
- #endif
123
114
124
- extension ParserSpanProvider where Self : RandomAccessCollection < UInt8 > {
125
- @ discardableResult
115
+ #if canImport(Foundation)
116
+ extension Data : ParserSpanProvider {
126
117
@inlinable
127
- public func withParserSpan< T> (
128
- _ body: ( inout ParserSpan ) throws ( ThrownParsingError ) -> T
129
- ) throws ( ThrownParsingError) -> T {
130
- do {
131
- guard
132
- let result = try self . withContiguousStorageIfAvailable ( { buffer in
133
- // FIXME: RawSpan getter
134
- // var span = ParserSpan(UnsafeRawBufferPointer(buffer).bytes)
135
- let rawBuffer = UnsafeRawBufferPointer ( buffer)
136
- var span = ParserSpan ( _unsafeBytes: rawBuffer)
137
- return try body ( & span)
138
- } )
139
- else {
140
- throw ParsingError ( status: . userError, location: 0 )
141
- }
142
- return result
143
- } catch {
144
- // Workaround for lack of typed-throwing API on Collection
145
- // swift-format-ignore: NeverForceUnwrap
146
- throw error as! ThrownParsingError
118
+ public func withParserSpan< T, E> (
119
+ _ body: ( inout ParserSpan ) throws ( E ) -> T
120
+ ) throws ( E) -> T {
121
+ let result = withUnsafeBytes { buffer in
122
+ var span = ParserSpan ( _unsafeBytes: buffer)
123
+ return Result < T , E > { ( ) throws ( E) in try body ( & span) }
124
+ }
125
+ switch result {
126
+ case . success( let t) : return t
127
+ case . failure( let e) : throw e
128
+ }
129
+ }
130
+ }
131
+ #endif
132
+
133
+ extension [ UInt8 ] : ParserSpanProvider {
134
+ public func withParserSpan< T, E> (
135
+ _ body: ( inout ParserSpan ) throws ( E ) -> T
136
+ ) throws ( E) -> T {
137
+ let result = self . withUnsafeBytes { rawBuffer in
138
+ var span = ParserSpan ( _unsafeBytes: rawBuffer)
139
+ return Result < T , E > { ( ) throws ( E) in try body ( & span) }
140
+ }
141
+ switch result {
142
+ case . success( let t) : return t
143
+ case . failure( let e) : throw e
147
144
}
148
145
}
149
146
}
150
147
151
- extension [ UInt8 ] : ParserSpanProvider { }
152
- extension ArraySlice < UInt8 > : ParserSpanProvider { }
148
+ extension ArraySlice < UInt8 > : ParserSpanProvider {
149
+ public func withParserSpan< T, E> (
150
+ _ body: ( inout ParserSpan ) throws ( E ) -> T
151
+ ) throws ( E) -> T {
152
+ let result = self . withUnsafeBytes { rawBuffer in
153
+ var span = ParserSpan ( _unsafeBytes: rawBuffer)
154
+ return Result < T , E > { ( ) throws ( E) in try body ( & span) }
155
+ }
156
+ switch result {
157
+ case . success( let t) : return t
158
+ case . failure( let e) : throw e
159
+ }
160
+ }
161
+ }
0 commit comments