reflect.go

v0.2.0
Doc Versions Source
1
package steward
2
3
import (
4
	"fmt"
5
	"reflect"
6
	"strings"
7
	"unicode"
8
	"unicode/utf8"
9
10
	"go.bigb.es/auxilia/collect"
11
	"go.bigb.es/auxilia/fn"
12
)
13
14
type (
15
	structField         = collect.Tuple2[reflect.StructField, reflect.Value]
16
	structFieldIterator collect.ListIterator[structField]
17
)
18
19
func structFieldIteratorFromType(p reflect.Value) structFieldIterator {
20
	if p.Kind() == reflect.Pointer {
21
		p = p.Elem()
22
	}
23
24
	if p.Kind() != reflect.Struct {
25
		panic(fmt.Sprintf("expected 'struct', got '%s'", p.Kind().String()))
26
	}
27
28
	pos := -1
29
30
	return collect.NewListIterator[structField](func() (structField, bool) {
31
		pos++
32
33
		if pos >= p.NumField() {
34
			return structField{}, false
35
		}
36
37
		return collect.NewTuple2(
38
			p.Type().Field(pos),
39
			p.Field(pos),
40
		), true
41
	}, p.NumField())
42
}
43
44
func typesEqual(l, r reflect.Type) bool {
45
	return l == r || (l.Kind() == reflect.Pointer && l.Elem() == r)
46
}
47
48
func isPublic(field reflect.StructField) bool {
49
	r, _ := utf8.DecodeRuneInString(field.Name)
50
	if r == utf8.RuneError {
51
		return false
52
	}
53
54
	return !unicode.IsLower(r)
55
}
56
57
func hasTag(field reflect.StructField, tag string) bool {
58
	return fn.SecondOf2(field.Tag.Lookup(tag))
59
}
60
61
func parseBool(in string) bool {
62
	switch strings.TrimSpace(strings.ToLower(in)) {
63
	case "true":
64
		return true
65
	default:
66
		return false
67
	}
68
}
69
70
func hasTagBool(field reflect.StructField, tagKey string) bool {
71
	rawBool, ok := field.Tag.Lookup(tagKey)
72
	if !ok {
73
		return false
74
	}
75
	return parseBool(rawBool)
76
}
77
78
func isComparable(value any) bool {
79
	return reflect.TypeOf(value).Comparable()
80
}
81
82
func isInterface(l reflect.Type) bool {
83
	return l.Kind() == reflect.Interface
84
}
85
86
func isPointerToStruct(l reflect.Type) bool {
87
	return l.Kind() == reflect.Ptr && l.Elem().Kind() == reflect.Struct
88
}
89
90
func isListOfInterfacesOrPointersToStructs(l reflect.Type) bool {
91
	return l.Kind() == reflect.Slice && (isInterface(l.Elem()) || isPointerToStruct(l.Elem()))
92
}
93
94
func isSingleInjectType(l reflect.Type) bool {
95
	return isInterface(l) || isPointerToStruct(l)
96
}
97
98
func isMultiInjectType(l reflect.Type) bool {
99
	return isListOfInterfacesOrPointersToStructs(l)
100
}
101
102
func isAllowedInjectType(l reflect.Type) bool {
103
	return isInterface(l) || isPointerToStruct(l) || isListOfInterfacesOrPointersToStructs(l)
104
}
105

Source Files