Documentation ¶
Overview ¶
Package sen contains the SEN parsers and writers.
Index ¶
- Variables
- func Bytes(data any, args ...any) []byte
- func MustParse(buf []byte, args ...any) any
- func MustParseReader(r io.Reader, args ...any) (data any)
- func MustWrite(w io.Writer, data any, args ...any)
- func Parse(buf []byte, args ...any) (any, error)
- func ParseReader(r io.Reader, args ...any) (data any, err error)
- func String(data any, args ...any) string
- func Tokenize(data []byte, handler oj.TokenHandler) error
- func TokenizeLoad(r io.Reader, handler oj.TokenHandler) error
- func TokenizeString(data string, handler oj.TokenHandler) error
- func Unmarshal(data []byte, vp any, recomposer ...*alt.Recomposer) (err error)
- func Write(w io.Writer, data any, args ...any) (err error)
- type Options
- type Parser
- func (p *Parser) AddMongoFuncs()
- func (p *Parser) AddTokenFunc(name string, tf TokenFunc)
- func (p *Parser) MustParse(buf []byte, args ...any) any
- func (p *Parser) MustParseReader(r io.Reader, args ...any) (data any)
- func (p *Parser) Parse(buf []byte, args ...any) (any, error)
- func (p *Parser) ParseReader(r io.Reader, args ...any) (data any, err error)
- func (p *Parser) Unmarshal(data []byte, vp any, recomposer ...alt.Recomposer) (err error)
- type TokenFunc
- type Tokenizer
- type Writer
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 Bytes ¶ added in v1.11.0
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
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
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
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
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
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 ¶
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 ¶
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 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
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
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
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 ¶
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 ¶
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
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
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.
type Writer ¶ added in v1.11.0
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
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
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
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
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}