-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathstruct.go
89 lines (79 loc) · 2.11 KB
/
struct.go
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
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package argmapper
import "reflect"
// Struct should be embedded into any struct where the parameters are
// populated. This lets argmapper differentiate between arguments
// where you want the full struct provided or fields within the struct.
//
// Example:
//
// type MyParams {
// argmapper.Struct
//
// // A and B will be populated through injection.
// A, B int
// }
//
// If the embedded Struct was left out, argmapper would look for
// a full MyParams type to inject.
//
// Named Parameters
//
// By default, the field name is the name of the parameter. In the
// example above, MyParams expects parameters named "A" and "B", both of
// type int.
//
// Parameter names are case insensitive.
//
// Parameters can be renamed using a struct tag. The example below
// renames the field "A" to "B".
//
// type MyParams {
// argmapper.Struct
//
// A int `argmapper:"B"`
// }
//
// Typed Parameters
//
// A field in the struct can be marked as typed only using struct tags.
// The field name of a typed field is ignored and argmapper will match it
// to any matching type.
//
// type MyParams {
// argmapper.Struct
//
// A int `argmapper:",typeOnly"`
// }
//
// Note the comma before the "typeOnly" string. The comma is necessary
// so tell argmapper you're setting an option versus renaming a field.
type Struct struct {
structInterface
}
// structInterface so that users can't just embed any struct{} type.
type structInterface interface {
argmapperStruct()
}
// isStruct returns true if the given type is a struct that embeds our
// struct marker.
func isStruct(t reflect.Type) bool {
for t.Kind() == reflect.Ptr {
t = t.Elem()
}
if t.Kind() != reflect.Struct {
return false
}
for i := 0; i < t.NumField(); i++ {
if isStructField(t.Field(i)) {
return true
}
}
return false
}
// isStructField returns true if the given struct field is our struct marker.
func isStructField(f reflect.StructField) bool {
return f.Anonymous && f.Type == structMarkerType
}
var structMarkerType = reflect.TypeOf((*Struct)(nil)).Elem()