Documentation
¶
Overview ¶
Package oj contains functions and types to support building simple types where simple types are:
nil bool int64 float64 string time.Time []any map[string]any
Parser ¶
Parse a JSON file or stream. The parser can be used on a single JSON document or a document with multiple JSON elements. An option also exists to allow comments in the JSON.
v, err := oj.ParseString("[true,[false,[null],123],456]")
or for a performance gain on repeated parses:
var p oj.Parser
v, err := p.Parse([]byte("[true,[false,[null],123],456]"))
Validator ¶
Validates a JSON file or stream. It can be used on a single JSON document or a document with multiple JSON elements. An option also exists to allow comments in the JSON.
err := oj.ValidateString("[true,[false,[null],123],456]")
or for a slight performance gain on repeated validations:
var v oj.Validator
err := v.Validate([]byte("[true,[false,[null],123],456]"))
Builder ¶
An example of building simple data is:
var b oj.Builder
b.Object()
b.Value(1, "a")
b.Array("b")
b.Value(2)
b.Pop()
b.Pop()
v := b.Result()
// v: map[string]any{"a": 1, "b": []any{2}}
Writer ¶
The writer function's output data values to JSON. The basic oj.JSON() attempts to build JSON from any data provided skipping types that can not be converted.
s := oj.JSON([]any{1, 2, "abc", true})
Output can also be use with an io.Writer.
var b strings.Builder
err := oj.Write(&b, []any{1, 2, "abc", true})
Index ¶
- Variables
- func JSON(data any, args ...any) string
- func Load(r io.Reader, args ...any) (any, error)
- func Marshal(data any, args ...any) (out []byte, err error)
- func Match(data []byte, onData func(path jp.Expr, data any), targets ...jp.Expr) error
- func MatchLoad(r io.Reader, onData func(path jp.Expr, data any), targets ...jp.Expr) error
- func MatchString(data string, onData func(path jp.Expr, data any), targets ...jp.Expr) error
- func MustLoad(r io.Reader, args ...any) (n any)
- func MustParse(b []byte, args ...any) (n any)
- func MustParseString(s string, args ...any) (n any)
- func Parse(b []byte, args ...any) (n any, err error)
- func ParseString(s string, args ...any) (n any, err error)
- func Tokenize(data []byte, handler TokenHandler) error
- func TokenizeLoad(r io.Reader, handler TokenHandler) error
- func TokenizeString(data string, handler TokenHandler) error
- func Unmarshal(data []byte, vp any, recomposer ...*alt.Recomposer) (err error)
- func Validate(b []byte) error
- func ValidateReader(r io.Reader) error
- func ValidateString(s string) error
- func Write(w io.Writer, data any, args ...any) (err error)
- type Builder
- type Options
- type ParseError
- type Parser
- type SimpleParser
- type TokenHandler
- type Tokenizer
- type Validator
- type Writer
- type ZeroHandler
- func (z *ZeroHandler) ArrayEnd()
- func (z *ZeroHandler) ArrayStart()
- func (z *ZeroHandler) Bool(bool)
- func (z *ZeroHandler) Float(float64)
- func (z *ZeroHandler) Int(int64)
- func (z *ZeroHandler) Key(string)
- func (z *ZeroHandler) Null()
- func (z *ZeroHandler) Number(string)
- func (z *ZeroHandler) ObjectEnd()
- func (z *ZeroHandler) ObjectStart()
- func (z *ZeroHandler) String(string)
Examples ¶
Constants ¶
This section is empty.
Variables ¶
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 JSON ¶
JSON returns a JSON 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 or a *Options.
Example ¶
package main
import (
"fmt"
"github.com/ohler55/ojg/oj"
)
func main() {
type Valley struct {
Val int `json:"value"`
}
b := oj.JSON(&Valley{Val: 3})
fmt.Printf("%s\n", b)
}
Output: {"val":3}
func Load ¶
Load a JSON from a io.Reader into a simple type. An error is returned if not valid JSON.
Example ¶
package main
import (
"fmt"
"strings"
"github.com/ohler55/ojg/oj"
"github.com/ohler55/ojg/pretty"
)
func main() {
r := strings.NewReader(`[true,false,[3,2,1],{"a":1,"b":2,"c":3,"d":["x","y","z",[]]}]`)
val, err := oj.Load(r)
if err != nil {
panic(err)
}
fmt.Println(pretty.JSON(val, 80.3))
}
Output: [ true, false, [3, 2, 1], {"a": 1, "b": 2, "c": 3, "d": ["x", "y", "z", []]} ]
func Marshal ¶ added in v1.3.0
Marshal returns a JSON 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 gen.Node type, The args, if supplied can be an int as an indent, *ojg.Options, or a *Writer. An error will be returned if the Option.Strict flag is true and a value is encountered that can not be encoded other than by using the %v format of the fmt package.
Example ¶
package main
import (
"fmt"
"github.com/ohler55/ojg/oj"
)
func main() {
type Valley struct {
Val int `json:"value"`
}
b, err := oj.Marshal(&Valley{Val: 3})
fmt.Printf("%v %s\n", err, b)
}
Output: <nil> {"value":3}
func Match ¶ added in v1.24.0
Match parses a JSON document and calls onData when a data element that matches the target path is encountered.
func MatchLoad ¶ added in v1.24.0
MatchLoad parses a JSON document from an io.Reader and calls onData when a data element that matches the target path is encountered.
func MatchString ¶ added in v1.24.0
MatchString parses a JSON document and calls onData when a data element that matches the target path is encountered.
func MustLoad ¶ added in v1.11.0
MustLoad a JSON from a io.Reader into a simple type. Panics on error.
Example ¶
package main
import (
"fmt"
"strings"
"github.com/ohler55/ojg/oj"
"github.com/ohler55/ojg/pretty"
)
func main() {
r := strings.NewReader(`[true,false,[3,2,1],{"a":1,"b":2,"c":3,"d":["x","y","z",[]]}]`)
val := oj.MustLoad(r)
fmt.Println(pretty.JSON(val, 80.3))
}
Output: [ true, false, [3, 2, 1], {"a": 1, "b": 2, "c": 3, "d": ["x", "y", "z", []]} ]
func MustParse ¶ added in v1.11.0
MustParse JSON into a simple type. Arguments are optional and can be a bool, func(any) bool for callbacks, or a chan any for chan based result delivery. Panics on error
A bool indicates the NoComment parser attribute should be set to the bool value.
A func argument is the callback for the parser if processing multiple JSONs. If no callback function is provided the processing is limited to only one JSON.
A chan argument will be used to deliver parse results.
Example ¶
package main
import (
"fmt"
"github.com/ohler55/ojg/oj"
"github.com/ohler55/ojg/pretty"
)
func main() {
val := oj.MustParse([]byte(`[true,false,[3,2,1],{"a":1,"b":2,"c":3,"d":["x","y","z",[]]}]`))
fmt.Println(pretty.JSON(val, 80.3))
}
Output: [ true, false, [3, 2, 1], {"a": 1, "b": 2, "c": 3, "d": ["x", "y", "z", []]} ]
func MustParseString ¶ added in v1.11.0
MustParseString is similar to MustParse except it takes a string argument to be parsed instead of a []byte.
Example ¶
package main
import (
"fmt"
"github.com/ohler55/ojg/oj"
"github.com/ohler55/ojg/pretty"
)
func main() {
val := oj.MustParseString(`[true,false,[3,2,1],{"a":1,"b":2,"c":3,"d":["x","y","z",[]]}]`)
fmt.Println(pretty.JSON(val, 80.3))
}
Output: [ true, false, [3, 2, 1], {"a": 1, "b": 2, "c": 3, "d": ["x", "y", "z", []]} ]
func Parse ¶
Parse JSON into a simple type. Arguments are optional and can be a bool, func(any) bool for callbacks, or a chan any for chan based result delivery.
A bool indicates the NoComment parser attribute should be set to the bool value.
A func argument is the callback for the parser if processing multiple JSONs. If no callback function is provided the processing is limited to only one JSON.
A chan argument will be used to deliver parse results.
Example ¶
package main
import (
"fmt"
"github.com/ohler55/ojg/oj"
"github.com/ohler55/ojg/pretty"
)
func main() {
val, err := oj.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.JSON(val, 80.3))
}
Output: [ true, false, [3, 2, 1], {"a": 1, "b": 2, "c": 3, "d": ["x", "y", "z", []]} ]
func ParseString ¶
ParseString is similar to Parse except it takes a string argument to be parsed instead of a []byte.
Example ¶
package main
import (
"fmt"
"github.com/ohler55/ojg/oj"
)
func main() {
v, err := oj.ParseString(`{"a": 1, "b":[2,3,4]}`)
if err == nil {
// Sorted output allows for consistent results.
fmt.Println(oj.JSON(v, &oj.Options{Sort: true}))
} else {
fmt.Println(err.Error())
}
}
Output: {"a":1,"b":[2,3,4]}
func Tokenize ¶ added in v1.10.0
func Tokenize(data []byte, handler TokenHandler) error
Tokenize the provided JSON and call the TokenHandler functions for each token in the JSON.
func TokenizeLoad ¶ added in v1.10.0
func TokenizeLoad(r io.Reader, handler TokenHandler) error
TokenizeLoad JSON from a io.Reader and call the TokenHandler functions for each token in the JSON.
func TokenizeString ¶ added in v1.10.0
func TokenizeString(data string, handler 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 (Interface) ¶
package main
import (
"fmt"
"github.com/ohler55/ojg"
"github.com/ohler55/ojg/alt"
"github.com/ohler55/ojg/oj"
)
// 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, err := oj.Marshal(pets, &ojg.Options{CreateKey: "^", Sort: true})
if err != nil {
panic(err)
}
// 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.
var r *alt.Recomposer
if r, err = alt.NewRecomposer("^", map[any]alt.RecomposeFunc{&Dog{}: nil, &Cat{}: nil}); err != nil {
panic(err)
}
var result any
if err = oj.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 = oj.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 *oj_test.Dog - big dog *oj_test.Cat - black cat
func ValidateReader ¶
ValidateReader a JSON stream. An error is returned if not valid JSON.
func ValidateString ¶
ValidateString a JSON string. An error is returned if not valid JSON.
Example ¶
package main
import (
"fmt"
"github.com/ohler55/ojg/oj"
)
func main() {
err := oj.ValidateString(`{"a": 1, "b":[2,3,4]}`)
fmt.Println(oj.JSON(err))
}
Output: null
func Write ¶
Write a JSON 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 or a *Options.
Example ¶
package main
import (
"fmt"
"strings"
"github.com/ohler55/ojg"
"github.com/ohler55/ojg/oj"
)
func main() {
var b strings.Builder
data := []any{
map[string]any{
"x": 1,
"y": 2,
},
}
if err := oj.Write(&b, data, &ojg.Options{Sort: true}); err != nil {
panic(err)
}
fmt.Println(b.String())
}
Output: [{"x":1,"y":2}]
Types ¶
type Builder ¶
Builder is an aliase for alt.Builder.
Example ¶
package main
import (
"fmt"
"github.com/ohler55/ojg/oj"
)
func main() {
var b oj.Builder
_ = b.Object()
_ = b.Array("a")
_ = b.Value(true)
_ = b.Object()
_ = b.Value(123, "x")
b.Pop()
_ = b.Value(nil)
b.PopAll()
v := b.Result()
fmt.Println(oj.JSON(v))
}
Output: {"a":[true,{"x":123},null]}
type ParseError ¶
ParseError represents a parse error.
func (*ParseError) Error ¶
func (err *ParseError) Error() string
Error returns a string representation of the error.
type Parser ¶
type Parser struct {
// Reuse maps. Previously returned maps will no longer be valid or rather
// could be modified during parsing.
Reuse 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) Parse ¶
Parse a JSON string in to simple types. An error is returned if not valid JSON.
Example ¶
package main
import (
"fmt"
"github.com/ohler55/ojg/oj"
)
func main() {
// The parser can be reused for better performance by reusing buffers.
var p oj.Parser
v, err := p.Parse([]byte(`{"a": 1, "b":[2,3,4]}`))
if err == nil {
// Sorted output allows for consistent results.
fmt.Println(oj.JSON(v, &oj.Options{Sort: true}))
} else {
fmt.Println(err.Error())
}
}
Output: {"a":1,"b":[2,3,4]}
Example (Callback) ¶
package main
import (
"fmt"
"github.com/ohler55/ojg/oj"
)
func main() {
var results []byte
cb := func(n any) bool {
if 0 < len(results) {
results = append(results, ' ')
}
results = append(results, oj.JSON(n)...)
return false
}
var p oj.Parser
_, _ = p.Parse([]byte("[1,2][3,4][5,6]"), cb)
fmt.Println(string(results))
}
Output: [1,2] [3,4] [5,6]
func (*Parser) ParseReader ¶
ParseReader reads JSON from an io.Reader. An error is returned if not valid JSON.
Example ¶
package main
import (
"fmt"
"strings"
"github.com/ohler55/ojg/oj"
)
func main() {
// The parser can be reused for better performance by reusing buffers.
var p oj.Parser
v, err := p.ParseReader(strings.NewReader(`{"a": 1, "b":[2,3,4]}`))
if err == nil {
// Sorted output allows for consistent results.
fmt.Println(oj.JSON(v, &oj.Options{Sort: true}))
} else {
fmt.Println(err.Error())
}
}
Output: {"a":1,"b":[2,3,4]}
type SimpleParser ¶ added in v1.1.0
type SimpleParser interface {
// Parse a string in to simple types. An error is returned if not valid.
Parse(buf []byte, args ...any) (data any, err error)
// ParseReader an io.Reader. An error is returned if not valid.
ParseReader(r io.Reader, args ...any) (node any, err error)
}
SimpleParser is the interface shared by the package parsers.
type TokenHandler ¶ added in v1.10.0
type TokenHandler interface {
// Null is called when a JSON null is encountered.
Null()
// Bool is called when a JSON true or false is encountered.
Bool(bool)
// Int is called when a JSON integer is encountered.
Int(int64)
// Float is called when a JSON decimal is encountered that fits into a
// float64.
Float(float64)
// Number is called when a JSON number is encountered that does not fit
// into an int64 or float64.
Number(string)
// String is called when a JSON string is encountered.
String(string)
// ObjectStart is called when a JSON object start '{' is encountered.
ObjectStart()
// ObjectEnd is called when a JSON object end '}' is encountered.
ObjectEnd()
// Key is called when a JSON object key is encountered.
Key(string)
// ArrayStart is called when a JSON array start '[' is encountered.
ArrayStart()
// ArrayEnd is called when a JSON array end ']' is encountered.
ArrayEnd()
}
TokenHandler describes an interface for handling tokens when using the Tokenizer for parsing JSON or SEN documents.
type Tokenizer ¶ added in v1.10.0
type Tokenizer struct {
// contains filtered or unexported fields
}
Tokenizer is used to tokenize a JSON document.
func (*Tokenizer) Load ¶ added in v1.10.0
func (t *Tokenizer) Load(r io.Reader, handler TokenHandler) (err error)
Load aand parse the JSON and call the handler functions for each token in the JSON.
func (*Tokenizer) Parse ¶ added in v1.10.0
func (t *Tokenizer) Parse(buf []byte, handler TokenHandler) (err error)
Parse the JSON and call the handler functions for each token in the JSON.
Example ¶
package main
import (
"bytes"
"fmt"
"github.com/ohler55/ojg/oj"
)
type Toker struct {
buf []byte
}
func (h *Toker) Null() {
h.buf = append(h.buf, "null "...)
}
func (h *Toker) Bool(v bool) {
h.buf = append(h.buf, fmt.Sprintf("%t ", v)...)
}
func (h *Toker) Int(v int64) {
h.buf = append(h.buf, fmt.Sprintf("%d ", v)...)
}
func (h *Toker) Float(v float64) {
h.buf = append(h.buf, fmt.Sprintf("%g ", v)...)
}
func (h *Toker) Number(v string) {
h.buf = append(h.buf, fmt.Sprintf("%s ", v)...)
}
func (h *Toker) String(v string) {
h.buf = append(h.buf, fmt.Sprintf("%s ", v)...)
}
func (h *Toker) ObjectStart() {
h.buf = append(h.buf, '{')
h.buf = append(h.buf, ' ')
}
func (h *Toker) ObjectEnd() {
h.buf = append(h.buf, '}')
h.buf = append(h.buf, ' ')
}
func (h *Toker) Key(v string) {
h.buf = append(h.buf, fmt.Sprintf("%s: ", v)...)
}
func (h *Toker) ArrayStart() {
h.buf = append(h.buf, '[')
h.buf = append(h.buf, ' ')
}
func (h *Toker) ArrayEnd() {
h.buf = append(h.buf, ']')
h.buf = append(h.buf, ' ')
}
func main() {
toker := oj.Tokenizer{}
h := Toker{}
src := `[true,null,123,12.3]{"x":12345678901234567890}`
if err := toker.Parse([]byte(src), &h); err != nil {
panic(err)
}
fmt.Println(string(bytes.TrimSpace(h.buf)))
}
Output: [ true null 123 12.3 ] { x: 12345678901234567890 }
type Validator ¶
type Validator struct {
// OnlyOne returns an error if more than one JSON is in the string or
// stream.
OnlyOne bool
// contains filtered or unexported fields
}
Validator is a reusable JSON validator. It can be reused for multiple validations or parsings which allows buffer reuse for a performance advantage.
type Writer ¶ added in v1.11.0
Writer is a JSON writer that includes a reused buffer for reduced allocations for repeated encoding calls.
func (*Writer) JSON ¶ added in v1.11.0
JSON writes data, JSON encoded. On error, an empty string is returned.
Example ¶
package main
import (
"fmt"
"github.com/ohler55/ojg"
"github.com/ohler55/ojg/oj"
)
func main() {
data := []any{
map[string]any{
"x": 1,
"y": 2,
},
}
wr := oj.Writer{Options: ojg.Options{Sort: true}}
j := wr.JSON(data)
fmt.Println(j)
}
Output: [{"x":1,"y":2}]
func (*Writer) MustJSON ¶ added in v1.11.0
MustJSON writes data, JSON encoded as a []byte and not a string like the JSON() 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.
func (*Writer) MustWrite ¶ added in v1.11.0
MustWrite a JSON 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"
"github.com/ohler55/ojg/oj"
)
func main() {
var b strings.Builder
data := []any{
map[string]any{
"x": 1,
"y": 2,
},
}
wr := oj.Writer{Options: ojg.Options{Sort: true}}
wr.MustWrite(&b, data)
fmt.Println(b.String())
}
Output: [{"x":1,"y":2}]
type ZeroHandler ¶ added in v1.10.0
type ZeroHandler struct {
}
ZeroHandler is a TokenHandler whose functions do nothing. It is used as an embedded member for TokenHandlers that don't care about all of the TokenHandler functions.
func (*ZeroHandler) ArrayEnd ¶ added in v1.10.0
func (z *ZeroHandler) ArrayEnd()
ArrayEnd is called when a JSON array end ']' is encountered.
func (*ZeroHandler) ArrayStart ¶ added in v1.10.0
func (z *ZeroHandler) ArrayStart()
ArrayStart is called when a JSON array start '[' is encountered.
func (*ZeroHandler) Bool ¶ added in v1.10.0
func (z *ZeroHandler) Bool(bool)
Bool is called when a JSON true or false is encountered.
func (*ZeroHandler) Float ¶ added in v1.10.0
func (z *ZeroHandler) Float(float64)
Float is called when a JSON decimal is encountered that fits into a float64.
func (*ZeroHandler) Int ¶ added in v1.10.0
func (z *ZeroHandler) Int(int64)
Int is called when a JSON integer is encountered.
func (*ZeroHandler) Key ¶ added in v1.10.0
func (z *ZeroHandler) Key(string)
Key is called when a JSON object key is encountered.
func (*ZeroHandler) Null ¶ added in v1.10.0
func (z *ZeroHandler) Null()
Null is called when a JSON null is encountered.
func (*ZeroHandler) Number ¶ added in v1.10.0
func (z *ZeroHandler) Number(string)
Number is called when a JSON number is encountered that does not fit into an int64 or float64.
func (*ZeroHandler) ObjectEnd ¶ added in v1.10.0
func (z *ZeroHandler) ObjectEnd()
ObjectEnd is called when a JSON object end '}' is encountered.
func (*ZeroHandler) ObjectStart ¶ added in v1.10.0
func (z *ZeroHandler) ObjectStart()
ObjectStart is called when a JSON object start '{' is encountered.
func (*ZeroHandler) String ¶ added in v1.10.0
func (z *ZeroHandler) String(string)
String is called when a JSON string is encountered.
Source Files
¶
- color.go
- doc.go
- error.go
- fbool.go
- ffloat32.go
- ffloat64.go
- finfo.go
- fint.go
- fint16.go
- fint32.go
- fint64.go
- fint8.go
- fuint.go
- fuint16.go
- fuint32.go
- fuint64.go
- fuint8.go
- genericer.go
- jsonmarshaler.go
- maps.go
- oj.go
- parser.go
- simpleparser.go
- simplifier.go
- sinfo.go
- textmarshaler.go
- tight.go
- tokenhandler.go
- tokenizer.go
- tracker.go
- validator.go
- writer.go
- zerohandler.go