fmtstruct

package module
v1.0.2 Latest Latest
Warning

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

Go to latest
Published: Apr 13, 2024 License: BSD-3-Clause Imports: 12 Imported by: 0

README

See the godoc for more information.

Documentation

Overview

Package fmtstruct writes slices of structs as formatted output in JSON, CSV, or tabular format.

Usage (library):

  • Set a Mode to CSV, JSON, JSON_PRETTY, or TABLE to determine the output format,
  • Use Print (mode, row...) to print to stdout using default configuration,
  • Use WriteTo(w, mode, opts, row...) to write to an io.Writer with custom options.

Usage (CLI):

  • Use RegisterCLI(flag.CommandLine, defaultMode) to register command-line flags for the output mode and options.

Everything else is just configuration, flag parsing, and convenience functions. # Anticipated questions:

  • Why only structs?

    A: that's what I needed.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func FormatOptFlag

func FormatOptFlag(fs *flag.FlagSet, prefix string, o *Opts)

FormatOptFlag creates flags for setting the options for formatting a struct. Usually, you just want to use RegisterCLI instead of this function. The prefix is used to create the flag names. For example, if prefix is "fmt", the flags will be "fmt-omitempty", "fmt-no-header", etc. Trailing '-' characters are removed from the prefix. The flags are:

  • prefix-omitempty: allow omitting empty fields with the 'omitempty' JSON tag
  • prefix-no-header: do not print the header row
  • prefix-separator: print a separator line '----' between the header and the row
  • prefix-verbs: map of field names to format verbs
  • prefix-fields: which fields to print: comma-separated list of field names

Usage:

fs := flag.NewFlagSet("example-flags", flag.PanicOnError)
opts := new(fmtstruct.Opts)
opts.AddFlagSet(fs, "fmt")

func Print

func Print[T any](mode Mode, row ...T) error

Print a slice of structs to stdout using the given Mode and it's Mode.DefaultOptions. This is a convenience wrapper around WriteTable(os.Stdout, nil, row...) T must be a struct type.

func PrintOutput

func PrintOutput[T any](mode Mode, row ...T) error

PrintOutput prints the row to stdout in the given mode, using the default options for that mode. This is syntactic sugar for WriteOutput(os.Stdout, mode, nil, row...)

func PrintTable

func PrintTable[T any](row ...T) error

Print a slice of structs to stdout using the JSON tags as the column headers. This is a convenience wrapper around WriteTable(os.Stdout, TABLE.DefaultOptions(), row...) The row slice must be a slice of structs.

Example
package main

import (
	"gitlab.com/efronlicht/fmtstruct"
)

func main() {
	type S struct {
		A int `json:"a"`
		B int `json:"b"`
	}
	if err := fmtstruct.PrintTable(S{1, 2}, S{3, 4}, S{5, 6}); err != nil {
		panic(err)
	}

}
Output:

a     b
----  ----
1     2
3     4
5     6

func RegisterCLI

func RegisterCLI(fs *flag.FlagSet, defaultMode Mode) (*Mode, *Opts)

RegisterCLI registers the flags on a flag.FlagSet for setting the output mode and options. You can just use this on flag.CommandLine if you don't have a custom flag set. See the example.

Example
package main

import (
	"flag"
	"fmt"

	"gitlab.com/efronlicht/fmtstruct"
)

func main() {
	fs := flag.NewFlagSet("example-flags", flag.PanicOnError)
	mode, opts := fmtstruct.RegisterCLI(fs, fmtstruct.TABLE)
	fs.Parse([]string{"-fmt-omitempty=false"})
	if *mode != fmtstruct.TABLE {
		panic("expected MODE_TABLE")
	}
	if opts == nil {
		panic("expected non-nil")
	}
	fmt.Printf(`mode=%s
opts.AllowOmitEmpty=%v
opts.NoHeader=%v
opts.PrintSeparator=%v
opts.Fields=%v
`, *mode, opts.AllowOmitEmpty, opts.NoHeader, opts.PrintSeparator, opts.Fields)
}
Output:

mode=table
opts.AllowOmitEmpty=false
opts.NoHeader=false
opts.PrintSeparator=true
opts.Fields=[]

func WriteCSV

func WriteCSV[T any](w io.Writer, opt *Opts, row ...T) error

WriteCSV writes a slice of structs to a CSV file, using the JSON tags as the column headers. See opts for more options.

