sen

package
v0.0.0-...-af45976 Latest Latest
Warning

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

Go to latest
Published: Jan 25, 2023 License: MIT Imports: 20 Imported by: 0

Documentation

Overview

Package sen contains the SEN parsers and writers.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// DefaultOptions are the default options for the this package.
	DefaultOptions = ojg.DefaultOptions
	// BrightOptions are the bright color options.
	BrightOptions = ojg.BrightOptions
	// HTMLOptions are the options that can be used to encode as HTML JSON.
	HTMLOptions = ojg.HTMLOptions
)

Functions

func Bytes

func Bytes(data any, args ...any) []byte

Bytes returns a SEN []byte for the data provided. The data can be a simple type of nil, bool, int, floats, time.Time, []any, or map[string]any or a Node type, The args, if supplied can be an int as an indent, *ojg.Options, or a *Writer. The returned buffer is the Writer buffer and is reused on the next call to write. If returned value is to be preserved past a second invocation then the buffer should be copied.

Example
package main

import (
	"fmt"

	"github.com/khaf/ojg/sen"
)

func main() {
	type Sample struct {
		X int
		Y string
	}
	b := sen.Bytes(&Sample{X: 3, Y: "why"})
	fmt.Println(string(b))

}
Output:

{x:3 y:why}

func MustParse

func MustParse(buf []byte, args ...any) any

MustParse SEN into a simple type. Arguments are optional and can be a func(any) bool for callbacks or a chan any for chan based result delivery. The SEN parser will also Parse JSON. Panics on error.

A func argument is the callback for the parser if processing multiple SENs. If no callback function is provided the processing is limited to only one SEN.

A chan argument will be used to deliver parse results.

Example
package main

import (
	"fmt"

	"github.com/khaf/ojg/pretty"
	"github.com/khaf/ojg/sen"
)

func main() {
	val := sen.MustParse([]byte("[true false [3 2 1] {a:1 b:2 c:3 d:[x y z []]}]"))
	fmt.Println(pretty.SEN(val, 80.3))

}
Output:

[
  true
  false
  [3 2 1]
  {a: 1 b: 2 c: 3 d: [x y z []]}
]

func MustParseReader

func MustParseReader(r io.Reader, args ...any) (data any)

MustParseReader reads and parses SEN into a simple type. Arguments are optional and can be a func(any) bool for callbacks or a chan any for chan based result delivery. The SEN parser will also Parse JSON. Panics on error.

A func argument is the callback for the parser if processing multiple SENs. If no callback function is provided the processing is limited to only one SEN.

A chan argument will be used to deliver parse results.

Example
package main

import (
	"fmt"
	"strings"

	"github.com/khaf/ojg/pretty"
	"github.com/khaf/ojg/sen"
)

func main() {
	r := strings.NewReader("[true false [3 2 1] {a:1 b:2 c:3 d:[x y z []]}]")
	val := sen.MustParseReader(r)
	fmt.Println(pretty.SEN(val, 80.3))

}
Output:

[
  true
  false
  [3 2 1]
  {a: 1 b: 2 c: 3 d: [x y z []]}
]

func MustWrite

func MustWrite(w io.Writer, data any, args ...any)

MustWrite SEN for the data provided. The data can be a simple type of nil, bool, int, floats, time.Time, []any, or map[string]any or a Node type, The args, if supplied can be an int as an indent, *ojg.Options, or a *Writer. Panics on error.

Example
package main

import (
	"fmt"
	"strings"

	"github.com/khaf/ojg/sen"
)

func main() {
	type Sample struct {
		X int
		Y string
	}
	var buf strings.Builder
	sen.MustWrite(&buf, &Sample{X: 3, Y: "why"})
	fmt.Println(buf.String())

}
Output:

{x:3 y:why}

func Parse

func Parse(buf []byte, args ...any) (any, error)

Parse SEN into a simple type. Arguments are optional and can be a func(any) bool for callbacks or a chan any for chan based result delivery. The SEN parser will also Parse JSON.

A func argument is the callback for the parser if processing multiple SENs. If no callback function is provided the processing is limited to only one SEN.

A chan argument will be used to deliver parse results.

Example
package main

import (
	"fmt"

	"github.com/khaf/ojg/pretty"
	"github.com/khaf/ojg/sen"
)

func main() {
	val, err := sen.Parse([]byte("[true false [3 2 1] {a:1 b:2 c:3 d:[x y z []]}]"))
	if err != nil {
		panic(err)
	}
	fmt.Println(pretty.SEN(val, 80.3))

}
Output:

