mirror of
https://github.com/pomerium/pomerium.git
synced 2025-04-29 10:26:29 +02:00
119 lines
2.9 KiB
Go
119 lines
2.9 KiB
Go
// Package protoutil contains functions for working with protobuf types.
|
|
package protoutil
|
|
|
|
import (
|
|
"fmt"
|
|
"reflect"
|
|
|
|
"google.golang.org/protobuf/encoding/protojson"
|
|
"google.golang.org/protobuf/proto"
|
|
"google.golang.org/protobuf/types/known/structpb"
|
|
)
|
|
|
|
// ToStruct converts any value into a structpb Value.
|
|
func ToStruct(value any) *structpb.Value {
|
|
if value == nil {
|
|
return NewStructNull()
|
|
}
|
|
|
|
switch v := value.(type) {
|
|
case bool:
|
|
return NewStructBool(v)
|
|
case float64:
|
|
return NewStructNumber(v)
|
|
case float32:
|
|
return NewStructNumber(float64(v))
|
|
case int:
|
|
return NewStructNumber(float64(v))
|
|
case int8:
|
|
return NewStructNumber(float64(v))
|
|
case int16:
|
|
return NewStructNumber(float64(v))
|
|
case int32:
|
|
return NewStructNumber(float64(v))
|
|
case int64:
|
|
return NewStructNumber(float64(v))
|
|
case string:
|
|
return NewStructString(v)
|
|
case uint:
|
|
return NewStructNumber(float64(v))
|
|
case uint8:
|
|
return NewStructNumber(float64(v))
|
|
case uint16:
|
|
return NewStructNumber(float64(v))
|
|
case uint32:
|
|
return NewStructNumber(float64(v))
|
|
case uint64:
|
|
return NewStructNumber(float64(v))
|
|
}
|
|
|
|
if msg, ok := value.(proto.Message); ok {
|
|
bs, _ := protojson.Marshal(msg)
|
|
var s structpb.Struct
|
|
_ = protojson.Unmarshal(bs, &s)
|
|
return &structpb.Value{
|
|
Kind: &structpb.Value_StructValue{StructValue: &s},
|
|
}
|
|
}
|
|
|
|
rv := reflect.ValueOf(value)
|
|
switch rv.Kind() {
|
|
case reflect.Slice:
|
|
svs := make([]*structpb.Value, rv.Len())
|
|
for i := range svs {
|
|
svs[i] = ToStruct(rv.Index(i).Interface())
|
|
}
|
|
return NewStructList(svs...)
|
|
case reflect.Map:
|
|
svm := make(map[string]*structpb.Value)
|
|
iter := rv.MapRange()
|
|
for iter.Next() {
|
|
svm[fmt.Sprint(iter.Key().Interface())] = ToStruct(iter.Value().Interface())
|
|
}
|
|
return NewStructMap(svm)
|
|
}
|
|
|
|
return NewStructNull()
|
|
}
|
|
|
|
// NewStructBool creates a new bool struct value.
|
|
func NewStructBool(v bool) *structpb.Value {
|
|
return &structpb.Value{
|
|
Kind: &structpb.Value_BoolValue{BoolValue: v},
|
|
}
|
|
}
|
|
|
|
// NewStructMap creates a new map struct value.
|
|
func NewStructMap(v map[string]*structpb.Value) *structpb.Value {
|
|
return &structpb.Value{
|
|
Kind: &structpb.Value_StructValue{StructValue: &structpb.Struct{Fields: v}},
|
|
}
|
|
}
|
|
|
|
// NewStructNull creates a new null struct value.
|
|
func NewStructNull() *structpb.Value {
|
|
return &structpb.Value{
|
|
Kind: &structpb.Value_NullValue{},
|
|
}
|
|
}
|
|
|
|
// NewStructNumber creates a new number struct value.
|
|
func NewStructNumber(v float64) *structpb.Value {
|
|
return &structpb.Value{
|
|
Kind: &structpb.Value_NumberValue{NumberValue: v},
|
|
}
|
|
}
|
|
|
|
// NewStructList creates a new list struct value.
|
|
func NewStructList(vs ...*structpb.Value) *structpb.Value {
|
|
return &structpb.Value{
|
|
Kind: &structpb.Value_ListValue{ListValue: &structpb.ListValue{Values: vs}},
|
|
}
|
|
}
|
|
|
|
// NewStructString creates a new string struct value.
|
|
func NewStructString(v string) *structpb.Value {
|
|
return &structpb.Value{
|
|
Kind: &structpb.Value_StringValue{StringValue: v},
|
|
}
|
|
}
|