File: func_property.go

package info (click to toggle)
dasel 2.8.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 5,844 kB
  • sloc: sh: 53; python: 21; makefile: 21; xml: 20
file content (94 lines) | stat: -rw-r--r-- 2,240 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package dasel

import (
	"fmt"
	"reflect"
	"strings"
)

type ErrPropertyNotFound struct {
	Property string
}

func (e ErrPropertyNotFound) Error() string {
	return fmt.Sprintf("property not found: %s", e.Property)
}

func (e ErrPropertyNotFound) Is(other error) bool {
	o, ok := other.(*ErrPropertyNotFound)
	if !ok {
		return false
	}
	if o.Property != "" && o.Property != e.Property {
		return false
	}
	return true
}

var PropertyFunc = BasicFunction{
	name: "property",
	runFn: func(c *Context, s *Step, args []string) (Values, error) {
		if err := requireXOrMoreArgs("property", args, 1); err != nil {
			return nil, err
		}

		input := s.inputs()

		if c.CreateWhenMissing() {
			input = input.initEmptydencodingMaps()
		}

		res := make(Values, 0)

		for _, val := range input {
			for _, property := range args {
				isOptional := strings.HasSuffix(property, "?")
				if isOptional {
					property = strings.TrimSuffix(property, "?")
				}

				switch val.Kind() {
				case reflect.Map:
					index := val.MapIndex(ValueOf(property))
					if index.IsEmpty() {
						if isOptional {
							continue
						}
						if !c.CreateWhenMissing() {
							return nil, fmt.Errorf("could not access map index: %w", &ErrPropertyNotFound{Property: property})
						}
						index = index.asUninitialised()
					}
					res = append(res, index)
				case reflect.Struct:
					value := val.FieldByName(property)
					if value.IsEmpty() {
						if isOptional {
							continue
						}
						return nil, fmt.Errorf("could not access struct field: %w", &ErrPropertyNotFound{Property: property})
					}
					res = append(res, value)
				default:
					if val.IsDencodingMap() {
						index := val.dencodingMapIndex(ValueOf(property))
						if index.IsEmpty() {
							if isOptional {
								continue
							}
							if !c.CreateWhenMissing() {
								return nil, fmt.Errorf("could not access map index: %w", &ErrPropertyNotFound{Property: property})
							}
							index = index.asUninitialised()
						}
						res = append(res, index)
					} else {
						return nil, fmt.Errorf("cannot use property selector on non map/struct types: %s: %w", val.Kind().String(), &ErrPropertyNotFound{Property: property})
					}
				}
			}
		}

		return res, nil
	},
}