[
  true
  false
  [3 2 1]
  {a: 1 b: 2 c: 3 d: [x y z []]}
]

func ParseReader

func ParseReader(r io.Reader, args ...any) (data any, err error)

ParseReader reads and parses SEN into a simple type. Arguments are optional and can be a func(any) bool for callbacks or a chan any for chan based result delivery. The SEN parser will also Parse JSON.

A func argument is the callback for the parser if processing multiple SENs. If no callback function is provided the processing is limited to only one SEN.

A chan argument will be used to deliver parse results.

Example
package main

import (
	"fmt"
	"strings"

	"github.com/khaf/ojg/pretty"
	"github.com/khaf/ojg/sen"
)

func main() {
	r := strings.NewReader("[true false [3 2 1] {a:1 b:2 c:3 d:[x y z []]}]")
	val, err := sen.ParseReader(r)
	if err != nil {
		panic(err)
	}
	fmt.Println(pretty.SEN(val, 80.3))

}
Output:

[
  true
  false
  [3 2 1]
  {a: 1 b: 2 c: 3 d: [x y z []]}
]

func String

func String(data any, args ...any) string

String returns a SEN string for the data provided. The data can be a simple type of nil, bool, int, floats, time.Time, []any, or map[string]any or a Node type, The args, if supplied can be an int as an indent, *ojg.Options, or a *Writer.

Example
package main

import (
	"fmt"

	"github.com/khaf/ojg/sen"
)

func main() {
	type Sample struct {
		X int
		Y string
	}
	s := sen.String(&Sample{X: 3, Y: "why"})
	fmt.Println(s)

}
Output:

{x:3 y:why}

func Tokenize

func Tokenize(data []byte, handler oj.TokenHandler) error

Tokenize a JSON string in to simple types. An error is returned if not valid JSON.

func TokenizeLoad

func TokenizeLoad(r io.Reader, handler oj.TokenHandler) error

TokenizeLoad a JSON io.Reader. An error is returned if not valid JSON.

func TokenizeString

func TokenizeString(data string, handler oj.TokenHandler) error

TokenizeString the provided JSON and call the handler functions for each token in the JSON.

func Unmarshal

func Unmarshal(data []byte, vp any, recomposer ...*alt.Recomposer) (err error)

Unmarshal parses the provided JSON and stores the result in the value pointed to by vp.

Example
package main

import (
	"fmt"

	"github.com/khaf/ojg/sen"
)

func main() {
	type Sample struct {
		X int
		Y string
	}
	var sample Sample
	if err := sen.Unmarshal([]byte("{x: 3 y: why}"), &sample); err != nil {
		panic(err)
	}
	fmt.Printf("sample.X: %d  sample.Y: %s\n", sample.X, sample.Y)

}
Output:

sample.X: 3  sample.Y: why
Example (Interface)
package main

import (
	"fmt"

	"github.com/khaf/ojg"
	"github.com/khaf/ojg/alt"
	"github.com/khaf/ojg/sen"
)

// Encode and decode slice of interfaces.

type Animal interface {
	Kind() string
}

type Dog struct {
	Size string
}

func (d *Dog) Kind() string {
	return fmt.Sprintf("%s dog", d.Size)
}

type Cat struct {
	Color string
}

func (c *Cat) Kind() string {
	return fmt.Sprintf("%s cat", c.Color)
}

func main() {
	pets := []Animal{&Dog{Size: "big"}, &Cat{Color: "black"}}

	// Encode and use a create key to identify the encoded type.
	b := sen.Bytes(pets, &ojg.Options{CreateKey: "^", Sort: true})
	// Sort the object members in the output for repeatability.
	fmt.Printf("as JSON: %s\n", b)

	// Create a new Recomposer. This can be use over and over again. Register
	// the types with a nil creation function to let reflection do the work
	// since the types are exported.
	r, err := alt.NewRecomposer("^", map[any]alt.RecomposeFunc{&Dog{}: nil, &Cat{}: nil})
	if err != nil {
		panic(err)
	}
	var result any
	if err = sen.Unmarshal(b, &result, r); err != nil {
		panic(err)
	}
	list, _ := result.([]any)
	for _, item := range list {
		animal, _ := item.(Animal)
		fmt.Printf("  %s\n", animal.Kind())
	}
	// Unmarshal with a typed target.
	var animals []Animal
	if err = sen.Unmarshal(b, &animals, r); err != nil {
		panic(err)
	}
	fmt.Println("Unmarshal into a target struct")
	for _, animal := range animals {
		fmt.Printf("  %T - %s\n", animal, animal.Kind())
	}

}
Output:

as JSON: [{^:Dog size:big} {^:Cat color:black}]
  big dog
  black cat
Unmarshal into a target struct
  *sen_test.Dog - big dog
  *sen_test.Cat - black cat

func Write

func Write(w io.Writer, data any, args ...any) (err error)

Write SEN for the data provided. The data can be a simple type of nil, bool, int, floats, time.Time, []any, or map[string]any or a Node type, The args, if supplied can be an int as an indent, *ojg.Options, or a *Writer.

Example
package main

import (
	"fmt"
	"strings"

	"github.com/khaf/ojg/sen"
)

func main() {
	type Sample struct {
		X int
		Y string
	}
	var buf strings.Builder
	if err := sen.Write(&buf, &Sample{X: 3, Y: "why"}); err != nil {
		panic(err)
	}
	fmt.Println(buf.String())

}
Output:

{x:3 y:why}

Types

type Options

type Options = ojg.Options

Options is an alias for ojg.Options

type Parser

type Parser struct {

	// Reuse maps. Previously returned maps will no longer be valid or rather
	// could be modified during parsing.
	Reuse bool

	// OnlyOne returns an error if more than one JSON is in the string or stream.
	OnlyOne bool
	// contains filtered or unexported fields
}

Parser is a reusable JSON parser. It can be reused for multiple parsings which allows buffer reuse for a performance advantage.

func (*Parser) AddMongoFuncs

func (p *Parser) AddMongoFuncs()

AddMongoFuncs adds TokenFuncs for the common mongo Javascript functions that appear in the output from mongosh for some types. They functions included are:

ISODate(arg) returns time.Time when given either a RFC3339 string or milliseconds
ObjectId(arg) returns the arg as a string
NumberInt(arg)  returns the string argument as an int64 or if too large the original string
NumberLong(arg)  returns the string argument as an int64 or if too large the original string
NumberDecimal(arg)  returns the string argument as a float64 or if too large the original string

func (*Parser) AddTokenFunc

func (p *Parser) AddTokenFunc(name string, tf TokenFunc)

AddTokenFunc add a token function that can appear in the data being parsed. As an example `[ISODate("2021-06-28T10:11:12Z")]` could be parsed to a time.Time.

func (*Parser) MustParse

func (p *Parser) MustParse(buf []byte, args ...any) any

MustParse a JSON string in to simple types. Panics on error.

Example
package main

import (
	"fmt"

	"github.com/khaf/ojg"
	"github.com/khaf/ojg/sen"
)

func main() {
	p := sen.Parser{}
	// An invalid JSON but valid SEN.
	simple := p.MustParse([]byte(`{abc: [{"x": {"y": [{b: true}]} z: 7}]}`))
	fmt.Println(sen.String(simple, &ojg.Options{Sort: true}))

}
Output:

{abc:[{x:{y:[{b:true}]} z:7}]}

func (*Parser) MustParseReader

func (p *Parser) MustParseReader(r io.Reader, args ...any) (data any)

MustParseReader a JSON io.Reader. Panics on error.

Example
package main

import (
	"fmt"
	"strings"

	"github.com/khaf/ojg"
	"github.com/khaf/ojg/sen"
)

func main() {
	p := sen.Parser{}
	// An invalid JSON but valid SEN.
	r := strings.NewReader(`{abc: [{"x": {"y": [{b: true}]} z: 7}]}`)
	simple := p.MustParseReader(r)
	fmt.Println(sen.String(simple, &ojg.Options{Sort: true}))

}
Output:

{abc:[{x:{y:[{b:true}]} z:7}]}

func (*Parser) Parse

func (p *Parser) Parse(buf []byte, args ...any) (any, error)

Parse a SEN string in to simple types. An error is returned if not valid SEN.

Example
package main

import (
	"fmt"

	"github.com/khaf/ojg"
	"github.com/khaf/ojg/sen"
)

func main() {
	p := sen.Parser{}
	// An invalid JSON but valid SEN.
	simple, err := p.Parse([]byte(`{abc: [{"x": {"y": [{b: true}]} z: 7}]}`))
	if err != nil {
		panic(err)
	}
	fmt.Println(sen.String(simple, &ojg.Options{Sort: true}))

}
Output:

{abc:[{x:{y:[{b:true}]} z:7}]}

func (*Parser) ParseReader

func (p *Parser) ParseReader(r io.Reader, args ...any) (data any, err error)

ParseReader a SEN io.Reader. An error is returned if not valid SEN.

Example
package main

