| 177 | } |
| 178 | |
| 179 | func (t *parser) key(data map[string]any, nestedNameLevel int) (reterr error) { |
| 180 | defer func() { |
| 181 | if r := recover(); r != nil { |
| 182 | reterr = fmt.Errorf("unable to parse key: %s", r) |
| 183 | } |
| 184 | }() |
| 185 | stop := runeSet([]rune{'=', '[', ',', '.'}) |
| 186 | for { |
| 187 | switch k, last, err := runesUntil(t.sc, stop); { |
| 188 | case err != nil: |
| 189 | if len(k) == 0 { |
| 190 | return err |
| 191 | } |
| 192 | return fmt.Errorf("key %q has no value", string(k)) |
| 193 | //set(data, string(k), "") |
| 194 | //return err |
| 195 | case last == '[': |
| 196 | // We are in a list index context, so we need to set an index. |
| 197 | i, err := t.keyIndex() |
| 198 | if err != nil { |
| 199 | return fmt.Errorf("error parsing index: %w", err) |
| 200 | } |
| 201 | kk := string(k) |
| 202 | // Find or create target list |
| 203 | list := []any{} |
| 204 | if _, ok := data[kk]; ok { |
| 205 | list = data[kk].([]any) |
| 206 | } |
| 207 | |
| 208 | // Now we need to get the value after the ]. |
| 209 | list, err = t.listItem(list, i, nestedNameLevel) |
| 210 | set(data, kk, list) |
| 211 | return err |
| 212 | case last == '=': |
| 213 | if t.isjsonval { |
| 214 | empval, err := t.emptyVal() |
| 215 | if err != nil { |
| 216 | return err |
| 217 | } |
| 218 | if empval { |
| 219 | set(data, string(k), nil) |
| 220 | return nil |
| 221 | } |
| 222 | // parse jsonvals by using Go’s JSON standard library |
| 223 | // Decode is preferred to Unmarshal in order to parse just the json parts of the list key1=jsonval1,key2=jsonval2,... |
| 224 | // Since Decode has its own buffer that consumes more characters (from underlying t.sc) than the ones actually decoded, |
| 225 | // we invoke Decode on a separate reader built with a copy of what is left in t.sc. After Decode is executed, we |
| 226 | // discard in t.sc the chars of the decoded json value (the number of those characters is returned by InputOffset). |
| 227 | var jsonval any |
| 228 | dec := json.NewDecoder(strings.NewReader(t.sc.String())) |
| 229 | if err = dec.Decode(&jsonval); err != nil { |
| 230 | return err |
| 231 | } |
| 232 | set(data, string(k), jsonval) |
| 233 | if _, err = io.CopyN(io.Discard, t.sc, dec.InputOffset()); err != nil { |
| 234 | return err |
| 235 | } |
| 236 | // skip possible blanks and comma |