Help us shape the future of Go! Take the 2026 Go Developer Survey

tblfmt

package module
v0.21.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 31, 2026 License: MIT Imports: 23 Imported by: 16

README

About tblfmt

Package tblfmt writes result sets as text tables. A result set is the rows and columns that a database query returns. tblfmt reads a result set one row at a time, so it does not keep the whole result in memory. It writes tables like this one:

 author_id |            name            | z 
-----------+----------------------------+---
        14 | a       b       c       d  | 
        15 | aoeu                      +| 
           | test                      +| 
           |                            | 
        16 | foo\x08bar                 | 
        17 | a       b       \r        +| 
           |         a                  | 
        18 | 袈      袈              袈 | 
        19 | 袈      袈              袈+| a+
           |                            | 
(6 rows)

tblfmt writes each format that psql has: aligned, wrapped, unaligned, csv, html, asciidoc, latex, latex-longtable and troff-ms. It also writes JSON, the vertical format that the mysql client writes for \G, and a plain table with no lines. usql uses all of them.

Unit Tests Go Reference Discord Discussion

Installing

Install tblfmt with the Go tool:

$ go get -u github.com/xo/tblfmt

Using

tblfmt is for usql and for the database/sql types of Go. It accepts any type that has this interface:

// ResultSet is the shared interface for a result set.
type ResultSet interface {
	Next() bool
	Scan(...any) error
	Columns() ([]string, error)
	Close() error
	Err() error
	NextResultSet() bool
}

This program uses tblfmt:

// _example/example.go
package main

import (
	"log"
	"os"

	_ "github.com/lib/pq"
	"github.com/xo/dburl"

	"github.com/xo/tblfmt"
)

func main() {
	db, err := dburl.Open("postgres://booktest:booktest@localhost")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()
	res, err := db.Query("select * from authors")
	if err != nil {
		log.Fatal(err)
	}
	defer res.Close()
	enc, err := tblfmt.NewTableEncoder(
		res,
		// force minimum column widths
		tblfmt.WithWidths(20, 20),
	)
	if err = enc.EncodeAll(os.Stdout); err != nil {
		log.Fatal(err)
	}
}

The program writes output like this:

      author_id       |            name            | z 
----------------------+----------------------------+---
                   14 | a       b       c       d  | 
                   15 | aoeu                      +| 
                      | test                      +| 
                      |                            | 
                    2 | 袈      袈              袈 | 
(3 rows)

The Go Reference has the full API.

Differences from psql

tblfmt writes the same output as psql. The differences below are deliberate. If you find a different difference, report it as a bug. docs/BACKLOG.md lists the differences that are known faults.

Blank line after a table

psql writes one blank line after an aligned table. tblfmt does not. usql is the client that matches psql, so usql writes the line. If tblfmt wrote it too, usql would write two. See D48 in docs/PLAN.md.

Quotes in csv

tblfmt quotes a csv field that holds a space or a tab. psql quotes a field only when it holds the separator, a line break or a double quote. For a field that holds a, a tab and b, psql writes a<TAB>b, and tblfmt writes "a<TAB>b". See D52 in docs/PLAN.md.

Separator between unaligned result sets

psql writes nothing between two result sets in the unaligned and csv formats. tblfmt writes a newline by default. The caller chooses the separator with WithResultSetSeparator. See D53 in docs/PLAN.md.

Control characters in html and asciidoc

tblfmt escapes a control character in the html, asciidoc and vertical formats, as it does in a table. For example, it writes U+0008 as \x08. psql writes the character as it is in html and asciidoc. See D54 in docs/PLAN.md.

Wrapped columns that hold a wide character

In the wrapped format, psql can make a column 1 column wide when its values hold a character 2 columns wide, such as 日 or an emoji. The line with that character is then 1 column too wide. tblfmt keeps such a column at least 2 columns wide. See D56 in docs/PLAN.md.

Width of an emoji

tblfmt measures the width of text by grapheme cluster. A grapheme cluster is the group of code points that a terminal draws as one character. psql measures each code point. An emoji with a skin tone, such as 👍🏽, is two code points, and a current terminal draws it 2 columns wide. psql counts it 4 columns wide and pads the cell by 2 columns too few. tblfmt counts it 2 columns wide. A joined emoji, such as 👨‍👩‍👧, and a flag are one grapheme cluster each, and tblfmt counts each of them 2 columns wide. See D39 in docs/PLAN.md.

A terminal that draws each code point on its own, such as xterm, does not line up such a column.

Comparison with other packages

Other Go packages write text tables too. They take the rows as strings and draw the table in their own style. tblfmt reads a result set from a database, and writes it as psql does. The table below compares the versions that the benchmark uses. "Some" means that the package has the feature only in a mode or an option.

Feature tblfmt text/tabwriter tablewriter v1.1.5 go-pretty v6.8.3 lipgloss v1.1.0 simpletable v1.0.0 rodaine/table v1.4.1 aquasecurity/table v1.11.0
Reads a *sql.Rows yes no no no no no no no
Writes a row before it reads the next row some no some no no no no no
Writes a table as psql does yes no no no no no no no
Writes each row as a record (expanded) yes no no no no no no no
Wraps a table to a width yes no yes yes yes no no yes
Formats other than a text table csv, json, html, asciidoc, latex, troff no markdown, html, svg csv, tsv, html, markdown no no no no
Colors and text styles no no yes yes yes no yes yes

tblfmt writes each row of the unaligned, csv and json formats when it reads it. The table formats keep one batch of rows, and WithCount sets the size of the batch. tablewriter writes each row in its streaming mode.

The benchmark in test/ writes a table of 10,000 rows with each package. Each row holds an integer, 100 bytes of text and a float, as strings. Each package draws its default style. text/tabwriter and rodaine/table draw no lines, and tblfmt also escapes each value and measures it by grapheme cluster. The results on an AMD Ryzen 9 9950X with Go 1.27.1, on 2026-10-31:

Package Time Memory Allocations
text/tabwriter 2.8 ms 9.4 MiB 30,000
rodaine/table 6.3 ms 7.6 MiB 210,000
tblfmt 8.8 ms 9.2 MiB 213,000
go-pretty 11.1 ms 12.4 MiB 125,000
tablewriter 40.1 ms 49.0 MiB 1,086,000
simpletable 45.0 ms 25.4 MiB 545,000
lipgloss 82.0 ms 78.1 MiB 735,000
aquasecurity/table 215.5 ms 344.7 MiB 9,421,000

To run the benchmark, run this command in the test directory:

go test -run '^$' -bench BenchmarkWrite -benchmem