import (
	"fmt"
	"strings"

	"github.com/khaf/ojg"
	"github.com/khaf/ojg/sen"
)

func main() {
	p := sen.Parser{}
	// An invalid JSON but valid SEN.
	r := strings.NewReader(`{abc: [{"x": {"y": [{b: true}]} z: 7}]}`)
	simple, err := p.ParseReader(r)
	if err != nil {
		panic(err)
	}
	fmt.Println(sen.String(simple, &ojg.Options{Sort: true}))

}
Output:

{abc:[{x:{y:[{b:true}]} z:7}]}

func (*Parser) Unmarshal

func (p *Parser) Unmarshal(data []byte, vp any, recomposer ...alt.Recomposer) (err error)

Unmarshal parses the provided JSON and stores the result in the value pointed to by vp.

Example
package main

import (
	"fmt"

	"github.com/khaf/ojg/sen"
)

func main() {
	type Sample struct {
		X int
		Y string
	}
	p := sen.Parser{}
	var sample Sample
	if err := p.Unmarshal([]byte("{x: 3 y: why}"), &sample); err != nil {
		panic(err)
	}
	fmt.Printf("sample.X: %d  sample.Y: %s\n", sample.X, sample.Y)

}
Output:

sample.X: 3  sample.Y: why

type TokenFunc

type TokenFunc func(args ...any) any

TokenFunc is a function that can be used to evaluate functions embedded in a SEN file.

type Tokenizer

type Tokenizer struct {

	// OnlyOne returns an error if more than one JSON is in the string or stream.
	OnlyOne bool
	// contains filtered or unexported fields
}

Tokenizer is a reusable JSON tokenizer. It can be reused for multiple parsings which allows buffer reuse for a performance advantage.

func (*Tokenizer) Load

func (t *Tokenizer) Load(r io.Reader, handler oj.TokenHandler) (err error)

Load a JSON io.Reader. An error is returned if not valid JSON.

func (*Tokenizer) Parse

func (t *Tokenizer) Parse(buf []byte, handler oj.TokenHandler) (err error)

Parse a JSON string in to simple types. An error is returned if not valid JSON.

type Writer

type Writer struct {
	ojg.Options
	// contains filtered or unexported fields
}

Writer is a SEN writer that includes a reused buffer for reduced allocations for repeated encoding calls.

func (*Writer) MustSEN

func (wr *Writer) MustSEN(data any) []byte

MustSEN writes data, SEN encoded as a []byte and not a string like the SEN() function. On error a panic is called with the error. The returned buffer is the Writer buffer and is reused on the next call to write. If returned value is to be preserved past a second invocation then the buffer should be copied.

Example
package main

import (
	"fmt"

	"github.com/khaf/ojg/sen"
)

func main() {
	type Sample struct {
		X int
		Y string
	}
	wr := sen.Writer{}
	b := wr.MustSEN(&Sample{X: 3, Y: "why"})
	fmt.Println(string(b))

}
Output:

{x:3 y:why}

func (*Writer) MustWrite

func (wr *Writer) MustWrite(w io.Writer, data any)

MustWrite a SEN string for the data provided. If an error occurs panic is called with the error.

Example
package main

import (
	"fmt"
	"strings"

	"github.com/khaf/ojg/sen"
)

func main() {
	type Sample struct {
		X int
		Y string
	}
	wr := sen.Writer{}
	var buf strings.Builder
	wr.MustWrite(&buf, &Sample{X: 3, Y: "why"})
	fmt.Println(buf.String())

}
Output:

{x:3 y:why}

func (*Writer) SEN

func (wr *Writer) SEN(data any) string

SEN writes data, SEN encoded. On error, an empty string is returned.

Example
package main

import (
	"fmt"

	"github.com/khaf/ojg/sen"
)

func main() {
	type Sample struct {
		X int
		Y string
	}
	wr := sen.Writer{}
	s := wr.SEN(&Sample{X: 3, Y: "why"})
	fmt.Println(s)

}
Output:

{x:3 y:why}

func (*Writer) Write

func (wr *Writer) Write(w io.Writer, data any) (err error)

Write a SEN string for the data provided.

Example
package main

import (
	"fmt"
	"strings"

	"github.com/khaf/ojg/sen"
)

func main() {
	type Sample struct {
		X int
		Y string
	}
	wr := sen.Writer{}
	var buf strings.Builder
	if err := wr.Write(&buf, &Sample{X: 3, Y: "why"}); err != nil {
		panic(err)
	}
	fmt.Println(buf.String())

}
Output:

{x:3 y:why}

Jump to

Keyboard shortcuts

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