Skip to content

Commit db79e36

Browse files
authored
Adjust print formatting (deepnoodle-ai#250)
1 parent bcf5a8a commit db79e36

File tree

5 files changed

+116
-29
lines changed

5 files changed

+116
-29
lines changed

cmd/risor-modgen/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ func {{ .FuncGenName }}(ctx context.Context, args ...object.Object) object.Objec
283283
// Useful if you want to write your own "Module()" function.
284284
func addGeneratedBuiltins(builtins map[string]object.Object) map[string]object.Object {
285285
{{- range .ExportedFuncs }}
286-
builtins["{{ .ExportedName }}"] = object.NewBuiltin("{{ $.Package }}.{{ .ExportedName }}", {{ .FuncGenName }})
286+
builtins["{{ .ExportedName }}"] = object.NewBuiltin("{{ .ExportedName }}", {{ .FuncGenName }})
287287
{{- end }}
288288
return builtins
289289
}

modules/fmt/fmt.go

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,36 @@ import (
44
"context"
55
_ "embed"
66
"fmt"
7+
"time"
78

89
"github.com/risor-io/risor/object"
910
"github.com/risor-io/risor/os"
1011
)
1112

1213
func printableValue(obj object.Object) interface{} {
13-
iface := obj.Interface()
14-
if iface != nil {
15-
return iface
14+
switch obj := obj.(type) {
15+
// Primitive types have their underlying Go value passed to fmt.Printf
16+
// so that Go's Printf-style formatting directives work as expected. Also,
17+
// with these types there's no good reason for the print format to differ.
18+
case *object.String,
19+
*object.Int,
20+
*object.Float,
21+
*object.Byte,
22+
*object.Error,
23+
*object.Bool,
24+
*object.NilType:
25+
return obj.Interface()
26+
// For time objects, as a personal preference, I'm using RFC3339 format
27+
// rather than Go's default time print format, which I find less readable.
28+
case *object.Time:
29+
return obj.Value().Format(time.RFC3339)
1630
}
31+
// For everything else, convert the object to a string directly, relying
32+
// on the object type's String() or Inspect() methods. This gives the author
33+
// of new types the ability to customize the object print string. Note that
34+
// Risor map and list objects fall into this category on purpose and the
35+
// print format for these is intentionally a bit different than the print
36+
// format for the equivalent Go type (maps and slices).
1737
switch obj := obj.(type) {
1838
case fmt.Stringer:
1939
return obj.String()

modules/fmt/fmt_test.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package fmt
2+
3+
import (
4+
"context"
5+
"errors"
6+
"fmt"
7+
"testing"
8+
"time"
9+
10+
"github.com/risor-io/risor/object"
11+
"github.com/stretchr/testify/require"
12+
)
13+
14+
func TestPrintableValue(t *testing.T) {
15+
type testCase struct {
16+
obj object.Object
17+
expected any
18+
}
19+
20+
testTime, err := time.Parse("2006-01-02", "2021-01-01")
21+
require.NoError(t, err)
22+
23+
builtin := func(ctx context.Context, args ...object.Object) object.Object {
24+
return nil
25+
}
26+
27+
cases := []testCase{
28+
{object.NewString("hello"), "hello"},
29+
{object.NewByte(5), byte(5)},
30+
{object.NewInt(42), int64(42)},
31+
{object.NewFloat(42.42), 42.42},
32+
{object.NewBool(true), true},
33+
{object.NewBool(false), false},
34+
{object.Errorf("error"), errors.New("error")},
35+
{obj: object.Nil, expected: nil},
36+
{obj: object.NewTime(testTime), expected: "2021-01-01T00:00:00Z"},
37+
{obj: object.NewBuiltin("foo", builtin), expected: "builtin(foo)"},
38+
{ // strings printed inside lists are quoted in Risor
39+
obj: object.NewList([]object.Object{
40+
object.NewString("hello"),
41+
object.NewInt(42),
42+
}),
43+
expected: `["hello", 42]`,
44+
},
45+
{ // strings printed inside maps are quoted in Risor
46+
obj: object.NewMap(map[string]object.Object{
47+
"a": object.NewInt(42),
48+
"b": object.NewString("hello"),
49+
"c": object.Nil,
50+
}),
51+
expected: `{"a": 42, "b": "hello", "c": nil}`,
52+
},
53+
{
54+
obj: object.NewSet([]object.Object{
55+
object.NewInt(42),
56+
object.NewString("hi there"),
57+
}),
58+
expected: `{42, "hi there"}`,
59+
},
60+
}
61+
for _, tc := range cases {
62+
t.Run(fmt.Sprintf("%v", tc.expected), func(t *testing.T) {
63+
got := printableValue(tc.obj)
64+
require.Equal(t, tc.expected, got)
65+
})
66+
}
67+
}

modules/gha/gha_gen.go

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

modules/strings/strings_gen.go

Lines changed: 18 additions & 18 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)