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