func dropFieldPath()

in lib/collections.go [847:911]


func dropFieldPath(arg ref.Val, path types.String) (val ref.Val) {
	defer func() {
		switch err := recover().(type) {
		case *types.Err:
			val = err
		}
	}()
	if !hasFieldPath(arg, path) {
		return arg
	}

	switch obj := arg.(type) {
	case traits.Lister:
		new := make([]ref.Val, 0, obj.Size().Value().(int64))
		it := obj.Iterator()
		for it.HasNext() == types.True {
			elem := it.Next()
			new = append(new, dropFieldPath(elem, path))
		}
		return types.NewRefValList(types.DefaultTypeAdapter, new)

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

		case dotIdx < 0:
			new := make(map[ref.Val]ref.Val)
			m, err := obj.ConvertToNative(refValMap)
			if err != nil {
				return 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.False {
					new[k] = v
				}
			}
			return types.NewRefValMap(types.DefaultTypeAdapter, new)

		default:
			new := make(map[ref.Val]ref.Val)
			m, err := obj.ConvertToNative(refValMap)
			if err != nil {
				return 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 {
					new[head] = dropFieldPath(v, tail)
				} else {
					new[k] = v
				}
			}
			return types.NewRefValMap(types.DefaultTypeAdapter, new)
		}

	default:
		return obj
	}
}