Print Go values as Go source.

printsrc: Printing Go Values as Source

There are many packages that print Go values so people can read them. This package prints Go values so the Go compiler can read them. It is intended for use in code generators.

Background

I wanted to provide some data to my program at startup. I could have used go:embed to store the raw data with the program and process it at startup, but I wanted to pay the processing cost beforehand and generate Go data structures into a .go file that could be linked with the rest of my code.

So I need something that printed Go values as Go source. I looked around at the many pretty-printing packages out there:

  • github.com/davecgh/go-spew/spew
  • github.com/k0kubun/pp/v3
  • github.com/kr/pretty
  • github.com/kylelemons/godebug/pretty
  • github.com/sanity-io/litter

and more. They do a great job of formatting Go values for people to read. But I couldn't find one that correctly prints values as Go source. So I wrote this package.

Issues with Printing Source

Here are a few challenges that come up when trying to print Go values in a way that the compiler can understand.

Special floating-point values

Consider the floating-point value for positive infinity. There is no Go literal for this value, but it can be obtained with math.Inf(1). Calling fmt.Sprintf("%#v", math.Inf(1)) returns +Inf, which is not valid Go.

The printsrc package prints a float64 positive infinity as math.Inf(1) and a float32 positive infinity as float32(math.Inf(1)). It handles negative infinity and NaN similarly.

Values that cannot be represented

Function and channel values cannot be written as source using information available from the reflect package. Pretty-printers do their best to render these values, as they should, but printsrc fails on them so you can discover the problem quickly.

Pointers

