(t reflect.Type, ops ...option)
| 120 | } |
| 121 | |
| 122 | func (c *Context) use(t reflect.Type, ops ...option) *Type { |
| 123 | config := &config{} |
| 124 | for _, op := range ops { |
| 125 | op(config) |
| 126 | } |
| 127 | |
| 128 | methods := make([]reflect.Method, 0) |
| 129 | |
| 130 | // Methods of struct should be gathered from original struct with pointer, |
| 131 | // as methods maybe declared on pointer receiver. Also this method retrieves |
| 132 | // all embedded structs methods as well, no need to recursion. |
| 133 | for i := 0; i < t.NumMethod(); i++ { |
| 134 | m := t.Method(i) |
| 135 | if isPrivate(m.Name) || isProtobuf(m.Name) { |
| 136 | continue |
| 137 | } |
| 138 | methods = append(methods, m) |
| 139 | } |
| 140 | |
| 141 | t = deref.Type(t) |
| 142 | |
| 143 | // Only named types will have methods defined on them. |
| 144 | // It maybe not even struct, but we gonna call then |
| 145 | // structs in appendix anyway. |
| 146 | if len(methods) > 0 { |
| 147 | goto appendix |
| 148 | } |
| 149 | |
| 150 | // This switch only for "simple" types. |
| 151 | switch t.Kind() { |
| 152 | case reflect.Bool: |
| 153 | return &Type{Kind: "bool"} |
| 154 | |
| 155 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: |
| 156 | fallthrough |
| 157 | |
| 158 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: |
| 159 | return &Type{Kind: "int"} |
| 160 | |
| 161 | case reflect.Float32, reflect.Float64: |
| 162 | return &Type{Kind: "float"} |
| 163 | |
| 164 | case reflect.String: |
| 165 | return &Type{Kind: "string"} |
| 166 | |
| 167 | case reflect.Interface: |
| 168 | return &Type{Kind: "any"} |
| 169 | |
| 170 | case reflect.Array, reflect.Slice: |
| 171 | return &Type{ |
| 172 | Kind: "array", |
| 173 | Type: c.use(t.Elem()), |
| 174 | } |
| 175 | |
| 176 | case reflect.Map: |
| 177 | return &Type{ |
| 178 | Kind: "map", |
| 179 | Key: c.use(t.Key()), |
no test coverage detected