func WriteTable

func WriteTable[T any](dst io.Writer, opts *Opts, row ...T) error

Write a table to the given io.Writer. The table is a slice of structs, where the JSON tags are used as the column headers (if they exist) and the struct names otherwise. Yes, this is overloading the meaning of the 'JSON' struct tags, but we just want consistency.

func WriteTo

func WriteTo[T any](w io.Writer, mode Mode, opts *Opts, row ...T) error

Write output in a format determined by the Mode and (optionally) Opts to the io.Writer `w`.

`T` must be a struct type. If opts are nil, the Mode.DefaultOptions() are used instead.

Example
package main

import (
	"os"

	"gitlab.com/efronlicht/fmtstruct"
)

func main() {
	type S struct {
		PrintMe int
		OmitMe  int
	}
	opts := &fmtstruct.Opts{
		NoHeader:       false,
		PrintSeparator: true,
		Fields:         []string{"PrintMe"},
	}
	if err := fmtstruct.WriteTo(os.Stdout, fmtstruct.TABLE, opts, S{1, 2}, S{3, 4}, S{5, 6}); err != nil {
		panic(err)
	}
}
Output:

PrintMe
----
1
3
5

Types

type Mode

type Mode byte

Mode specifies the output format for WriteOutput. Valid modes are:

  • JSON: compact JSON output with no indentation
  • JSON_PRETTY: JSON output with indentation
  • TABLE: tabular output via text/tabwriter
  • CSV: CSV output

It implements flag.Value and encoding.Marshaler/Unmarshaler, so it can be easily obtained via environment variables, flags, or configuration files. The integer values are subject to change, so don't rely on them.

const (
	MODE_UNSET    Mode = iota // not yet set. presence indicates programmer error
	JSON                      // JSON output with no indentation
	JSON_PRETTY               // JSON output with indentation
	TABLE                     // tabular output via text/tabwriter
	CSV                       // CSV output
	FORMAT_MODE_N             // number of modes: length placeholder
)

func FormatModeFlag

func FormatModeFlag(fs *flag.FlagSet, name string, usage string, defaultValue Mode) *Mode

FormatModeFlag creates a flag for setting the output mode. Usually you just want to use RegisterCLI instead of this function.

Example
package main

import (
	"flag"
	"os"

	"gitlab.com/efronlicht/fmtstruct"
)

func main() {
	fs := flag.NewFlagSet("example-flags", flag.PanicOnError)
	_ = fmtstruct.FormatModeFlag(fs, "format", "output mode", fmtstruct.TABLE)
	*os.Stderr = *os.Stdout
	fs.Usage()
}
Output:

Usage of example-flags:
  -format value
    	output mode: one of [json json-pretty table csv]

func ParseMode

func ParseMode(s string) (Mode, error)

ParseMode parses a string into a Mode. It returns an error if the string is not a valid mode.

func (Mode) DefaultOptions

func (fm Mode) DefaultOptions() *Opts

DefaultOptions returns the default options for the given mode. Don't modify the returned value; make a copy if you need to.

func (*Mode) MarshalText

func (fm *Mode) MarshalText() ([]byte, error)

func (Mode) String

func (fm Mode) String() string

String returns the name of the mode: "json", "json-pretty", "table", or "csv".

func (*Mode) UnmarshalText

func (fm *Mode) UnmarshalText(text []byte) error

type Opts

type Opts struct {
	AllowOmitEmpty bool                                      // allow omitting empty fields with the 'omitempty' tag
	FormatVerbs    map[string]string                         // map of field names to format verbs. If empty, fmt.Sprintf("%v") is used. Exactly one of Verb or CustomFormat should be set for a field.
	Fields         []string                                  // Which fields to print. If empty, all (exported) fields are printed.
	NoHeader       bool                                      // Do not print the header row.
	PrintSeparator bool                                      // Print a separator line between the header and the row. Default: ON for PrintTable, otherwise OFF.
	CustomFormat   map[string]func(w io.Writer, v any) error // Custom formatters for specific fields. Exactly one of Verb or CustomFormat should be set for a field.
}

Formatting options for WriteTable and WriteCSV. The nil value is OK to use and will be treated as DefaultCSVOptions, DefaultTableOptions, etc as appropriate. Use (*Opts).AddFlagSet register command-line flags for these options.

Jump to

Keyboard shortcuts

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