When faced with a pointer, printers either print the address (like Go's fmt package) or follow the pointer and print the value. Neither of those, when fed back into Go, will produce the right value. Given

i := 5
s := []*int{&i, &i}

this package will print s as

[]*int{
    func() *int { var x int = 5; return &x }(),
    func() *int { var x int = 5; return &x }(),
}

That is a valid Go expression, although it doesn't preserve the sharing relationship of the original. For simplicity, printsrc doesn't detect sharing, and fails on cycles.

Types from other packages

Say your data structure contains a time.Duration. Depending on where it occurs, such values may have to be rendered with their type, like time.Duration(100). But that code won't compile unless the time package has been imported (and imported under the name "time"). Types in the package for where the generated code lives don't have that problem; they can be generated without a qualifying package identifier.

printsrc assumes that packages it encounters have been imported using the identifier that is the last component of their import path. Most of the time that is correct, but when it isn't you can register a different identifier with an import path.

Values that need constructors

The time.Time type has unexported fields, so it can't be usably printed as a Go struct literal (unless the code is being generated in the time package itself). There are many other types that need to be constructed with a function call or in some other way. Since printsrc can't discover the constructors for these types on its own, it lets you provide custom printing functions for any type. The one for time.Time is built in and prints a call to time.Date. (You can override it if you want.)

Owner
Jonathan Amsterdam
Jonathan Amsterdam
Similar Resources

Print random bytes from a secure source to stdout.

Print random bytes from a secure source to stdout.

Feb 11, 2022

Console Text Colors - The non-invasive cross-platform terminal color library does not need to modify the Print method

ctc - Console Text Colors The non-invasive cross-platform terminal color library does not need to modify the Print method Virtual unix-like environmen

Nov 9, 2022

Gotabulate - Easily pretty-print your tabular data with Go

Gotabulate - Easily pretty-print tabular data Summary Go-Tabulate - Generic Go Library for easy pretty-printing of tabular data. Installation go get g

Dec 27, 2022

💻 PTerm | Pretty Terminal Printer A golang module to print pretty text

💻 PTerm | Pretty Terminal Printer A golang module to print pretty text

✨ PTerm is a modern go module to beautify console output. Featuring charts, progressbars, tables, trees, and many more 🚀 It's completely configurable and 100% cross-platform compatible.

Jan 1, 2023

Slice graph uses graphviz in order to pretty print slices for you.

slicegraph Slice graph uses graphviz in order to make you understand what happens underneath your slices.

Sep 22, 2022

🎨 Terminal color rendering library, support 8/16 colors, 256 colors, RGB color rendering output, support Print/Sprintf methods, compatible with Windows.

🎨 Terminal color rendering library, support 8/16 colors, 256 colors, RGB color rendering output, support Print/Sprintf methods, compatible with Windows.

🎨 Terminal color rendering library, support 8/16 colors, 256 colors, RGB color rendering output, support Print/Sprintf methods, compatible with Windows. GO CLI 控制台颜色渲染工具库,支持16色,256色,RGB色彩渲染输出,使用类似于 Print/Sprintf,兼容并支持 Windows 环境的色彩渲染

Dec 30, 2022

A cross-platform tool to convert images into ascii art and print them on the console

A cross-platform tool to convert images into ascii art and print them on the console

A cross-platform tool to convert images into ascii art and print them on the console

Dec 30, 2022

Print debugging, but a little bit nicer

testlog Print debugging, but a little bit nicer. The use case this is primarily designed for is effectively debugging problematic, flaky tests.

Oct 11, 2021

An opinionated package that helps you print user-friendly output messages from your Go command line applications.

github.com/eth-p/clout (Command Line Output) clout is a package that helps you print user-friendly output messages from your Go command line applicati

Jan 15, 2022

timea.go (did you see what I did there?) is a simple library to print given times in

timea.go timea.go (did you see what I did there?) is a simple library to print given times in "time ago" manner. Usage Get it: go get github.com/caarl

Sep 29, 2022

mmdb-dump-networks - print every network in an MMDB to STDOUT

mmdb-dump-networks mmdb-dump-networks - print every network in an MMDB to STDOUT Project Description Usage Description Installation Reporting Bugs and

Oct 19, 2021

dshield-intelfeel-ips - print all IPs from the DShield API's Intelfeed to STDOUT

dshield-intelfeel-ips dshield-intelfeel-ips - print all IPs from the DShield API's Intelfeed to STDOUT Project Description Usage Description Installat

Oct 20, 2021

thermal print server for esc pos printers

thprint thprint is an extremely simple printing server for thermal printers connected to raspberry pis. This printing server exposes a print endpoint

Nov 4, 2021

Print lines matching a pattern in repositories using GitHub API

Print lines matching a pattern in repositories using GitHub API

gh-grep Print lines matching a pattern in repositories using GitHub API Usage $ gh grep func.*schema.Schema --include=**/*.go --owner k1LoW --repo tbl

Dec 1, 2022

A program to create assembly 8086 strings to print without using any printing/strings related function but only mov-xchg-int and loops

Assembly String builder tool A program to create assembly 8086 strings to print without using any printing/strings related function but only mov-xchg-

Feb 1, 2022

Watch and print changes in k8s

Watch kubernetes resources and print the delta in changes.

Jan 8, 2023

Print day progress in your terminal

Day progress Print day progress in your terminal Install go install github.com/tsivinsky/day-progress@latest Usage day-progress By default, day-progre

Jan 10, 2022

A command-line tool to pretty print your system's PATH environment variable.

A command-line tool to pretty print your system's PATH environment variable.

Description A command-line tool to pretty print your system's PATH environment variable. The output paths are colorized if they have special associati

Nov 9, 2022

Use go to count file's lines and print them.

用法 go run staticCodeLine.go -p [root path] -s [suffix name] -e [exclude dirs] 如果 -e 有多个参数,多次输入 -e [suffix name]。 ╰─± go run statisticCodeLine.go -p /U

Dec 12, 2022
Decode / encode XML to/from map[string]interface{} (or JSON); extract values with dot-notation paths and wildcards. Replaces x2j and j2x packages.

mxj - to/from maps, XML and JSON Decode/encode XML to/from map[string]interface{} (or JSON) values, and extract/modify values from maps by key or key-

Dec 22, 2022
Convert Go values to their AST

valast - convert Go values to their AST Valast converts Go values at runtime into their go/ast equivalent,

Dec 21, 2022
Enforce default values on structs in Go

Defaults Enforce default values on struct fields. type User struct { Name string `default:"Goku"` Power float64 `default:"9000.01"` } var u

Aug 23, 2022
Go library for encoding native Go structures into generic map values.

wstructs origin: github.com/things-go/structs Go library for encoding native Go structures into generic map values. Installation Use go get. go ge

Jan 10, 2022
Print specified values from desktop files to stdout.
Print specified values from desktop files to stdout.

dprint Print specified values from desktop files to stdout. Look, it’s hard to describe okay? Here’s a picture of me using it with dmenu. My launcher

Dec 22, 2021
Compute and print message digest hash values from stdin.

Compute and print message digest hash values from stdin.

Jan 31, 2022
This CLI tool sends HTTP GET requests and print MD5 hash values of the response's body

HTTP Body Hash Generator This CLI (Command Line Interface) tool sends HTTP GET requests and print MD5 hash values of the response's body. Usage You ne

Feb 10, 2022
:steam_locomotive: Decodes url.Values into Go value(s) and Encodes Go value(s) into url.Values. Dual Array and Full map support.

Package form Package form Decodes url.Values into Go value(s) and Encodes Go value(s) into url.Values. It has the following features: Supports map of

Dec 26, 2022
Print all source code for a given go package or module.

gosrcs gosrcs is a tool to print all the source code a given go package depends on. The original motivation of this tool is to integrate go builds int

Oct 25, 2021