From a0ab55685ca729dfb63b13b56b14c1574c1e062c Mon Sep 17 00:00:00 2001 From: Leon Mika Date: Mon, 3 Feb 2025 10:53:36 +1100 Subject: [PATCH] Added the -stdout switch --- _docs/mod/csv.md | 8 ++++++-- ucl/builtins/csv.go | 10 +++++++++- ucl/builtins/csv_test.go | 21 +++++++++++++++++++++ 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/_docs/mod/csv.md b/_docs/mod/csv.md index 8926ad1..3a43ae7 100644 --- a/_docs/mod/csv.md +++ b/_docs/mod/csv.md @@ -28,8 +28,10 @@ csv:each-record "winds.csv" { |row hdr| } ``` +### to-csv + ``` -csv:to-csv CONT [-header HEADER] +csv:to-csv CONT [-header HEADER] [-stdout] ``` Produces a CSV using the items of CONT and writes it as a string. CONT must be a list of iterator of hashable @@ -37,4 +39,6 @@ elements. If HEADER is defined, it must be a list of strings identifying the name and order of the hash keys to read from each hashable item of CONT. If HEADER is not defined, then the keys of the first consumed hashable item will be -used, with the keys sorted in alphabetical order. \ No newline at end of file +used, with the keys sorted in alphabetical order. + +If `-stdout` is set, the CSV will be written to standard out and `to-csv` will return the empty string. \ No newline at end of file diff --git a/ucl/builtins/csv.go b/ucl/builtins/csv.go index c013549..93fc664 100644 --- a/ucl/builtins/csv.go +++ b/ucl/builtins/csv.go @@ -144,7 +144,15 @@ func (h csvHandlers) toCsv(ctx context.Context, args ucl.CallArgs) (any, error) } var sb strings.Builder - cw := csv.NewWriter(&sb) + + var w io.Writer + if args.HasSwitch("stdout") { + w = os.Stdout + } else { + w = &sb + } + + cw := csv.NewWriter(w) i := 0 for { diff --git a/ucl/builtins/csv_test.go b/ucl/builtins/csv_test.go index e8a436e..e8c3132 100644 --- a/ucl/builtins/csv_test.go +++ b/ucl/builtins/csv_test.go @@ -53,6 +53,11 @@ func TestCSV_ReadRecord(t *testing.T) { } func TestCSV_ToCSV(t *testing.T) { + type testStruct struct { + Alpha string + Bravo string + } + tests := []struct { descr string eval string @@ -78,6 +83,16 @@ func TestCSV_ToCSV(t *testing.T) { eval: `itrs:from [[hello:"one" world:"this"] [hello:"two" other:"the" world:"that"]] | csv:to-csv -header [world other]`, want: "world,other\nthis,\nthat,the\n", }, + { + descr: "to csv 5", + eval: `test-native | csv:to-csv`, + want: "Alpha,Bravo\nHello,World\nAnother,Test\n", + }, + { + descr: "to csv 6", + eval: `test-native | itrs:from | csv:to-csv`, + want: "Alpha,Bravo\nHello,World\nAnother,Test\n", + }, } for _, tt := range tests { @@ -89,6 +104,12 @@ func TestCSV_ToCSV(t *testing.T) { ucl.WithModule(builtins.Itrs()), ucl.WithOut(&bfr), ) + inst.SetBuiltin("test-native", func(ctx context.Context, args ucl.CallArgs) (any, error) { + return []testStruct{ + {Alpha: "Hello", Bravo: "World"}, + {Alpha: "Another", Bravo: "Test"}, + }, nil + }) res, err := inst.Eval(context.Background(), tt.eval) assert.NoError(t, err)