Skip to content

Wrong TCL String representation for Go Built-ins #21

@gtarcea

Description

@gtarcea

Hi,

This is a really great project. I've run into an issue in version version v0.0.0-20260119183325-601d6c2067cd, that doesn't occur in version v0.0.0-20251227222940-8b153391b49e. Specifically the handling of go types when I do feather.OK() call.

In version v0.0.0-20251227222940-8b153391b49e if I have a list of strings they are properly represented as TCL strings. For example:

{name: "file1.txt" path: "/home/gtarcea/proj/Aging/cliuptest/file1.txt" type: "file" size: 37 mtime: 2026-02-02T15:36:37Z ctime: 2026-02-02T15:36:37Z} {name: "subdir" path: "/home/gtarcea/proj/Aging/cliuptest/subdir" type: "directory" size: 4096 mtime: 2026-02-02T15:36:49Z ctime: 2026-02-02T15:36:49Z}

In version v0.0.0-20260119183325-601d6c2067cd, they aren't converted, but instead are shown in the go "%v" format. For example:

[name: "file1.txt" path: "/home/gtarcea/proj/Aging/cliuptest/file1.txt" type: "file" size: 37 mtime: 2026-02-02T15:36:37Z ctime: 2026-02-02T15:36:37Z name: "subdir" path: "/home/gtarcea/proj/Aging/cliuptest/subdir" type: "directory" size: 4096 mtime: 2026-02-02T15:36:49Z ctime: 2026-02-02T15:36:49Z]

Specifically I'm creating a list of strings like:

       var items []string
	for _, item := range files {
		i := item.(map[string]any)
		lsItem, err := decoder.DecodeMapStrict[lsResponse](i)
		if err != nil {
			return feather.Error(fmt.Errorf("failed to decode lsResponse: %v", err))
		}
		items = append(items, fmt.Sprintf("name: %q path: %q type: %q size: %d mtime: %s ctime: %s",
			lsItem.Name, lsItem.Path, lsItem.Type, lsItem.Size,
			lsItem.Mtime.Format(time.RFC3339), lsItem.Ctime.Format(time.RFC3339)))
	}

It looks like feather.OK() has changed. In the v0.0.0-20260119183325-601d6c2067cd version its:

func OK(v any) Result {
	if o, ok := v.(*Obj); ok {
		return Result{code: ResultOK, obj: o, hasObj: true}
	}
	// For simple types, don't quote - just convert to string
	switch val := v.(type) {
	case string:
		return Result{code: ResultOK, val: val}
	case int:
		return Result{code: ResultOK, val: fmt.Sprintf("%d", val)}
	case int64:
		return Result{code: ResultOK, val: fmt.Sprintf("%d", val)}
	case float64:
		return Result{code: ResultOK, val: fmt.Sprintf("%g", val)}
	case bool:
		if val {
			return Result{code: ResultOK, val: "1"}
		}
		return Result{code: ResultOK, val: "0"}
	default:
		return Result{code: ResultOK, val: fmt.Sprintf("%v", v)}
	}
}

The default case is the reason for the go representation of []string.

In the v0.0.0-20251227222940-8b153391b49e version feather.OK() is implemented as:

func OK(v any) Result {
	if o, ok := v.(*Obj); ok {
		return Result{code: ResultOK, obj: o, hasObj: true}
	}
	return Result{code: ResultOK, val: toTclString(v)}
}

The toTclString() is handling the formatting. Is this an intentional change? If so what should I use to convert my types to a TCL String without writing my own version of toTclString?

For now I've copied your toTclString into my project and I'm making use of it. I had originally reverted to the 2025 version, but I noticed there are API changes and I want to use the latest version.

Let me know if you'd like a pull request.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions