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 ¶
- Variables
- func Marshal(object interface{}, keys []interface{}, expandKeys bool, ...) ([]byte, error)
- func Read(input *ReadInput) (interface{}, error)
- func Unmarshal(b []byte, keyValueSeparator rune) (interface{}, error)
- func UnmarshalType(b []byte, keyValueSeparator rune, outputType reflect.Type) (interface{}, error)
- func Write(input *WriteInput) error
- type ErrInvalidKind
- type Flusher
- type Iterator
- type NewIteratorInput
- type ReadInput
- type WriteFlusher
- type WriteInput
- type Writer
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( ErrEmptyInput = errors.New("empty input") ErrInvalidRune = errors.New("invalid rune") ErrMissingKeyValueSeparator = errors.New("missing key-value separator") ErrMissingLineSeparator = errors.New("missing line separator") ErrMissingKeySerializer = errors.New("missing key serializer") ErrMissingValueSerializer = errors.New("missing value serializer") ErrMissingType = errors.New("missing type") ErrInvalidUTF8 = errors.New("invalid utf-8") )
var (
DefaultType = reflect.TypeOf(map[string]string{})
)
Functions ¶
func Marshal ¶
func Marshal(object interface{}, keys []interface{}, expandKeys bool, keyValueSeparator string, keySerializer stringify.Stringer, valueSerializer stringify.Stringer, sorted bool, reversed bool) ([]byte, error)
Marshal formats an object into a slice of bytes of tags (aka key=value pairs) The value serializer is used to render the key and value of each pair into strings. If keys is not empty, then prints the tags in the order specifed by keys. If expandKeys is true, then adds unknown keys to the end of the list of tags. 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, } keys := make([]interface{}, 0) b, err := Marshal(obj, keys, true, "=", 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"} keys := make([]interface{}, 0) keySerializer := stringify.NewStringer("", false, false, false) valueSerializer := stringify.NewStringer("", false, false, false) b, err := Marshal(in, keys, true, "=", keySerializer, valueSerializer, true, false) if err != nil { panic(err) } fmt.Println(string(b))
Output: A=1 B=2 C=3
func Read ¶
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, KeyValueSeparator: "=", 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 ¶
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 ¶
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"} keys := make([]interface{}, 0) keySerializer := stringify.NewStringer("", false, false, false) valueSerializer := stringify.NewStringer("", false, false, false) buf := new(bytes.Buffer) err := Write(&WriteInput{ Writer: buf, Keys: keys, KeyValueSeparator: "=", 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, }, } keys := make([]interface{}, 0) keySerializer := stringify.NewStringer("", false, false, false) valueSerializer := stringify.NewStringer("", false, false, false) buf := new(bytes.Buffer) err := Write(&WriteInput{ Writer: buf, Keys: keys, KeyValueSeparator: "=", 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 ¶
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 KeyValueSeparator rune // the key value separator 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, error)
NewIterator returns a new JSON Lines (aka jsonl) Iterator base on the given input.
func (*Iterator) Next ¶
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. KeyValueSeparator string // the key value separator 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 Keys []interface{} // the keys to read SkipLines int SkipBlanks bool SkipComments bool Comment string // the comment prefix KeyValueSeparator string // the key-value separator LineSeparator byte // the line separator DropCR bool // drop carriage return Limit int }
ReadInput provides the input for the Read function.
type WriteFlusher ¶
WriterFlusher is a simple interface that wraps io.Writer and Flusher.
type WriteInput ¶
type WriteInput struct { Writer io.Writer // the underlying writer Keys []interface{} // subset of keys to print ExpandKeys bool // dynamically expand keys KeyValueSeparator string // the key-value separator 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, keys []interface{}, expandKeys bool, keyValueSeparator string, lineSeparator 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) Close ¶ added in v0.0.9
Close closes the underlying writer, if it has a Close method.
func (*Writer) Flush ¶
Flush flushes the underlying writer, if it has a Flush method. This writer itself does no buffering.
func (*Writer) WriteObject ¶
WriteObject formats and writes a single object to the underlying writer as JSON and appends the writer's line separator.
func (*Writer) WriteObjects ¶
WriteObjects formats and writes the given objets to the underlying writer as JSON lines and separates the objects using the writer's line separator.