Documentation

Document What it holds
CONTRIBUTING.md What a change must do, and the commands to run before a pull request
docs/PLAN.md Each decision that shapes tblfmt, and the reason for it
docs/BACKLOG.md Known faults and work that is not done
AGENTS.md The rules for a coding agent. CLAUDE.md imports it

Testing

Run the tests with go test:

$ go test -v

To measure each format at 10,000 and 1,000,000 rows, run the benchmarks:

$ go test -run '^$' -bench BenchmarkEncode -benchmem

The benchmark against other packages is in the test module. See "Comparison with other packages".

TestPsql in the test module compares the output with psql 18, query by query. It needs a PostgreSQL server. "Tests" in AGENTS.md says how to start one with dbrun from dbmeta.

Documentation

Overview

Package tblfmt provides streaming table encoders for result sets (that is, result sets from a database).

Example
package main

import (
	"fmt"
	"log"
	"os"

	"github.com/xo/tblfmt"
)

func main() {
	res := getDatabaseResults()
	if err := tblfmt.EncodeAll(os.Stdout, res, map[string]string{
		"format": "aligned",
		"border": "2",
	}); err != nil {
		log.Fatal(err)
	}
}

// getDatabaseResults returns a tblfmt.ResultSet. A *sql.Rows from the
// database/sql package also implements that interface.
func getDatabaseResults() tblfmt.ResultSet {
	return &result{
		cols: []string{"author_id", "name", "z"},
		vals: [][]any{
			{14, "a\tb\tc\td", nil},
			{15, "aoeu\ntest\n", nil},
			{2, "袈\t袈\t\t袈", nil},
		},
	}
}

// result is a type that implements the tblfmt.ResultSet interface.
type result struct {
	pos  int
	cols []string
	vals [][]any
}

// Columns satisfies the tblfmt.ResultSet interface.
func (res *result) Columns() ([]string, error) {
	return res.cols, nil
}

// Next satisfies the tblfmt.ResultSet interface.
func (res *result) Next() bool {
	return res.pos < len(res.vals)
}

// Scan satisfies the tblfmt.ResultSet interface.
func (res *result) Scan(vals ...any) error {
	for i := range vals {
		x, ok := vals[i].(*any)
		if !ok {
			return fmt.Errorf("scan for col %d expected *interface{}, got: %T", i, vals[i])
		}
		*x = res.vals[res.pos][i]
	}
	res.pos++
	return nil
}

// Err satisfies the tblfmt.ResultSet interface.
func (res *result) Err() error {
	return nil
}

// Close satisfies the tblfmt.ResultSet interface.
func (res *result) Close() error {
	return nil
}

// NextResultSet satisfies the tblfmt.ResultSet interface.
func (res *result) NextResultSet() bool {
	return false
}
Output:
+-----------+----------------------------+---+
| author_id |            name            | z |
+-----------+----------------------------+---+
|        14 | a       b       c       d  |   |
|        15 | aoeu                      +|   |
|           | test                      +|   |
|           |                            |   |
|         2 | 袈      袈              袈 |   |
+-----------+----------------------------+---+
(3 rows)

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Encode

func Encode(w io.Writer, resultSet ResultSet, params map[string]string, options ...Option) error

Encode encodes the result set to the writer. It uses the parameters in the map and any other options that you supply.

func EncodeAll

func EncodeAll(w io.Writer, resultSet ResultSet, params map[string]string, options ...Option) error

EncodeAll encodes all result sets to the writer. It uses the parameters in the map and any other options that you supply.

Example
package main

import (
	"fmt"
	"log"
	"os"

	"github.com/xo/tblfmt"
)

func main() {
	res := getDatabaseResults()
	if err := tblfmt.EncodeAll(os.Stdout, res, map[string]string{
		"format":   "csv",
		"fieldsep": "|",
		"null":     "<nil>",
	}); err != nil {
		log.Fatal(err)
	}
}

// getDatabaseResults returns a tblfmt.ResultSet. A *sql.Rows from the
// database/sql package also implements that interface.
func getDatabaseResults() tblfmt.ResultSet {
	return &result{
		cols: []string{"author_id", "name", "z"},
		vals: [][]any{
			{14, "a\tb\tc\td", nil},
			{15, "aoeu\ntest\n", nil},
			{2, "袈\t袈\t\t袈", nil},
		},
	}
}

// result is a type that implements the tblfmt.ResultSet interface.
type result struct {
	pos  int
	cols []string
	vals [][]any
}

// Columns satisfies the tblfmt.ResultSet interface.
func (res *result) Columns() ([]string, error) {
	return res.cols, nil
}

// Next satisfies the tblfmt.ResultSet interface.
func (res *result) Next() bool {
	return res.pos < len(res.vals)
}

// Scan satisfies the tblfmt.ResultSet interface.
func (res *result) Scan(vals ...any) error {
	for i := range vals {
		x, ok := vals[i].(*any)
		if !ok {
			return fmt.Errorf("scan for col %d expected *interface{}, got: %T", i, vals[i])
		}
		*x = res.vals[res.pos][i]
	}
	res.pos++
	return nil
}

// Err satisfies the tblfmt.ResultSet interface.
func (res *result) Err() error {
	return nil
}

// Close satisfies the tblfmt.ResultSet interface.
func (res *result) Close() error {
	return nil
}

// NextResultSet satisfies the tblfmt.ResultSet interface.
func (res *result) NextResultSet() bool {
	return false
}
Output:
author_id,name,z
14,"a	b	c	d",<nil>
15,"aoeu
test
",<nil>
2,"袈	袈		袈",<nil>

func EncodeAsciiDoc added in v0.6.2

func EncodeAsciiDoc(w io.Writer, resultSet ResultSet, opts ...Option) error

EncodeAsciiDoc encodes the result set to the writer with the asciidoc template and the options that you supply.

func EncodeAsciiDocAll added in v0.6.2

func EncodeAsciiDocAll(w io.Writer, resultSet ResultSet, opts ...Option) error

EncodeAsciiDocAll encodes all result sets to the writer with the asciidoc template and the options that you supply.

func EncodeCSV

func EncodeCSV(w io.Writer, resultSet ResultSet, opts ...Option) error

EncodeCSV encodes the result set to the writer as unaligned CSV, with the options that you supply.

func EncodeCSVAll

func EncodeCSVAll(w io.Writer, resultSet ResultSet, opts ...Option) error

EncodeCSVAll encodes all result sets to the writer as unaligned CSV, with the options that you supply.

func EncodeExpanded

