@@ -19,6 +19,15 @@ public protocol ExpressibleByParsing {
1919}
2020
2121extension 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
2231 public init ( parsing data: some RandomAccessCollection < UInt8 > )
2332 throws ( ThrownParsingError)
2433 {
@@ -41,112 +50,112 @@ extension RandomAccessCollection<UInt8> {
4150 ) throws ( ThrownParsingError) -> T ? {
4251 #if canImport(Foundation)
4352 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
5360 }
5461 }
5562 #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
6673 }
6774 }
6875}
6976
7077// MARK: ParserSpanProvider
7178
7279public 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
7683}
7784
78- #if canImport(Foundation)
79- extension Data : ParserSpanProvider {
85+ extension ParserSpanProvider {
86+ #if !$Embedded
87+ @_alwaysEmitIntoClient
8088 @inlinable
8189 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)
9597 }
9698 }
99+ #endif
97100
98101 @_alwaysEmitIntoClient
99102 @inlinable
100103 public func withParserSpan< T> (
101104 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)
119111 }
120112 }
121113}
122- #endif
123114
124- extension ParserSpanProvider where Self : RandomAccessCollection < UInt8 > {
125- @ discardableResult
115+ #if canImport(Foundation)
116+ extension Data : ParserSpanProvider {
126117 @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
147144 }
148145 }
149146}
150147
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