Skip to content

Commit 2b61003

Browse files
committed
Support structpb too
1 parent 219b268 commit 2b61003

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed

cli/any.go

+60
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ import (
44
"fmt"
55
"log/slog"
66
"strconv"
7+
"strings"
78

89
pythonv1 "buf.build/gen/go/stealthrocket/dispatch-proto/protocolbuffers/go/dispatch/sdk/python/v1"
910
"google.golang.org/protobuf/types/known/anypb"
1011
"google.golang.org/protobuf/types/known/durationpb"
1112
"google.golang.org/protobuf/types/known/emptypb"
13+
"google.golang.org/protobuf/types/known/structpb"
1214
"google.golang.org/protobuf/types/known/timestamppb"
1315
"google.golang.org/protobuf/types/known/wrapperspb"
1416
)
@@ -67,6 +69,15 @@ func anyString(any *anypb.Any) string {
6769
case *durationpb.Duration:
6870
return mm.AsDuration().String()
6971

72+
case *structpb.Struct:
73+
return structpbStructString(mm)
74+
75+
case *structpb.ListValue:
76+
return structpbListString(mm)
77+
78+
case *structpb.Value:
79+
return structpbValueString(mm)
80+
7081
case *pythonv1.Pickled:
7182
s, err := pythonPickleString(mm.PickledValue)
7283
if err != nil {
@@ -79,6 +90,55 @@ func anyString(any *anypb.Any) string {
7990
}
8091
}
8192

93+
func structpbStructString(s *structpb.Struct) string {
94+
var b strings.Builder
95+
b.WriteByte('{')
96+
i := 0
97+
for name, value := range s.Fields {
98+
if i > 0 {
99+
b.WriteString(", ")
100+
}
101+
b.WriteString(fmt.Sprintf("%q", name))
102+
b.WriteString(": ")
103+
b.WriteString(structpbValueString(value))
104+
i++
105+
}
106+
b.WriteByte('}')
107+
return b.String()
108+
}
109+
110+
func structpbListString(s *structpb.ListValue) string {
111+
var b strings.Builder
112+
b.WriteByte('[')
113+
for i, value := range s.Values {
114+
if i > 0 {
115+
b.WriteString(", ")
116+
}
117+
b.WriteString(structpbValueString(value))
118+
}
119+
b.WriteByte(']')
120+
return b.String()
121+
}
122+
123+
func structpbValueString(s *structpb.Value) string {
124+
switch v := s.Kind.(type) {
125+
case *structpb.Value_StructValue:
126+
return structpbStructString(v.StructValue)
127+
case *structpb.Value_ListValue:
128+
return structpbListString(v.ListValue)
129+
case *structpb.Value_BoolValue:
130+
return strconv.FormatBool(v.BoolValue)
131+
case *structpb.Value_NumberValue:
132+
return fmt.Sprintf("%v", v.NumberValue)
133+
case *structpb.Value_StringValue:
134+
return fmt.Sprintf("%q", v.StringValue)
135+
case *structpb.Value_NullValue:
136+
return "null"
137+
default:
138+
panic("unreachable")
139+
}
140+
}
141+
82142
func unsupportedAny(any *anypb.Any, err error) string {
83143
if err != nil {
84144
slog.Debug("cannot parse input/output value", "error", err)

cli/any_test.go

+37
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"google.golang.org/protobuf/types/known/anypb"
1010
"google.golang.org/protobuf/types/known/durationpb"
1111
"google.golang.org/protobuf/types/known/emptypb"
12+
"google.golang.org/protobuf/types/known/structpb"
1213
"google.golang.org/protobuf/types/known/timestamppb"
1314
"google.golang.org/protobuf/types/known/wrapperspb"
1415
)
@@ -91,6 +92,34 @@ func TestAnyString(t *testing.T) {
9192
input: asAny(&emptypb.Empty{}),
9293
want: "empty()",
9394
},
95+
{
96+
input: asAny(structpb.NewNullValue()),
97+
want: "null",
98+
},
99+
{
100+
input: asAny(structpb.NewBoolValue(false)),
101+
want: "false",
102+
},
103+
{
104+
input: asAny(structpb.NewNumberValue(1111)),
105+
want: "1111",
106+
},
107+
{
108+
input: asAny(structpb.NewNumberValue(3.14)),
109+
want: "3.14",
110+
},
111+
{
112+
input: asAny(structpb.NewStringValue("foobar")),
113+
want: `"foobar"`,
114+
},
115+
{
116+
input: asStructValue([]any{1, true, "abc", nil, map[string]any{}, []any{}}),
117+
want: `[1, true, "abc", null, {}, []]`,
118+
},
119+
{
120+
input: asStructValue(map[string]any{"foo": []any{"bar", "baz"}}),
121+
want: `{"foo": ["bar", "baz"]}`,
122+
},
94123
} {
95124
t.Run(test.want, func(*testing.T) {
96125
got := anyString(test.input)
@@ -109,6 +138,14 @@ func asAny(m proto.Message) *anypb.Any {
109138
return any
110139
}
111140

141+
func asStructValue(v any) *anypb.Any {
142+
m, err := structpb.NewValue(v)
143+
if err != nil {
144+
panic(err)
145+
}
146+
return asAny(m)
147+
}
148+
112149
func pickled(b []byte) *anypb.Any {
113150
m := &pythonv1.Pickled{PickledValue: b}
114151
mb, err := proto.Marshal(m)

0 commit comments

Comments
 (0)