@@ -9,6 +9,17 @@ import (
99 "unsafe"
1010)
1111
12+ // Errors
13+ var (
14+ KeyPathNotFoundError = errors .New ("Key path not found" )
15+ UnknownValueTypeError = errors .New ("Unknown value type" )
16+ MalformedJsonError = errors .New ("Malformed JSON error" )
17+ MalformedStringError = errors .New ("Value is string, but can't find closing '\" ' symbol" )
18+ MalformedArrayError = errors .New ("Value is array, but can't find closing ']' symbol" )
19+ MalformedObjectError = errors .New ("Value looks like object, but can't find closing '}' symbol" )
20+ MalformedValueError = errors .New ("Value looks like Number/Boolean/None, but can't find its end: ',' or '}' symbol" )
21+ )
22+
1223func tokenEnd (data []byte ) int {
1324 for i , c := range data {
1425 switch c {
@@ -186,15 +197,15 @@ If no keys provided it will try to extract closest JSON value (simple ones or ob
186197func Get (data []byte , keys ... string ) (value []byte , dataType ValueType , offset int , err error ) {
187198 if len (keys ) > 0 {
188199 if offset = searchKeys (data , keys ... ); offset == - 1 {
189- return []byte {}, NotExist , - 1 , errors . New ( "Key path not found" )
200+ return []byte {}, NotExist , - 1 , KeyPathNotFoundError
190201 }
191202 }
192203
193204 // Go to closest value
194205 nO := nextToken (data [offset :], false )
195206
196207 if nO == - 1 {
197- return []byte {}, NotExist , - 1 , errors . New ( "Malformed JSON error" )
208+ return []byte {}, NotExist , - 1 , MalformedJsonError
198209 }
199210
200211 offset += nO
@@ -206,15 +217,15 @@ func Get(data []byte, keys ...string) (value []byte, dataType ValueType, offset
206217 if idx := stringEnd (data [offset + 1 :]); idx != - 1 {
207218 endOffset += idx + 1
208219 } else {
209- return []byte {}, dataType , offset , errors . New ( "Value is string, but can't find closing ' \" ' symbol" )
220+ return []byte {}, dataType , offset , MalformedStringError
210221 }
211222 } else if data [offset ] == '[' { // if array value
212223 dataType = Array
213224 // break label, for stopping nested loops
214225 endOffset = blockEnd (data [offset :], '[' , ']' )
215226
216227 if endOffset == - 1 {
217- return []byte {}, dataType , offset , errors . New ( "Value is array, but can't find closing ']' symbol" )
228+ return []byte {}, dataType , offset , MalformedArrayError
218229 }
219230
220231 endOffset += offset
@@ -224,7 +235,7 @@ func Get(data []byte, keys ...string) (value []byte, dataType ValueType, offset
224235 endOffset = blockEnd (data [offset :], '{' , '}' )
225236
226237 if endOffset == - 1 {
227- return []byte {}, dataType , offset , errors . New ( "Value looks like object, but can't find closing '}' symbol" )
238+ return []byte {}, dataType , offset , MalformedObjectError
228239 }
229240
230241 endOffset += offset
@@ -233,7 +244,7 @@ func Get(data []byte, keys ...string) (value []byte, dataType ValueType, offset
233244 end := tokenEnd (data [endOffset :])
234245
235246 if end == - 1 {
236- return nil , dataType , offset , errors . New ( "Value looks like Number/Boolean/None, but can't find its end: ',' or '}' symbol" )
247+ return nil , dataType , offset , MalformedValueError
237248 }
238249
239250 value := data [offset : endOffset + end ]
@@ -243,18 +254,18 @@ func Get(data []byte, keys ...string) (value []byte, dataType ValueType, offset
243254 if bytes .Equal (value , trueLiteral ) || bytes .Equal (value , falseLiteral ) {
244255 dataType = Boolean
245256 } else {
246- return nil , Unknown , offset , errors . New ( "Unknown value type" )
257+ return nil , Unknown , offset , UnknownValueTypeError
247258 }
248259 case 'u' , 'n' : // undefined or null
249260 if bytes .Equal (value , nullLiteral ) {
250261 dataType = Null
251262 } else {
252- return nil , Unknown , offset , errors . New ( "Unknown value type" )
263+ return nil , Unknown , offset , UnknownValueTypeError
253264 }
254265 case '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , '-' :
255266 dataType = Number
256267 default :
257- return nil , Unknown , offset , errors . New ( "Unknown value type" )
268+ return nil , Unknown , offset , UnknownValueTypeError
258269 }
259270
260271 endOffset += end
@@ -277,27 +288,27 @@ func Get(data []byte, keys ...string) (value []byte, dataType ValueType, offset
277288// ArrayEach is used when iterating arrays, accepts a callback function with the same return arguments as `Get`.
278289func ArrayEach (data []byte , cb func (value []byte , dataType ValueType , offset int , err error ), keys ... string ) (err error ) {
279290 if len (data ) == 0 {
280- return errors . New ( "Object is empty" )
291+ return MalformedObjectError
281292 }
282293
283294 offset := 1
284295
285296 if len (keys ) > 0 {
286297 if offset = searchKeys (data , keys ... ); offset == - 1 {
287- return errors . New ( "Key path not found" )
298+ return KeyPathNotFoundError
288299 }
289300
290301 // Go to closest value
291302 nO := nextToken (data [offset :], false )
292303
293304 if nO == - 1 {
294- return errors . New ( "Malformed JSON" )
305+ return MalformedJsonError
295306 }
296307
297308 offset += nO
298309
299310 if data [offset ] != '[' {
300- return errors . New ( "Value is not array" )
311+ return MalformedArrayError
301312 }
302313
303314 offset ++
0 commit comments