sen

package
v1.22.0 Latest Latest
Warning

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

Go to latest
Published: Apr 28, 2024 License: MIT Imports: 20 Imported by: 2

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 added in v1.11.0

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/ohler55/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 added in v1.11.0

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/ohler55/ojg/pretty"
	"github.com/ohler55/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 added in v1.11.0

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/ohler55/ojg/pretty"
	"github.com/ohler55/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 added in v1.11.0

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/ohler55/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 added in v1.6.0

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/ohler55/ojg/pretty"
	"github.com/ohler55/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 added in v1.6.0

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/ohler55/ojg/pretty"
	"github.com/ohler55/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/ohler55/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 added in v1.10.0

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 added in v1.10.0

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

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

func TokenizeString added in v1.10.0

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 added in v1.9.0

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/ohler55/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/ohler55/ojg"
	"github.com/ohler55/ojg/alt"
	"github.com/ohler55/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/ohler55/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 added in v1.12.0

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 added in v1.12.0

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 added in v1.11.0

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/ohler55/ojg"
	"github.com/ohler55/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 added in v1.11.0

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/ohler55/ojg"
	"github.com/ohler55/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/ohler55/ojg"
	"github.com/ohler55/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/ohler55/ojg"
	"github.com/ohler55/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 added in v1.9.0

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/ohler55/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 added in v1.12.0

type TokenFunc func(args ...any) any

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

type Tokenizer added in v1.10.0

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 added in v1.10.0

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 added in v1.10.0

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 added in v1.11.0

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 added in v1.11.0

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/ohler55/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 added in v1.11.0

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/ohler55/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 added in v1.11.0

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/ohler55/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 added in v1.11.0

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/ohler55/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