func EncodeExpanded(w io.Writer, resultSet ResultSet, opts ...Option) error

EncodeExpanded encodes the result set to the writer as an expanded table, with the options that you supply.

func EncodeExpandedAll

func EncodeExpandedAll(w io.Writer, resultSet ResultSet, opts ...Option) error

EncodeExpandedAll encodes all result sets to the writer as an expanded table, with the options that you supply.

func EncodeHTML added in v0.6.2

func EncodeHTML(w io.Writer, resultSet ResultSet, opts ...Option) error

EncodeHTML encodes the result set to the writer with the html template and the options that you supply.

func EncodeHTMLAll added in v0.6.2

func EncodeHTMLAll(w io.Writer, resultSet ResultSet, opts ...Option) error

EncodeHTMLAll encodes all result sets to the writer with the html template and the options that you supply.

func EncodeJSON

func EncodeJSON(w io.Writer, resultSet ResultSet, opts ...Option) error

EncodeJSON encodes the result set to the writer as JSON, with the options that you supply.

func EncodeJSONAll

func EncodeJSONAll(w io.Writer, resultSet ResultSet, opts ...Option) error

EncodeJSONAll encodes all result sets to the writer as JSON, with the options that you supply.

func EncodeTable

func EncodeTable(w io.Writer, resultSet ResultSet, opts ...Option) error

EncodeTable encodes the result set to the writer as a table, with the options that you supply.

func EncodeTableAll

func EncodeTableAll(w io.Writer, resultSet ResultSet, opts ...Option) error

EncodeTableAll encodes all result sets to the writer as a table, with the options that you supply.

func EncodeTemplate

func EncodeTemplate(w io.Writer, resultSet ResultSet, opts ...Option) error

EncodeTemplate encodes the result set to the writer with a template. The options that you supply set the template.

func EncodeTemplateAll

func EncodeTemplateAll(w io.Writer, resultSet ResultSet, opts ...Option) error

EncodeTemplateAll encodes all result sets to the writer with a template. The options that you supply set the template.

Example
package main

import (
	"fmt"
	"log"
	"os"

	"github.com/xo/tblfmt"
)

func main() {
	res := getDatabaseResults()
	if err := tblfmt.EncodeTemplateAll(os.Stdout, res, tblfmt.WithTemplate("html")); err != nil {
		log.Fatal(err)
	}
}

// getDatabaseResults returns a tblfmt.ResultSet. A *sql.Rows from the
// database/sql package also implements that interface.
func getDatabaseResults() tblfmt.ResultSet {
	return &result{
		cols: []string{"author_id", "name", "z"},
		vals: [][]any{
			{14, "a\tb\tc\td", nil},
			{15, "aoeu\ntest\n", nil},
			{2, "袈\t袈\t\t袈", nil},
		},
	}
}

// result is a type that implements the tblfmt.ResultSet interface.
type result struct {
	pos  int
	cols []string
	vals [][]any
}

// Columns satisfies the tblfmt.ResultSet interface.
func (res *result) Columns() ([]string, error) {
	return res.cols, nil
}

// Next satisfies the tblfmt.ResultSet interface.
func (res *result) Next() bool {
	return res.pos < len(res.vals)
}

// Scan satisfies the tblfmt.ResultSet interface.
func (res *result) Scan(vals ...any) error {
	for i := range vals {
		x, ok := vals[i].(*any)
		if !ok {
			return fmt.Errorf("scan for col %d expected *interface{}, got: %T", i, vals[i])
		}
		*x = res.vals[res.pos][i]
	}
	res.pos++
	return nil
}

// Err satisfies the tblfmt.ResultSet interface.
func (res *result) Err() error {
	return nil
}

// Close satisfies the tblfmt.ResultSet interface.
func (res *result) Close() error {
	return nil
}

// NextResultSet satisfies the tblfmt.ResultSet interface.
func (res *result) NextResultSet() bool {
	return false
}
Output:
<table border="1">
  <tr>
    <th align="center">author_id</th>
    <th align="center">name</th>
    <th align="center">z</th>
  </tr>
  <tr valign="top">
    <td align="right">14</td>
    <td align="left">a	b	c	d</td>
    <td align="left">&nbsp; </td>
  </tr>
  <tr valign="top">
    <td align="right">15</td>
    <td align="left">aoeu<br />
test<br />
</td>
    <td align="left">&nbsp; </td>
  </tr>
  <tr valign="top">
    <td align="right">2</td>
    <td align="left">袈	袈		袈</td>
    <td align="left">&nbsp; </td>
  </tr>
</table>
<p>(3 rows)<br />
</p>

func EncodeUnaligned added in v0.5.0

func EncodeUnaligned(w io.Writer, resultSet ResultSet, opts ...Option) error

EncodeUnaligned encodes the result set to the writer as unaligned text, with the options that you supply.

func EncodeUnalignedAll added in v0.5.0

func EncodeUnalignedAll(w io.Writer, resultSet ResultSet, opts ...Option) error

EncodeUnalignedAll encodes all result sets to the writer as unaligned text, with the options that you supply.

func EncodeVertical added in v0.6.2

func EncodeVertical(w io.Writer, resultSet ResultSet, opts ...Option) error

EncodeVertical encodes the result set to the writer with the vertical template and the options that you supply.

func EncodeVerticalAll added in v0.6.2

func EncodeVerticalAll(w io.Writer, resultSet ResultSet, opts ...Option) error

EncodeVerticalAll encodes all result sets to the writer with the vertical template and the options that you supply.

func FromMap

func FromMap(opts map[string]string) (Builder, []Option)

FromMap returns the Builder and the options for the format and the other parameters in the map.

Note: this func is mainly a helper for parameter names that are like the format option names of psql.

func WriteAsciidocTo added in v0.17.0

func WriteAsciidocTo(w io.Writer, tpl *Template) error

WriteAsciidocTo writes AsciiDoc output to the writer, as psql print_asciidoc_text and print_asciidoc_vertical do.

func WriteHTMLTo added in v0.17.0

func WriteHTMLTo(w io.Writer, tpl *Template) error

WriteHTMLTo writes HTML output to the writer, as psql print_html_text and print_html_vertical do.

func WriteLaTeXLongtableTo added in v0.21.0

func WriteLaTeXLongtableTo(w io.Writer, tpl *Template) error

WriteLaTeXLongtableTo writes LaTeX longtable output to the writer, as psql print_latex_longtable_text does. The attributes hold the widths of the left aligned columns, as fractions of the text width. Expanded output is the same as for WriteLaTeXTo.

func WriteLaTeXTo added in v0.21.0

func WriteLaTeXTo(w io.Writer, tpl *Template) error

WriteLaTeXTo writes LaTeX output to the writer, as psql print_latex_text and print_latex_vertical do.

func WriteTroffMSTo added in v0.21.0

func WriteTroffMSTo(w io.Writer, tpl *Template) error

WriteTroffMSTo writes troff output with the ms macros to the writer, as psql print_troff_ms_text and print_troff_ms_vertical do.

func WriteVerticalTo added in v0.17.0

func WriteVerticalTo(w io.Writer, tpl *Template) error

WriteVerticalTo writes vertical output to the writer, as the mysql client writes a result for \G. It right aligns each column name to the widest name, by display width. With SkipHeader, it writes no names, as mysql does with --skip-column-names. See D60 in docs/PLAN.md.

Types

type Align

type Align int

Align is the alignment direction of a value.

const (
	AlignLeft Align = iota
	AlignRight
	AlignCenter
)

The Align directions.

func (Align) String

func (a Align) String() string

String satisfies the fmt.Stringer interface.

type Builder

type Builder = func(ResultSet, ...Option) (Encoder, error)

Builder is a func that creates an encoder for a result set.

type CrosstabView added in v0.5.0

type CrosstabView struct {
	// contains filtered or unexported fields
}

CrosstabView is a crosstab view for result sets.

CAUTION:

By design, a crosstab view does not support multiple result sets. You must create a new crosstab view for each result set. Thus, NextResultSet always returns false. If you use this view inside a loop, or give it to other code that calls NextResultSet, be careful.

func (*CrosstabView) Close added in v0.5.0

func (view *CrosstabView) Close() error

Close satisfies the ResultSet interface.

func (*CrosstabView) Columns added in v0.5.0

func (view *CrosstabView) Columns() ([]string, error)

Columns satisfies the ResultSet interface.

func (*CrosstabView) Err added in v0.5.0

func (view *CrosstabView) Err() error

Err satisfies the ResultSet interface.

func (*CrosstabView) Next added in v0.5.0

func (view *CrosstabView) Next() bool

Next satisfies the ResultSet interface.

func (*CrosstabView) NextResultSet added in v0.5.0

func (view *CrosstabView) NextResultSet() bool

NextResultSet satisfies the ResultSet interface.

func (*CrosstabView) Scan added in v0.5.0

func (view *CrosstabView) Scan(v ...any) error

Scan satisfies the ResultSet interface.

type Encoder

type Encoder interface {
	Encode(io.Writer) error
	EncodeAll(io.Writer) error
}

Encoder is the shared interface for encoders.

func NewAsciiDocEncoder added in v0.5.0

func NewAsciiDocEncoder(resultSet ResultSet, opts ...Option) (Encoder, error)

NewAsciiDocEncoder creates a template encoder for AsciiDoc with the options.

func NewCSVEncoder

func NewCSVEncoder(resultSet ResultSet, opts ...Option) (Encoder, error)

NewCSVEncoder creates a CSV encoder with the options.

It creates an unaligned encoder. By default, the field separator is ',' and the field quote is '"'.

func NewExpandedEncoder

func NewExpandedEncoder(resultSet ResultSet, opts ...Option) (Encoder, error)

NewExpandedEncoder creates an expanded table encoder with the options.

func NewHTMLEncoder added in v0.5.0

func NewHTMLEncoder(resultSet ResultSet, opts ...Option) (Encoder, error)

NewHTMLEncoder creates a template encoder for HTML with the options.

func NewJSONEncoder

func NewJSONEncoder(resultSet ResultSet, opts ...Option) (Encoder, error)

NewJSONEncoder creates a JSON encoder with the options.

func NewLaTeXEncoder added in v0.21.0

func NewLaTeXEncoder(resultSet ResultSet, opts ...Option) (Encoder, error)

NewLaTeXEncoder creates a template encoder for LaTeX with the options.

func NewLaTeXLongtableEncoder added in v0.21.0

func NewLaTeXLongtableEncoder(resultSet ResultSet, opts ...Option) (Encoder, error)

NewLaTeXLongtableEncoder creates a template encoder for the LaTeX longtable package with the options.

func NewTableEncoder

func NewTableEncoder(resultSet ResultSet, opts ...Option) (Encoder, error)

NewTableEncoder creates a table encoder with the options.

By default, the table encoder has a border of 1.

Example
package main

import (
	"fmt"
	"log"
	"os"

	"github.com/xo/tblfmt"
)

func main() {
	res := getDatabaseResults()
	enc, err := tblfmt.NewTableEncoder(
		res,
		tblfmt.WithBorder(2),
		tblfmt.WithLineStyle(tblfmt.UnicodeLineStyle(true, false, false)),
		tblfmt.WithWidths(20, 20),
		tblfmt.WithSummary(tblfmt.DefaultTableSummary()),
	)
	if err != nil {
		log.Fatal(err)
	}
	if err := enc.EncodeAll(os.Stdout); err != nil {
		log.Fatal(err)
	}
}

// getDatabaseResults returns a tblfmt.ResultSet. A *sql.Rows from the
// database/sql package also implements that interface.
func getDatabaseResults() tblfmt.ResultSet {
	return &result{
		cols: []string{"author_id", "name", "z"},
		vals: [][]any{
			{14, "a\tb\tc\td", nil},
			{15, "aoeu\ntest\n", nil},
			{2, "袈\t袈\t\t袈", nil},
		},
	}
}

// result is a type that implements the tblfmt.ResultSet interface.
type result struct {
	pos  int
	cols []string
	vals [][]any
}

// Columns satisfies the tblfmt.ResultSet interface.
func (res *result) Columns() ([]string, error) {
	return res.cols, nil
}

// Next satisfies the tblfmt.ResultSet interface.
func (res *result) Next() bool {
	return res.pos < len(res.vals)
}

// Scan satisfies the tblfmt.ResultSet interface.
func (res *result) Scan(vals ...any) error {
	for i := range vals {
		x, ok := vals[i].(*any)
		if !ok {
			return fmt.Errorf("scan for col %d expected *interface{}, got: %T", i, vals[i])
		}
		*x = res.vals[res.pos][i]
	}
	res.pos++
	return nil
}

// Err satisfies the tblfmt.ResultSet interface.
func (res *result) Err() error {
	return nil
}

// Close satisfies the tblfmt.ResultSet interface.
func (res *result) Close() error {
	return nil
}

// NextResultSet satisfies the tblfmt.ResultSet interface.
func (res *result) NextResultSet() bool {
	return false
}
Output:
╔══════════════════════╤════════════════════════════╤═══╗
║      author_id       │            name            │ z ║
╟──────────────────────┼────────────────────────────┼───╢
║                   14 │ a       b       c       d  │   ║
║                   15 │ aoeu                      ↵│   ║
║                      │ test                      ↵│   ║
║                      │                            │   ║
║                    2 │ 袈      袈              袈 │   ║
╚══════════════════════╧════════════════════════════╧═══╝
(3 rows)

func NewTemplateEncoder

func NewTemplateEncoder(resultSet ResultSet, opts ...Option) (Encoder, error)

NewTemplateEncoder creates a template encoder with the options.

func NewTroffMSEncoder added in v0.21.0

func NewTroffMSEncoder(resultSet ResultSet, opts ...Option) (Encoder, error)

NewTroffMSEncoder creates a template encoder for troff with the ms macros, with the options.

func NewUnalignedEncoder added in v0.5.0

func NewUnalignedEncoder(resultSet ResultSet, opts ...Option) (Encoder, error)

NewUnalignedEncoder creates an unaligned encoder with the options.

func NewVerticalEncoder added in v0.6.2

func NewVerticalEncoder(resultSet ResultSet, opts ...Option) (Encoder, error)

NewVerticalEncoder creates a vertical template encoder with the options.

type Error

type Error string

Error is an error.

const (
	// ErrResultSetIsNil is the result set is nil error.
	ErrResultSetIsNil Error = "result set is nil"
	// ErrResultSetHasNoColumnTypes is the result set has no column types error.
	ErrResultSetHasNoColumnTypes Error = "result set has no column types"
	// ErrResultSetReturnedInvalidColumnTypes is the result set returned invalid column types error.
	ErrResultSetReturnedInvalidColumnTypes Error = "result set returned invalid column types"
	// ErrInvalidFormat is the invalid format error.
	ErrInvalidFormat Error = "invalid format"
	// ErrInvalidLineStyle is the invalid line style error.
	ErrInvalidLineStyle Error = "invalid line style"
	// ErrFormatterIsNotEscapeFormatter is the formatter is not an escape
	// formatter error.
	ErrFormatterIsNotEscapeFormatter Error = "formatter options need an escape formatter"
	// ErrInvalidIndent is the invalid indent error.
	ErrInvalidIndent Error = "invalid indent"
	// ErrInvalidTemplate is the invalid template error.
	ErrInvalidTemplate Error = "invalid template"
	// ErrInvalidFieldSeparator is the invalid field separator error.
	ErrInvalidFieldSeparator Error = "invalid field separator"
	// ErrInvalidCSVFieldSeparator is the invalid csv field separator error.
	ErrInvalidCSVFieldSeparator Error = "invalid csv field separator"
	// ErrInvalidColumnParams is the invalid column params error.
	ErrInvalidColumnParams Error = "invalid column params"
	// ErrCrosstabResultMustHaveAtLeast3Columns is the crosstab result must
	// have at least 3 columns error.
	ErrCrosstabResultMustHaveAtLeast3Columns Error = "crosstab result must have at least 3 columns"
	// ErrCrosstabDataColumnMustBeSpecifiedWhenQueryReturnsMoreThanThreeColumns
	// is the data column must be specified when query returns more than three
	// columns error.
	ErrCrosstabDataColumnMustBeSpecifiedWhenQueryReturnsMoreThanThreeColumns Error = "data column must be specified when query returns more than three columns"
	// ErrCrosstabVerticalAndHorizontalColumnsMustNotBeSame is the crosstab
	// vertical and horizontal columns must not be same error.
	ErrCrosstabVerticalAndHorizontalColumnsMustNotBeSame Error = "crosstab vertical and horizontal columns must not be same"
	// ErrCrosstabVerticalColumnNotInResult is the crosstab vertical column not
	// in result error.
	ErrCrosstabVerticalColumnNotInResult Error = "crosstab vertical column not in result"
	// ErrCrosstabHorizontalColumnNotInResult is the crosstab horizontal column
	// not in result error.
	ErrCrosstabHorizontalColumnNotInResult Error = "crosstab horizontal column not in result"
	// ErrCrosstabDataColumnNotInResult is the crosstab data column not in
	// result error.
	ErrCrosstabDataColumnNotInResult Error = "crosstab data column not in result"
	// ErrCrosstabHorizontalSortColumnNotInResult is the crosstab horizontal
	// sort column not in result error.
	ErrCrosstabHorizontalSortColumnNotInResult Error = "crosstab horizontal sort column not in result"
	// ErrCrosstabDuplicateVerticalAndHorizontalValue is the crosstab duplicate
	// vertical and horizontal value error.
	ErrCrosstabDuplicateVerticalAndHorizontalValue Error = "crosstab duplicate vertical and horizontal value"
	// ErrCrosstabHorizontalSortColumnIsNotANumber is the crosstab horizontal
	// sort column is not a number error.
	ErrCrosstabHorizontalSortColumnIsNotANumber Error = "crosstab horizontal sort column is not a number"
)

Error values.

func (Error) Error

func (err Error) Error() string

Error satisfies the error interface.

type EscapeFormatter

type EscapeFormatter struct {
	// contains filtered or unexported fields
}

EscapeFormatter is a formatter that escapes values. It formats the standard Go types.

If a marshal func is set with WithEncoder, the formatter passes it each map[string]interface{} and []interface{} value. Otherwise, the formatter uses encoding/json/v2 from the standard library.

func NewEscapeFormatter

func NewEscapeFormatter(opts ...EscapeFormatterOption) *EscapeFormatter

NewEscapeFormatter creates an escape formatter for basic Go values, such as []byte, string, time.Time, sql.Null*, and any database/sql/driver.Valuer. The formatter passes map[string]interface{} and []interface{} values to the marshal func set with WithEncoder. Otherwise, it uses the standard encoding/json/v2 to marshal those values.

func (*EscapeFormatter) Format

func (f *EscapeFormatter) Format(vals []any) ([]*Value, error)

Format satisfies the Formatter interface.

func (*EscapeFormatter) Header

func (f *EscapeFormatter) Header(headers []string) ([]*Value, error)

Header satisfies the Formatter interface.

type EscapeFormatterOption

type EscapeFormatterOption func(*EscapeFormatter)

EscapeFormatterOption is an escape formatter option.

func WithAlign added in v0.18.0

func WithAlign(a Align) EscapeFormatterOption

WithAlign sets the forced alignment for values.

func WithEncoder added in v0.10.0

func WithEncoder(encoder func(any) ([]byte, error)) EscapeFormatterOption

WithEncoder is an escape formatter option that sets a standard Go marshal func to encode the value.

func WithHeaderAlign added in v0.2.0

func WithHeaderAlign(a Align) EscapeFormatterOption

WithHeaderAlign sets the alignment of the column names in the header.

func WithInvalid

func WithInvalid(invalid string) EscapeFormatterOption

WithInvalid is an escape formatter option that sets the text that replaces an invalid rune in the escape.

func WithIsJSON added in v0.5.0

func WithIsJSON(isJSON bool) EscapeFormatterOption

WithIsJSON is an escape formatter option that turns on a special escape for JSON characters in values that are not complex.

func WithIsRaw added in v0.5.0

func WithIsRaw(isRaw bool, sep, quote rune) EscapeFormatterOption

WithIsRaw is an escape formatter option that turns on a special escape for raw characters in values.

func WithJSONConfig

func WithJSONConfig(prefix, indent string, escapeHTML bool) EscapeFormatterOption

WithJSONConfig is an escape formatter option that sets the JSON prefix, the JSON indent, and whether to escape HTML. The formatter passes them to encoding/json/v2 if no marshal func is set on the escape formatter.

The prefix and indent must contain only spaces and tabs, and are ignored otherwise. Output is compact when both are empty.

func WithMask

func WithMask(mask string) EscapeFormatterOption

WithMask is an escape formatter option that sets the mask for an empty column name in the header.

func WithNumericLocale added in v0.10.0

func WithNumericLocale(enable bool, locale string) EscapeFormatterOption

WithNumericLocale sets the numeric locale printer. The printer groups the digits of a number as the locale does, the same as \pset numericlocale in psql.

It has no effect on JSON output. A grouped number is not a JSON number. A JSON string for it makes the JSON type of a column depend on a display option. Every other format applies it. The csv output quotes each field that needs it, exactly as psql does.

func WithTimeFormat

func WithTimeFormat(timeFormat string) EscapeFormatterOption

WithTimeFormat is an escape formatter option that sets the time format for time values.

func WithTimeLocation added in v0.13.1

func WithTimeLocation(timeLocation *time.Location) EscapeFormatterOption

WithTimeLocation is an escape formatter option that sets the time location for time values.

type ExpandedEncoder

type ExpandedEncoder struct {
	TableEncoder
	// contains filtered or unexported fields
}

ExpandedEncoder is an encoder that writes a result set as an expanded table. It writes each row as a record, with one line for each column. It buffers a batch of rows ahead, as TableEncoder does.

func (*ExpandedEncoder) Encode

func (enc *ExpandedEncoder) Encode(w io.Writer) error

Encode encodes one result set to the writer with the options of the encoder.

The encoder draws the records as psql does in print_aligned_vertical, in src/fe_utils/print.c.

func (*ExpandedEncoder) EncodeAll

func (enc *ExpandedEncoder) EncodeAll(w io.Writer) error

EncodeAll encodes each result set to the writer with the options of the encoder.

type Formatter

type Formatter interface {
	// Header returns a slice of formatted values for the column names of a
	// header.
	Header([]string) ([]*Value, error)
	// Format returns a slice of formatted values for the values of a row.
	Format([]any) ([]*Value, error)
}

Formatter is the common interface that formats values.

type JSONEncoder

type JSONEncoder struct {
	// contains filtered or unexported fields
}

JSONEncoder is an encoder that writes a result set as JSON. It does not buffer rows.

func (*JSONEncoder) Encode

func (enc *JSONEncoder) Encode(w io.Writer) error

Encode encodes one result set to the writer with the options of the encoder.

func (*JSONEncoder) EncodeAll

func (enc *JSONEncoder) EncodeAll(w io.Writer) error

EncodeAll encodes each result set to the writer with the options of the encoder.

type LineStyle

type LineStyle struct {
	// Top is the line above the header. Mid is the line under the header,
	// and End is the line under the last row. A rule with an empty Line
	// writes no line.
	Top Rule
	Mid Rule
	End Rule
	// Row holds the vertical lines of a row. Its Line is not used.
	Row Rule
	// MidNewline is the vertical line before a value that continues after a
	// newline. MidBlank is the vertical line before a value that has no more
	// lines. psql draws MidWrap before a wrapped value. In expanded output, it
	// also draws MidWrap beside each further line of a column name after a
	// value that is not empty ends.
	MidNewline string
	MidBlank   string
	MidWrap    string
	// HeaderNewlineLeft and HeaderNewlineRight mark a line of a column name
	// that continues after a newline.
	HeaderNewlineLeft  string
	HeaderNewlineRight string
	// NewlineLeft and NewlineRight mark a line of a value that continues
	// after a newline. WrapLeft and WrapRight mark a line of a value that
	// continues after a wrap.
	NewlineLeft  string
	NewlineRight string
	WrapLeft     string
	WrapRight    string
	// LeftMarks is true when the style marks a continued line on the left of
	// a value, as the psql old-ascii style does. With a border of 0, such a
	// style writes no mark at the right of a column name.
	LeftMarks bool
}

LineStyle is a line style for tables. It holds the parts of a psql line style.

The TableLineStyle, ASCIILineStyle, OldASCIILineStyle and UnicodeLineStyle funcs below return the predefined line styles.

A table with a border of 2 looks like this:

+-----------+---------------------------+---+
| author_id |           name            | z |
+-----------+---------------------------+---+
|        14 | a       b       c       d |   |
|        15 | aoeu                     +|   |
|           | test                     +|   |
|           |                           |   |
+-----------+---------------------------+---+

If the border is 1, the encoder writes the vertical lines between the columns:

 author_id |           name            | z
-----------+---------------------------+---
        14 | a       b       c       d | x
        15 | aoeu                     +|
           | test                     +|
           |                           |

If the border is 0, the encoder writes no vertical line:

author_id           name            z
--------- ------------------------- -
       14 a       b       c       d x
       15 aoeu                     +
          test                     +

func ASCIILineStyle

func ASCIILineStyle() LineStyle

ASCIILineStyle is the ASCII line style for tables, as psql draws it.

A table with this line style looks like this:

+-----------+---------------------------+---+
| author_id |           name            | z |
+-----------+---------------------------+---+
|        14 | a       b       c       d | x |
|        15 | aoeu                     +|   |
|           | test                     +|   |
|           |                           |   |
+-----------+---------------------------+---+

func OldASCIILineStyle

func OldASCIILineStyle() LineStyle

OldASCIILineStyle is the old ASCII line style for tables, as psql draws it. It marks a value that continues after a newline with a colon on its left.

A table with this line style looks like this:

+-----------+---------------------------+---+
| author_id |           name            | z |
+-----------+---------------------------+---+
|        14 | a       b       c       d | x |
|        15 | aoeu                      |   |
|           : test                          |
|           :                               |
+-----------+---------------------------+---+

func TableLineStyle added in v0.18.0

func TableLineStyle() LineStyle

TableLineStyle is the table line style. It draws no line.

A table with this line style looks like this:

AUTHOR_ID NAME                      Z
14        a       b       c       d x
15        aoeu
          test

func UnicodeLineStyle

func UnicodeLineStyle(doubleBorder, doubleHeader, doubleColumn bool) LineStyle

UnicodeLineStyle is the Unicode line style for tables, as psql draws it. Each argument draws one part of the table with double lines, as the psql variables unicode_border_linestyle, unicode_header_linestyle and unicode_column_linestyle do.

A table with single lines looks like this:

┌───────────┬───────────────────────────┬───┐
│ author_id │           name            │ z │
├───────────┼───────────────────────────┼───┤
│        14 │ a       b       c       d │ x │
│        15 │ aoeu                     ↵│   │
│           │ test                     ↵│   │
│           │                           │   │
└───────────┴───────────────────────────┴───┘

type Option

type Option interface {
	// contains filtered or unexported methods
}

Option is an encoder option.

func FormatterOptionFromMap added in v0.11.1

func FormatterOptionFromMap(opts map[string]string) Option

FormatterOptionFromMap builds an option that sets the formatter options from the parameters in the map.

func WithBorder

func WithBorder(border int) Option

WithBorder is an encoder option that sets the border size.

func WithColumnAlign added in v0.21.0

func WithColumnAlign(f func(*sql.ColumnType) (Align, bool)) Option

WithColumnAlign is an encoder option that sets the alignment of each column from its database type, before the encoder reads a row. For each column, f gets the *sql.ColumnType, and returns the alignment and true, or false to align the column by its values. The alignment holds for each value of the column, a null value too, and for a result set that has no rows.

The result set must have a ColumnTypes method, as *sql.Rows has. The table and template encoders read it.

For example, psql right aligns the numbers, and the money type:

tblfmt.WithColumnAlign(func(col *sql.ColumnType) (tblfmt.Align, bool) {
	switch col.DatabaseTypeName() {
	case "INT2", "INT4", "INT8", "FLOAT4", "FLOAT8", "NUMERIC", "OID", "MONEY":
		return tblfmt.AlignRight, true
	}
	return tblfmt.AlignLeft, true
})

func WithColumnTypes added in v0.12.0

func WithColumnTypes(columnTypes func(ResultSet, []any, int) error) Option

WithColumnTypes is an encoder option that sets the func that builds the column types.

func WithColumnTypesFunc added in v0.12.0

func WithColumnTypesFunc(f func(*sql.ColumnType) (any, error)) Option

WithColumnTypesFunc is an encoder option that sets a func that builds the type of each column.

func WithCount

func WithCount(count int) Option

WithCount is an encoder option that sets the number of rows to buffer.

func WithEmpty

func WithEmpty(empty string) Option

WithEmpty is an encoder option that sets the value for empty (nil) cells.

func WithExecutor added in v0.5.0

func WithExecutor(executor func(io.Writer, *Template) error) Option

WithExecutor is an encoder option that sets the executor.

func WithExpanded added in v0.21.0

func WithExpanded(expanded bool) Option

WithExpanded is an encoder option that writes each row as a record, as psql does with the variable expanded on. The unaligned and csv encoders and the html, asciidoc, latex, latex-longtable and troff-ms templates read it. The table encoder has NewExpandedEncoder instead.

func WithForceUpperColumnNames added in v0.18.0

func WithForceUpperColumnNames(forceUpper bool) Option

WithForceUpperColumnNames is an encoder option that changes all column names to upper case. See TransformForceUpper.

func WithFormatter

func WithFormatter(formatter Formatter) Option

WithFormatter is an encoder option that sets the formatter for values.

func WithFormatterOptions added in v0.7.1

func WithFormatterOptions(opts ...EscapeFormatterOption) Option

WithFormatterOptions is an encoder option that adds more formatter options. The formatter of the encoder must be an EscapeFormatter. For any other formatter, the encoder returns ErrFormatterIsNotEscapeFormatter.

func WithHeaderTransformer added in v0.18.0

func WithHeaderTransformer(headerTransformer Transformer) Option

WithHeaderTransformer is an encoder option that sets the transform style for the header.

func WithIndent added in v0.21.0

func WithIndent(indent string) Option

WithIndent is an encoder option that sets the indent of the JSON encoder. By default, the indent is empty, and the encoder writes each result set as compact JSON on one line.

The indent must contain only spaces and tabs.

func WithLineStyle

func WithLineStyle(lineStyle LineStyle) Option

WithLineStyle is an encoder option that sets the line style of the table.

func WithLowerColumnNames added in v0.7.5

func WithLowerColumnNames(lowerColumnNames bool) Option

WithLowerColumnNames is an encoder option that changes the column names to lower case when they are all upper case. See TransformUpperToLower.

func WithMinExpandWidth added in v0.3.0

func WithMinExpandWidth(w int) Option

WithMinExpandWidth is an encoder option that sets the maximum width before the encoder switches to the expanded format.

func WithNewline

func WithNewline(newline string) Option

WithNewline is an encoder option that sets the newline.

func WithParams added in v0.5.0

func WithParams(params ...string) Option

WithParams is a view option that sets the column parameters.

func WithQuote added in v0.5.0

func WithQuote(quote rune) Option

WithQuote is an encoder option that sets the quote character for fields.

func WithResultSetSeparator added in v0.21.0

func WithResultSetSeparator(sep string) Option

WithResultSetSeparator is an encoder option that sets the text that EncodeAll writes between two result sets. By default, EncodeAll writes the newline.

func WithSeparator added in v0.5.0

func WithSeparator(sep rune) Option

WithSeparator is an encoder option that sets the field separator.

func WithSkipHeader added in v0.4.0

func WithSkipHeader(s bool) Option

WithSkipHeader is an encoder option that stops the encoder from writing the header.

func WithSummary

func WithSummary(summary Summary) Option

WithSummary is an encoder option that sets the summary of the table. The JSON encoder writes no summary.

func WithTableAttributes added in v0.2.0

func WithTableAttributes(a string) Option

WithTableAttributes is an encoder option that sets the table attributes.

func WithTemplate

func WithTemplate(name string) Option

