@@ -3,7 +3,9 @@ extension BufferProtocol where Element == Byte {
33 var comps : [ Leaf . Component ] = [ ]
44 while let next = try nextComponent ( ) {
55 if case let . tagTemplate( i) = next, i. isChain {
6- guard comps. count > 0 else { throw " invalid chain component w/o preceeding tagTemplate " }
6+ guard comps. count > 0 else {
7+ throw ParseError . expectedLeadingTemplate ( have: nil )
8+ }
79 while let last = comps. last {
810 var loop = true
911
@@ -30,16 +32,12 @@ extension BufferProtocol where Element == Byte {
3032
3133 mutating func nextComponent( ) throws -> Leaf . Component ? {
3234 guard let token = current else { return nil }
33- if token == TOKEN {
34- let tagTemplate = try extractInstruction ( )
35- return . tagTemplate( tagTemplate)
36- } else {
37- let raw = extractUntil { $0 == TOKEN }
38- return . raw( raw)
39- }
35+ guard token == TOKEN else { return . raw( extractUntil { $0 == TOKEN } ) }
36+ let tagTemplate = try extractInstruction ( )
37+ return . tagTemplate( tagTemplate)
4038 }
4139
42- mutating func extractUntil( _ until: @ noescape ( Element ) -> Bool ) -> [ Element ] {
40+ mutating func extractUntil( _ until: ( Element ) -> Bool ) -> [ Element ] {
4341 var collection = Bytes ( )
4442 if let current = current {
4543 guard !until( current) else { return [ ] }
@@ -53,6 +51,14 @@ extension BufferProtocol where Element == Byte {
5351 }
5452}
5553
54+ enum ParseError : LeafError {
55+ case tagTemplateNotFound( name: String )
56+ case missingBodyOpener( expected: String , have: String ? )
57+ case missingBodyCloser( expected: String )
58+ case expectedOpenParenthesis
59+ case expectedLeadingTemplate( have: Leaf . Component ? )
60+ }
61+
5662/*
5763 Syntax
5864
@@ -77,11 +83,11 @@ extension BufferProtocol where Element == Byte {
7783 }
7884
7985 mutating func extractInstructionName( ) throws -> String {
80- // can't extract section because of @@
81- guard current == TOKEN else { throw " tagTemplate name must lead with token " }
8286 moveForward ( ) // drop initial token from name. a secondary token implies chain
8387 let name = extractUntil { $0 == . openParenthesis }
84- guard current == . openParenthesis else { throw " tagTemplate names must be alphanumeric and terminated with '(' " }
88+ guard current == . openParenthesis else {
89+ throw ParseError . expectedOpenParenthesis
90+ }
8591 return name. string
8692 }
8793
@@ -98,7 +104,8 @@ extension BufferProtocol where Element == Byte {
98104
99105 mutating func extractSection( opensWith opener: Byte , closesWith closer: Byte ) throws -> Bytes {
100106 guard current == opener else {
101- throw " invalid body, missing opener: \( [ opener ] . string) "
107+ let have = current. flatMap { [ $0] } ? . string
108+ throw ParseError . missingBodyOpener ( expected: [ opener ] . string, have: have)
102109 }
103110
104111 var subBodies = 0
@@ -112,7 +119,7 @@ extension BufferProtocol where Element == Byte {
112119 }
113120
114121 guard current == closer else {
115- throw " invalid body, missing closer: \( [ closer ] . string) , got \( [ current ] ) "
122+ throw ParseError . missingBodyCloser ( expected : [ closer ] . string)
116123 }
117124
118125 return body
0 commit comments