1 package jreader 2 3 // ArrayState is returned by Reader's Array and ArrayOrNull methods. Use it in conjunction with 4 // Reader to iterate through a JSON array. To read the value of each array element, you will still 5 // use the Reader's methods. 6 // 7 // This example reads an array of strings; if there is a null instead of an array, it behaves the 8 // same as for an empty array. Note that it is not necessary to check for an error result before 9 // iterating over the ArrayState, or to break out of the loop if String causes an error, because 10 // the ArrayState's Next method will return false if the Reader has had any errors. 11 // 12 // var values []string 13 // for arr := r.ArrayOrNull(); arr.Next(); { 14 // if s := r.String(); r.Error() == nil { 15 // values = append(values, s) 16 // } 17 // } 18 type ArrayState struct { 19 r *Reader 20 afterFirst bool 21 } 22 23 // IsDefined returns true if the ArrayState represents an actual array, or false if it was 24 // parsed from a null value or was the result of an error. If IsDefined is false, Next will 25 // always return false. The zero value ArrayState{} returns false for IsDefined. 26 func (arr *ArrayState) IsDefined() bool { 27 return arr.r != nil 28 } 29 30 // Next checks whether an array element is available and returns true if so. It returns false 31 // if the Reader has reached the end of the array, or if any previous Reader operation failed, 32 // or if the array was empty or null. 33 // 34 // If Next returns true, you can then use Reader methods such as Bool or String to read the 35 // element value. If you do not care about the value, simply calling Next again without calling 36 // a Reader method will discard the value, just as if you had called SkipValue on the reader. 37 // 38 // See ArrayState for example code. 39 func (arr *ArrayState) Next() bool { 40 if arr.r == nil || arr.r.err != nil { 41 return false 42 } 43 var isEnd bool 44 var err error 45 if arr.afterFirst { 46 if arr.r.awaitingReadValue { 47 if err := arr.r.SkipValue(); err != nil { 48 return false 49 } 50 } 51 isEnd, err = arr.r.tr.EndDelimiterOrComma(']') 52 } else { 53 arr.afterFirst = true 54 isEnd, err = arr.r.tr.Delimiter(']') 55 } 56 if err != nil { 57 arr.r.AddError(err) 58 return false 59 } 60 if !isEnd { 61 arr.r.awaitingReadValue = true 62 } 63 return !isEnd 64 } 65