WithTemplate is an encoder option that sets the template by its name.

func WithTitle

func WithTitle(title string) Option

WithTitle is an encoder option that sets the title of the table.

func WithUseColumnTypes added in v0.7.0

func WithUseColumnTypes(useColumnTypes bool) Option

WithUseColumnTypes is an encoder option that makes the encoder use the column types of the result set.

func WithWidths

func WithWidths(widths ...int) Option

WithWidths is an encoder option that sets the minimum width of each column. Only the table encoders read it, because only they pad a column (D61).

func WithWrapWidth added in v0.21.0

func WithWrapWidth(width int) Option

WithWrapWidth is an encoder option that wraps the values of a table, so that the table fits in the width, as the psql format wrapped does. The encoder does not make a column narrower than its name. Zero turns off wrapping.

type ResultSet

type ResultSet interface {
	Next() bool
	Scan(...any) error
	Columns() ([]string, error)
	Close() error
	Err() error
	NextResultSet() bool
}

ResultSet is the shared interface for a result set.

func NewCrosstabView added in v0.5.0

func NewCrosstabView(resultSet ResultSet, opts ...Option) (ResultSet, error)

NewCrosstabView creates a new crosstab view.

type Rule added in v0.21.0

type Rule struct {
	Line   string
	Left   string
	Middle string
	Right  string
}

Rule holds the strings of one kind of line in a table: the horizontal line, and the vertical lines at the left, between two columns, and at the right.

type Summary added in v0.13.0

type Summary = map[int]func(io.Writer, int) (int, error)

Summary maps a row count to the func that writes the summary for that count. The key -1 holds the func for any other count.

func DefaultTableSummary

func DefaultTableSummary() Summary

DefaultTableSummary is the default summary for tables.

The default summary looks like this:

(3 rows)

type TableEncoder

type TableEncoder struct {
	// contains filtered or unexported fields
}

TableEncoder is an encoder that writes a result set as a table. It buffers a batch of rows ahead to find the widths of the columns.

func (*TableEncoder) Encode

func (enc *TableEncoder) Encode(w io.Writer) error

Encode encodes one result set to the writer with the options of the encoder.

The encoder draws the table as psql does in print_aligned_text, in src/fe_utils/print.c.

func (*TableEncoder) EncodeAll

func (enc *TableEncoder) EncodeAll(w io.Writer) error

EncodeAll encodes each result set to the writer with the options of the encoder.

type Template added in v0.17.0

type Template struct {
	Attributes string
	Headers    []*Value
	Rows       [][]*Value
	SkipHeader bool
	Title      *Value
	// Aligns are the alignments of the columns.
	Aligns []Align
	// Border is the border, as the psql variable border sets it.
	Border int
	// Expanded is true when the template writes each row as a record.
	Expanded bool
	// Footer is the summary line, or empty for none. The encoder follows the
	// rule of psql: a table gets the row count or the custom summary, and
	// expanded records get only a custom summary.
	Footer string
}

Template holds the data for a template.

type TemplateEncoder

type TemplateEncoder struct {
	// contains filtered or unexported fields
}

TemplateEncoder is a template encoder for result sets.

Note: the encoder reads every row of a result set into memory before it runs the template, because the template receives all the rows at once.

func (*TemplateEncoder) Encode

func (enc *TemplateEncoder) Encode(w io.Writer) error

Encode encodes one result set to the writer with the options of the encoder.

func (*TemplateEncoder) EncodeAll

func (enc *TemplateEncoder) EncodeAll(w io.Writer) error

EncodeAll encodes each result set to the writer with the options of the encoder.

type TransformStyle added in v0.18.0

type TransformStyle int

TransformStyle is a transform style for column names in the header.

const (
	TransformNone TransformStyle = iota
	TransformForceLower
	TransformForceUpper
	TransformUpperToLower
	TransformLowerToUpper
)

Transform styles.

func (TransformStyle) Transform added in v0.18.0

func (style TransformStyle) Transform(s string) string

Transform transforms s with the style. It satisfies the Transformer interface.

type Transformer added in v0.18.0

type Transformer interface {
	Transform(string) string
}

Transformer is the interface for column transformers.

type UnalignedEncoder added in v0.5.0

type UnalignedEncoder struct {
	// contains filtered or unexported fields
}

UnalignedEncoder is an encoder that writes a result set with no alignment. It does not buffer rows.

You can use it to encode a result set in formats such as comma-separated values (CSV) or tab-separated values (TSV).

By default, the field separator is '|', there is no quote character, and the record separator is the default newline for the platform ("\r\n" on Windows, "\n" otherwise).

func (*UnalignedEncoder) Encode added in v0.5.0

func (enc *UnalignedEncoder) Encode(w io.Writer) error

Encode encodes one result set to the writer with the options of the encoder.

The encoder writes the result set as psql does in print_unaligned_text, print_unaligned_vertical, print_csv_text and print_csv_vertical, in src/fe_utils/print.c.

func (*UnalignedEncoder) EncodeAll added in v0.5.0

func (enc *UnalignedEncoder) EncodeAll(w io.Writer) error

EncodeAll encodes each result set to the writer with the options of the encoder.

type Value

type Value struct {
	// Buf is the formatted value.
	Buf []byte
	// Newlines are the positions of newline characters in Buf.
	Newlines [][2]int
	// Tabs are the positions of tab characters in Buf, split per line.
	Tabs [][][2]int
	// Width is the remaining width.
	Width int
	// Align is the alignment of the value.
	Align Align
	// Raw is true when the JSON encoder writes Buf exactly, with no quotes.
	Raw bool
	// Quoted tracks whether a raw value must be quoted, that is, whether it
	// contains a space or a non printable character.
	Quoted bool
}

Value holds a formatted value and data about it.

func FormatBytes

func FormatBytes(src []byte, invalid []byte, invalidWidth int, isJSON, isRaw bool, sep, quote rune) *Value

FormatBytes escapes src to a Value. The Value holds the escaped (encoded) and unescaped runes, and the positions of the tabs and newlines in its Buf.

func (*Value) LineWidth

func (v *Value) LineWidth(l int) int

LineWidth returns the display width of line l. A tab moves to the next multiple of 8 columns from the start of the line, as psql writes it.

func (*Value) MaxWidth

func (v *Value) MaxWidth() int

MaxWidth returns the display width of the longest line in Buf.

func (*Value) String added in v0.2.0

func (v *Value) String() string

Directories

Path Synopsis
_example/example.go
_example/example.go
Package internal contains tblfmt internals.
Package internal contains tblfmt internals.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL