tags

package
v0.0.8 Latest Latest
Warning

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

Go to latest
Published: Jul 6, 2019 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package tags provides a simple API for reading and writing to lines of tags. tags also supports iterators for efficiently reading through a stream. See the examples below for usage.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ErrEmptyInput             = errors.New("empty input")
	ErrInvalidRune            = errors.New("invalid rune")
	ErrMissingLineSeparator   = errors.New("missing line separator")
	ErrMissingKeySerializer   = errors.New("missing key serializer")
	ErrMissingValueSerializer = errors.New("missing value serializer")
	ErrMissingType            = errors.New("missing type")
)

Functions

func Marshal

func Marshal(object interface{}, keySerializer stringify.Stringer, valueSerializer stringify.Stringer, sorted bool, reversed bool) ([]byte, error)

Marshal formats an object into a slice of bytes of tags. The value serializer is used to render the key and value of each pair into strings. If sorted and not reversed, then the keys are sorted in alphabetical order. If sorted and reversed, then the keys are sorted in reverse alphabetical order.

Example (Map)

This example shows how to marshal a map into a line of tags.

obj := map[string]interface{}{
	"a": 1,
	"b": 2,
	"c": 3,
}
b, err := Marshal(obj, stringify.NewStringer("", false, false, false), stringify.NewStringer("", false, false, false), true, false)
if err != nil {
	panic(err)
}
fmt.Println(string(b))
Output:

a=1 b=2 c=3
Example (Stuct)

This example shows how to marshal a struct into a line of tags.

in := struct {
	A string
	B string
	C string
}{A: "1", B: "2", C: "3"}
keySerializer := stringify.NewStringer("", false, false, false)
valueSerializer := stringify.NewStringer("", false, false, false)
b, err := Marshal(in, keySerializer, valueSerializer, true, false)
if err != nil {
	panic(err)
}
fmt.Println(string(b))
Output:

A=1 B=2 C=3

func Read

func Read(input *ReadInput) (interface{}, error)

Read reads the lines of tags from the input Reader into the given type. If no type is given, returns a slice of type []map[string]string.

Example
in := `
	a=b
	hello="beautiful world"
	hello="beautiful \"wide\" world"
  `
out, err := Read(&ReadInput{
	Type:          reflect.TypeOf([]interface{}{}),
	Reader:        strings.NewReader(in),
	SkipLines:     0,
	SkipBlanks:    true,
	SkipComments:  false,
	LineSeparator: []byte("\n")[0],
	DropCR:        true,
	Comment:       "",
})
if err != nil {
	panic(err)
}
fmt.Println(out)
Output:

[map[a:b] map[hello:beautiful world] map[hello:beautiful "wide" world]]

func Unmarshal

func Unmarshal(b []byte) (interface{}, error)

Unmarshal parses a slice of bytes into an object using a few simple type inference rules. This package is useful when your program needs to parse data, that you have no a priori awareness of its structure or type. If no input is given, then returns ErrEmptyInput. If the first rune is invalid, then returns ErrInvalidRune.

Example (Map)

This example shows you can unmarshal a line of tags into a map.

str := "a=1 b=2 c=3"
obj, err := Unmarshal([]byte(str))
if err != nil {
	panic(err)
}
fmt.Println(obj)
Output:

map[a:1 b:2 c:3]

func UnmarshalType

func UnmarshalType(b []byte, outputType reflect.Type) (interface{}, error)

UnmarshalType parses a slice of bytes into an object of a given type. If no input is given, then returns ErrEmptyInput. If the first rune in the slice of bytes is invalid, then returns ErrInvalidRune.

Example (Map)

This example shows you can unmarshal a line of tags into a map.

str := "a=1 b=2 c=3"
obj, err := UnmarshalType([]byte(str), reflect.TypeOf(map[string]string{}))
if err != nil {
	panic(err)
}
fmt.Println(obj)
Output:

map[a:1 b:2 c:3]

func Write

func Write(input *WriteInput) error

Write writes the given object(s) as lines of tags. If the type of the input object is of kind Array or Slice, then writes each object on its own line. If the type of the input object is of kind Map or Struct, then writes a single line of tags.

Example (Map)

This example shows you can marshal a single map into a JSON object

obj := map[string]string{"a": "b", "c": "beautiful world", "d": "beautiful \"wide\" world"}
buf := new(bytes.Buffer)
keySerializer := stringify.NewStringer("", false, false, false)
valueSerializer := stringify.NewStringer("", false, false, false)
err := Write(&WriteInput{
	Writer:          buf,
	LineSeparator:   "\n",
	Object:          obj,
	KeySerializer:   keySerializer,
	ValueSerializer: valueSerializer,
	Sorted:          true,
	Limit:           -1,
})
if err != nil {
	panic(err)
}
fmt.Println(buf.String())
Output:

a=b c="beautiful world" d="beautiful \"wide\" world"
Example (Slice)

This examples shows that you can marshal a slice of maps into lines of tags.

obj := []interface{}{
	map[string]interface{}{
		"a": 1,
		"b": 2,
		"c": 3,
	},
	map[string]interface{}{
		"a": 4,
		"b": 5,
		"c": 6,
	},
}
buf := new(bytes.Buffer)
keySerializer := stringify.NewStringer("", false, false, false)
valueSerializer := stringify.NewStringer("", false, false, false)
err := Write(&WriteInput{
	Writer:          buf,
	LineSeparator:   "\n",
	Object:          obj,
	KeySerializer:   keySerializer,
	ValueSerializer: valueSerializer,
	Sorted:          true,
	Limit:           -1,
})
if err != nil {
	panic(err)
}
fmt.Println(buf.String())
Output:

a=1 b=2 c=3
a=4 b=5 c=6

Types

type ErrInvalidKind

type ErrInvalidKind struct {
	Value    reflect.Type
	Expected []reflect.Kind
}

func (ErrInvalidKind) Error

func (e ErrInvalidKind) Error() string

Error returns the error formatted as a string.

type Flusher

type Flusher interface {
	Flush() error
}

Flusher interfaces is a simple interface that wraps the Flush() function.

type Iterator

type Iterator struct {
	Scanner      scanner.Scanner // the scanner that splits the underlying stream of bytes
	Type         reflect.Type
	Comment      string // The comment line prefix.  Can be any string.
	SkipBlanks   bool   // Skip blank lines.  If false, Next() returns a blank line as (nil, nil).  If true, Next() simply skips forward until it finds a non-blank line.
	SkipComments bool   // Skip commented lines.  If false, Next() returns a commented line as (nil, nil).  If true, Next() simply skips forward until it finds a non-commented line.
	Limit        int    // Limit the number of objects to read and return from the underlying stream.
	Count        int    // The current count of the number of objects read.
}

Iterator iterates trough a stream of bytes returning a new object on each call of Next() until it reaches the end and returns io.EOF.

func NewIterator

func NewIterator(input *NewIteratorInput) *Iterator

NewIterator returns a new JSON Lines (aka jsonl) Iterator base on the given input.

func (*Iterator) Next

func (it *Iterator) Next() (interface{}, error)

Next reads from the underlying reader and returns the next object and error, if any. If a blank line is found and SkipBlanks is false, then returns (nil, nil). If a commented line is found and SkipComments is false, then returns (nil, nil). When the input stream is exhausted, returns (nil, io.EOF).

type NewIteratorInput

type NewIteratorInput struct {
	Reader        io.Reader
	Type          reflect.Type
	SkipLines     int    // Skip a given number of lines at the beginning of the stream.
	SkipBlanks    bool   // Skip blank lines.  If false, Next() returns a blank line as (nil, nil).  If true, Next() simply skips forward until it finds a non-blank line.
	SkipComments  bool   // Skip commented lines.  If false, Next() returns a commented line as (nil, nil).  If true, Next() simply skips forward until it finds a non-commented line.
	Comment       string // The comment line prefix. Can be any string.
	Limit         int    // Limit the number of objects to read and return from the underlying stream.
	LineSeparator byte   // The new line byte.
	DropCR        bool   // Drop carriage returns at the end of lines.
}

Input for NewIterator function.

type ReadInput

type ReadInput struct {
	Type          reflect.Type // the output type
	Reader        io.Reader    // the underlying reader
	SkipLines     int
	SkipBlanks    bool
	SkipComments  bool
	Comment       string // the comment prefix
	LineSeparator byte   // the newline byte
	DropCR        bool   // drop carriage return
	Limit         int
}

ReadInput provides the input for the Read function.

type WriteFlusher

type WriteFlusher interface {
	io.Writer
	Flusher
}

WriterFlusher is a simple interface that wraps io.Writer and Flusher.

type WriteInput

type WriteInput struct {
	Writer          io.Writer   // the underlying writer
	LineSeparator   string      // the line separator
	Object          interface{} // the object to write
	KeySerializer   stringify.Stringer
	ValueSerializer stringify.Stringer
	Sorted          bool // sort keys
	Reversed        bool
	Limit           int
}

WriteInput provides the input for the Write function.

type Writer

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

Writer formats and writes objects to the underlying writer as JSON Lines (aka jsonl).

func NewWriter

func NewWriter(w io.Writer, separator string, keySerializer stringify.Stringer, valueSerializer stringify.Stringer, sorted bool, reversed bool) *Writer

NewWriter returns a writer for formating and writing objets to the underlying writer as JSON Lines (aka jsonl).

func (*Writer) Flush

func (w *Writer) Flush() error

Flush flushes the underlying writer, if it has a Flush method. This writer itself does no buffering.

func (*Writer) WriteObject

func (w *Writer) WriteObject(obj interface{}) error

WriteObject formats and writes a single object to the underlying writer as JSON and appends the writer's line separator.

func (*Writer) WriteObjects

func (w *Writer) WriteObjects(objects interface{}) error

WriteObjects formats and writes the given objets to the underlying writer as JSON lines and separates the objects using the writer's line separator.

Jump to

Keyboard shortcuts

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