MCPcopy Create free account
hub / github.com/TheThingsNetwork/lorawan-stack / valueFromReflect

Function valueFromReflect

pkg/goproto/struct.go:160–242  ·  view source on GitHub ↗
(rv reflect.Value, opts ...Option)

Source from the content-addressed store, hash-verified

158}
159
160func valueFromReflect(rv reflect.Value, opts ...Option) (*structpb.Value, error) {
161 switch k := rv.Kind(); k {
162 case reflect.Pointer:
163 if rv.IsNil() {
164 return &structpb.Value{Kind: &structpb.Value_NullValue{}}, nil
165 }
166 // It is not possible to have an infinite pointer type
167 // (pointer to pointer ad infinitum) without type erasure (interface{}).
168 // As such, it is not required to increase the stack depth while dealing
169 // with pointers, since a raw interface{} cannot be marshalled.
170 return valueFromReflect(rv.Elem(), opts...)
171 case reflect.String:
172 return &structpb.Value{Kind: &structpb.Value_StringValue{StringValue: rv.String()}}, nil
173
174 case reflect.Bool:
175 return &structpb.Value{Kind: &structpb.Value_BoolValue{BoolValue: rv.Bool()}}, nil
176
177 case reflect.Slice, reflect.Array:
178 if k == reflect.Slice && rv.IsNil() {
179 return &structpb.Value{Kind: &structpb.Value_NullValue{}}, nil
180 }
181 s := make([]any, rv.Len())
182 for i := 0; i < rv.Len(); i++ {
183 s[i] = rv.Index(i).Interface()
184 }
185 pv, err := List(s, opts...)
186 if err != nil {
187 return nil, err
188 }
189 return &structpb.Value{Kind: &structpb.Value_ListValue{ListValue: pv}}, nil
190
191 case reflect.Map:
192 if rv.IsNil() {
193 return &structpb.Value{Kind: &structpb.Value_NullValue{}}, nil
194 }
195 m := make(map[string]any, rv.Len())
196 for _, key := range rv.MapKeys() {
197 m[fmt.Sprint(key.Interface())] = rv.MapIndex(key).Interface()
198 }
199 pv, err := Struct(m, opts...)
200 if err != nil {
201 return nil, err
202 }
203 return &structpb.Value{Kind: &structpb.Value_StructValue{StructValue: pv}}, nil
204
205 case reflect.Struct:
206 state, err := createSerializationState(opts...)
207 if err != nil {
208 return nil, err
209 }
210 n := rv.NumField()
211 fields := make(map[string]*structpb.Value, n)
212 for i := range n {
213 f := rv.Field(i)
214 ft := f.Type()
215 if f.Type().PkgPath() != "" {
216 continue
217 }

Callers 1

ValueFunction · 0.85

Calls 10

StructFunction · 0.85
createSerializationStateFunction · 0.85
RecurseMethod · 0.80
ListFunction · 0.70
StringMethod · 0.65
FieldMethod · 0.65
NameMethod · 0.65
ErrorfMethod · 0.65
LenMethod · 0.45
TypeMethod · 0.45

Tested by

no test coverage detected