handle empty lists for yaml and json formatted lists in tctl#33547
handle empty lists for yaml and json formatted lists in tctl#33547stevenGravy merged 15 commits intomasterfrom
Conversation
zmb3
left a comment
There was a problem hiding this comment.
This is a pretty unidiomatic thing to do, normally we prefer the zero value (a nil slice).
Let's move this special case down for each branch so that it is only performed if the serialization format is JSON/YAML.
| return data, nil | ||
| } | ||
|
|
||
| // WriteJSON marshals array as a JSON list with indentation. |
There was a problem hiding this comment.
We should have tests for these that ensure that nil slices/maps get marshaled to [] and {}.
There was a problem hiding this comment.
A test for this would be good, since it looks like there is a bug there.
Co-authored-by: Zac Bergquist <zac.bergquist@goteleport.com>
Co-authored-by: Zac Bergquist <zac.bergquist@goteleport.com>
camscale
left a comment
There was a problem hiding this comment.
One bug I think - the others are a matter of taste - happy for you to ignore those.
I haven't approved because you have auto-merge on and I don't want the bug merged.
| // WriteJSONArray marshals values as a JSON array. | ||
| func WriteJSONArray[T any](w io.Writer, values []T) error { | ||
| if len(values) == 0 { | ||
| _, err := w.Write([]byte("[]")) |
There was a problem hiding this comment.
Rather that writing a string/bytes directly, perhaps just let json.Marshal do it. null is emitted for nil slices, and [] for empty non-nil slices (see https://go.dev/play/p/MUAis-9xFXn). So perhaps just convert it to a non-nil slice if nil?
if values == nil {
values = []T{}
}
return writeJSON(w, values)
| // WriteJSONObject marshals m as a JSON object. | ||
| func WriteJSONObject[M ~map[K]V, K comparable, V any](w io.Writer, m M) error { | ||
| if len(m) == 0 { | ||
| _, err := w.Write([]byte("[]")) |
There was a problem hiding this comment.
same here wrt nil vs empty:
if m == nil {
m = map[K]V{}
}
return writeJSON(w, m)
| // first pass makes sure that all values are documents (objects or maps) | ||
| slice := reflect.ValueOf(values) | ||
| if slice.Len() == 0 { | ||
| _, err := w.Write([]byte("[]")) |
There was a problem hiding this comment.
there's probably a way to get reflect to produce a non-nil slice, but every time I look at those package docs, I don't come away in less than half an hour :) Probably MakeSlice() but the way you have it is probably simpler in this specific case.
|
@stevenGravy See the table below for backport results.
|
fixes #33537 and #18672
This adds handling like
tshfor giving empty YAML and JSON formatted results. Currently this can return null or a text message of no values.ex:
Now returns