func collateFieldPath()

in lib/collections.go [991:1051]


func collateFieldPath(arg ref.Val, path types.String) []ref.Val {
	var collation []ref.Val
	switch obj := arg.(type) {
	case traits.Lister:
		it := obj.Iterator()
		for it.HasNext() == types.True {
			elem := it.Next()
			collation = append(collation, collateFieldPath(elem, path)...)
		}
		return collation

	case traits.Mapper:
		dotIdx, escaped := pathSepIndex(string(path))
		switch {
		case dotIdx == 0, dotIdx == len(path)-1:
			panic(types.NewErr("invalid parameter path for drop: %s", path))

		case dotIdx < 0:
			m, err := obj.ConvertToNative(refValMap)
			if err != nil {
				panic(types.NewErr("unable to convert map to native: %v", err))
			}
			for k, v := range m.(map[ref.Val]ref.Val) {
				if k.Equal(path) == types.True {
					switch v := v.(type) {
					case traits.Lister:
						it := v.Iterator()
						for it.HasNext() == types.True {
							collation = append(collation, it.Next())
						}
					default:
						collation = append(collation, v)
					}
				}
			}

		default:
			m, err := obj.ConvertToNative(refValMap)
			if err != nil {
				panic(types.NewErr("unable to convert map to native: %v", err))
			}
			head := path[:dotIdx]
			if escaped {
				head = types.String(strings.ReplaceAll(string(head), `\.`, "."))
			}
			tail := path[dotIdx+1:]
			for k, v := range m.(map[ref.Val]ref.Val) {
				if k.Equal(head) == types.True {
					collation = append(collation, collateFieldPath(v, tail)...)
				}
			}
		}

	default:
		if path == "" {
			collation = []ref.Val{obj}
		}
	}

	return collation
}