func()

in wstl1/mapping_engine/util/jsonutil/jsonutil.go [207:279]


func (w DefaultAccessor) getFieldSegmented(src JSONToken, segments []string) (JSONToken, error) {
	if len(segments) == 0 {
		return src, nil
	}
	if src == nil {
		return nil, nil
	}

	seg := segments[0]

	switch o := src.(type) {
	case JSONArr:
		if seg == "[]" {
			return nil, fmt.Errorf("expected an array index with brackets like [123] but got []")
		}
		if !IsIndex(seg) {
			return nil, fmt.Errorf("expected an array index with brackets like [123] but got %s", seg)
		}

		idxSubstr := seg[1 : len(seg)-1]

		if idxSubstr == "*" {
			flatten := JSONArr{}

			for i := range o {
				f, err := w.getFieldSegmented(o[i], segments[1:])
				if err != nil {
					return nil, fmt.Errorf("error expanding [*] on item index %d: %v", i, err)
				}

				// If an array expansion occurs down the line, we need to unnest the resulting array here.
				if f != nil && hasArrayStar(segments[1:]) {
					fArr, ok := f.(JSONArr)
					if !ok {
						return nil, fmt.Errorf("this is an internal bug: found nested [*] but value was not an array (was %T)", f)
					}
					flatten = append(flatten, fArr...)
				} else {
					flatten = append(flatten, f)
				}
			}

			return flatten, nil
		}

		idx, err := strconv.Atoi(idxSubstr)
		if err != nil {
			return nil, fmt.Errorf("could not parse array index %s: %v", seg, err)
		}
		if idx < 0 {
			return nil, fmt.Errorf("negative array indices are not supported but got %d", idx)
		}
		if idx >= len(o) {
			// TODO(): Consider returning a different value for fields that don't exist vs
			// fields that are actually set to null.
			return nil, nil
		}
		return w.getFieldSegmented(o[idx], segments[1:])
	case JSONContainer:
		if seg == "" || seg == "." {
			return w.getFieldSegmented(o, segments[1:])
		}
		if item, ok := o[seg]; ok {
			return w.getFieldSegmented(*item, segments[1:])
		}
		// TODO(): Consider returning a different value for fields that don't exist vs
		// fields that are actually set to null.
		return nil, nil
	case JSONNum, JSONStr, JSONBool:
		return nil, fmt.Errorf("attempt to key into primitive with key %s", seg)
	}
	return nil, fmt.Errorf("this is an internal bug: JSON contained unknown data type %T at %s", src, seg)
}