Documentation ¶
Overview ¶
Example (CustomMarshaler) ¶
package main import ( "log" "os" "strconv" "github.com/alesanro/jettison" ) type Animal int const ( Unknown Animal = iota Gopher Zebra ) // AppendJSON implements the jettison.AppendMarshaler interface. func (a Animal) AppendJSON(dst []byte) ([]byte, error) { var s string switch a { default: s = "unknown" case Gopher: s = "gopher" case Zebra: s = "zebra" } dst = append(dst, strconv.Quote(s)...) return dst, nil } func main() { zoo := []Animal{ Unknown, Zebra, Gopher, } b, err := jettison.Marshal(zoo) if err != nil { log.Fatal(err) } os.Stdout.Write(b) }
Output: ["unknown","zebra","gopher"]
Index ¶
- func Append(dst []byte, v interface{}) ([]byte, error)
- func AppendOpts(dst []byte, v interface{}, opts ...Option) ([]byte, error)
- func Marshal(v interface{}) ([]byte, error)
- func MarshalOpts(v interface{}, opts ...Option) ([]byte, error)
- type AppendMarshaler
- type AppendMarshalerCtx
- type DurationFmt
- type InvalidOptionError
- type MarshalerError
- type Option
- func AllowList(fields []string) Option
- func ByteArrayAsString() Option
- func DenyList(fields []string) Option
- func DurationFormat(format DurationFmt) Option
- func NilMapEmpty() Option
- func NilSliceEmpty() Option
- func NoCompact() Option
- func NoHTMLEscaping() Option
- func NoNumberValidation() Option
- func NoStringEscaping() Option
- func NoUTF8Coercion() Option
- func RawByteSlice() Option
- func TimeLayout(layout string) Option
- func UnixTime() Option
- func UnsortedMap() Option
- func WithContext(ctx context.Context) Option
- type SyntaxError
- type UnsupportedTypeError
- type UnsupportedValueError
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Append ¶
Append is similar to Marshal but appends the JSON representation of v to dst instead of returning a new allocated slice.
Example ¶
package main import ( "log" "os" "github.com/alesanro/jettison" ) func main() { type X struct { A bool `json:"a"` B uint32 `json:"b"` C map[string]string `json:"users"` } x := X{ A: true, B: 42, C: map[string]string{ "bob": "admin", "jerry": "user", }, } buf, err := jettison.Append([]byte(nil), x) if err != nil { log.Fatal(err) } os.Stdout.Write(buf) }
Output: {"a":true,"b":42,"users":{"bob":"admin","jerry":"user"}}
func AppendOpts ¶
AppendOpts is similar to Append, but also accepts a list of options to configure the encoding behavior.
Example ¶
package main import ( "fmt" "log" "time" "github.com/alesanro/jettison" ) func main() { for _, v := range []interface{}{ nil, 2 * time.Second, } { buf, err := jettison.AppendOpts([]byte(nil), v, jettison.DurationFormat(jettison.DurationString), ) if err != nil { log.Fatal(err) } fmt.Printf("%s\n", string(buf)) } }
Output: null "2s"
func Marshal ¶
Marshal returns the JSON encoding of v. The full documentation can be found at https://golang.org/pkg/encoding/json/#Marshal.
Example ¶
package main import ( "log" "os" "github.com/alesanro/jettison" ) func main() { type X struct { A string `json:"a"` B int64 `json:"b"` C []string `json:"colors"` } x := X{ A: "Loreum", B: -42, C: []string{"blue", "white", "red"}, } b, err := jettison.Marshal(x) if err != nil { log.Fatal(err) } os.Stdout.Write(b) }
Output: {"a":"Loreum","b":-42,"colors":["blue","white","red"]}
func MarshalOpts ¶
MarshalOpts is similar to Marshal, but also accepts a list of options to configure the encoding behavior.
Types ¶
type AppendMarshaler ¶
AppendMarshaler is a variant of the json.Marshaler interface, implemented by types that can append a valid and compact JSON representation of themselves to a buffer. If a type implements both interfaces, this one will be used in priority by the package.
type AppendMarshalerCtx ¶
AppendMarshalerCtx is similar to AppendMarshaler, but the method implemented also takes a context. The use case for this interface is to dynamically control the marshaling of the type implementing it through the values encapsulated by the context, that may be provided at runtime using WithContext.
type DurationFmt ¶
type DurationFmt int
DurationFmt represents the format used to encode a time.Duration value.
const ( DurationString DurationFmt = iota DurationMinutes DurationSeconds DurationMilliseconds DurationMicroseconds DurationNanoseconds // default )
DurationFmt constants.
func (DurationFmt) String ¶
func (f DurationFmt) String() string
String implements the fmt.Stringer interface for DurationFmt.
type InvalidOptionError ¶
type InvalidOptionError struct {
Err error
}
InvalidOptionError is the error returned by MarshalOpts when one of the given options is invalid.
func (*InvalidOptionError) Error ¶
func (e *InvalidOptionError) Error() string
Error implements the builtin error interface.
type MarshalerError ¶
type MarshalerError struct { Type reflect.Type Err error // contains filtered or unexported fields }
MarshalerError represents an error from calling the methods MarshalJSON or MarshalText.
func (*MarshalerError) Error ¶
func (e *MarshalerError) Error() string
Error implements the builtin error interface.
func (*MarshalerError) Unwrap ¶
func (e *MarshalerError) Unwrap() error
Unwrap returns the error wrapped by e. This doesn't implement a public interface, but allow to use the errors.Unwrap function released in Go1.13 with a MarshalerError.
type Option ¶
type Option func(*encOpts)
An Option overrides the default encoding behavior of the MarshalOpts function.
func AllowList ¶
AllowList sets the list of first-level fields which are to be considered when encoding a struct. The fields are identified by the name that is used in the final JSON payload. See DenyFields documentation for more information regarding joint use with this option.
Example ¶
package main import ( "fmt" "log" "github.com/alesanro/jettison" ) func main() { type Z struct { Omega int `json:"tω"` Theta int `json:"t"` } type Y struct { Pi string `json:"π"` } type W struct { Zeta Z } type X struct { Z Z `json:"Z"` Alpha string `json:"α"` Beta string `json:"β"` Gamma string Omega W `json:"W"` Y } x := X{ Z: Z{Omega: 42, Theta: 64}, Alpha: "1", Beta: "2", Gamma: "3", Y: Y{Pi: "4"}, Omega: W{Zeta: Z{Omega: 24, Theta: 46}}, } for _, opt := range []jettison.Option{ nil, jettison.AllowList([]string{"Z"}), jettison.AllowList([]string{"Z.t", "β", "Gamma", "π", "W.Zeta.t"}), } { b, err := jettison.MarshalOpts(x, opt) if err != nil { log.Fatal(err) } fmt.Printf("%s\n", string(b)) } }
Output: {"Z":{"tω":42,"t":64},"α":"1","β":"2","Gamma":"3","W":{"Zeta":{"tω":24,"t":46}},"π":"4"} {"Z":{"tω":42,"t":64}} {"Z":{"t":64},"β":"2","Gamma":"3","W":{"Zeta":{"t":46}},"π":"4"}
func ByteArrayAsString ¶
func ByteArrayAsString() Option
ByteArrayAsString configures an encoder to encode byte arrays as raw JSON strings.
Example ¶
package main import ( "fmt" "log" "github.com/alesanro/jettison" ) func main() { b1 := [6]byte{'L', 'o', 'r', 'e', 'u', 'm'} b2 := [6]*byte{&b1[0], &b1[1], &b1[2], &b1[3], &b1[4], &b1[5]} for _, opt := range []jettison.Option{ nil, jettison.ByteArrayAsString(), } { for _, v := range []interface{}{b1, b2} { b, err := jettison.MarshalOpts(v, opt) if err != nil { log.Fatal(err) } fmt.Printf("%s\n", string(b)) } } }
Output: [76,111,114,101,117,109] [76,111,114,101,117,109] "Loreum" [76,111,114,101,117,109]
func DenyList ¶
DenyList is similar to AllowList, but conversely sets the list of fields to omit during encoding. When used in cunjunction with AllowList, denied fields have precedence over the allowed fields.
Example ¶
package main import ( "fmt" "log" "github.com/alesanro/jettison" ) func main() { type Z struct { Omega int `json:"ω"` Theta int `json:"t"` } type W struct { Zeta Z } type X struct { A int `json:"aaAh"` B bool `json:"buzz"` C string D uint E W } x := X{ A: -42, B: true, C: "Loreum", D: 42, E: W{Zeta: Z{Omega: 42, Theta: 64}}, } for _, opt := range []jettison.Option{ nil, jettison.DenyList([]string{"buzz", "D", "E.Zeta.ω"}), } { b, err := jettison.MarshalOpts(x, opt) if err != nil { log.Fatal(err) } fmt.Printf("%s\n", string(b)) } }
Output: {"aaAh":-42,"buzz":true,"C":"Loreum","D":42,"E":{"Zeta":{"ω":42,"t":64}}} {"aaAh":-42,"C":"Loreum","E":{"Zeta":{"t":64}}}
func DurationFormat ¶
func DurationFormat(format DurationFmt) Option
DurationFormat sets the format used to encode time.Duration values.
Example ¶
package main import ( "fmt" "log" "time" "github.com/alesanro/jettison" ) func main() { d := 1*time.Hour + 3*time.Minute + 2*time.Second + 66*time.Millisecond for _, format := range []jettison.DurationFmt{ jettison.DurationString, jettison.DurationMinutes, jettison.DurationSeconds, jettison.DurationMilliseconds, jettison.DurationMicroseconds, jettison.DurationNanoseconds, } { b, err := jettison.MarshalOpts(d, jettison.DurationFormat(format)) if err != nil { log.Fatal(err) } fmt.Printf("%s\n", string(b)) } }
Output: "1h3m2.066s" 63.03443333333333 3782.066 3782066 3782066000 3782066000000
func NilMapEmpty ¶
func NilMapEmpty() Option
NilMapEmpty configures an encoder to encode nil Go maps as empty JSON objects, rather than null.
Example ¶
package main import ( "fmt" "log" "github.com/alesanro/jettison" ) func main() { type X struct { M1 map[string]int M2 map[int]string } x := X{ M1: map[string]int{}, M2: nil, } for _, opt := range []jettison.Option{ nil, jettison.NilMapEmpty(), } { b, err := jettison.MarshalOpts(x, opt) if err != nil { log.Fatal(err) } fmt.Printf("%s\n", string(b)) } }
Output: {"M1":{},"M2":null} {"M1":{},"M2":{}}
func NilSliceEmpty ¶
func NilSliceEmpty() Option
NilSliceEmpty configures an encoder to encode nil Go slices as empty JSON arrays, rather than null.
Example ¶
package main import ( "fmt" "log" "github.com/alesanro/jettison" ) func main() { type X struct { S1 []int S2 []string } x := X{ S1: []int{}, S2: nil, } for _, opt := range []jettison.Option{ nil, jettison.NilSliceEmpty(), } { b, err := jettison.MarshalOpts(x, opt) if err != nil { log.Fatal(err) } fmt.Printf("%s\n", string(b)) } }
Output: {"S1":[],"S2":null} {"S1":[],"S2":[]}
func NoCompact ¶
func NoCompact() Option
NoCompact configures an encoder to disable the compaction of the JSON output produced by a call to MarshalJSON, or the content of a json.RawMessage. see https://golang.org/pkg/encoding/json/#Compact
Example ¶
package main import ( "encoding/json" "fmt" "log" "github.com/alesanro/jettison" ) func main() { rm := json.RawMessage(`{ "a":"b" }`) for _, opt := range []jettison.Option{ nil, jettison.NoCompact(), } { b, err := jettison.MarshalOpts(rm, opt) if err != nil { log.Fatal(err) } fmt.Printf("%s\n", string(b)) } }
Output: {"a":"b"} { "a":"b" }
func NoHTMLEscaping ¶
func NoHTMLEscaping() Option
NoHTMLEscaping configures an encoder to disable the escaping of problematic HTML characters in JSON strings.
func NoNumberValidation ¶
func NoNumberValidation() Option
NoNumberValidation configures an encoder to disable the validation of json.Number values.
func NoStringEscaping ¶
func NoStringEscaping() Option
NoStringEscaping configures an encoder to disable string escaping.
func NoUTF8Coercion ¶
func NoUTF8Coercion() Option
NoUTF8Coercion configures an encoder to disable UTF8 coercion that replace invalid bytes with the Unicode replacement rune.
func RawByteSlice ¶
func RawByteSlice() Option
RawByteSlice configures an encoder to encode byte slices as raw JSON strings, rather than bas64-encoded strings.
Example ¶
package main import ( "fmt" "log" "github.com/alesanro/jettison" ) func main() { bs := []byte("Loreum Ipsum") for _, opt := range []jettison.Option{ nil, jettison.RawByteSlice(), } { b, err := jettison.MarshalOpts(bs, opt) if err != nil { log.Fatal(err) } fmt.Printf("%s\n", string(b)) } }
Output: "TG9yZXVtIElwc3Vt" "Loreum Ipsum"
func TimeLayout ¶
TimeLayout sets the time layout used to encode time.Time values. The layout must be compatible with the Golang time package specification.
Example ¶
package main import ( "fmt" "log" "time" "github.com/alesanro/jettison" ) func main() { t := time.Date(2042, time.July, 25, 16, 42, 24, 67850, time.UTC) locs := []*time.Location{ time.UTC, time.FixedZone("WTF", 666), time.FixedZone("LOL", -4242), } for _, layout := range []string{ time.RFC3339, time.RFC822, time.RFC1123Z, time.RFC3339Nano, // default } { for _, loc := range locs { b, err := jettison.MarshalOpts(t.In(loc), jettison.TimeLayout(layout)) if err != nil { log.Fatal(err) } fmt.Printf("%s\n", string(b)) } } }
Output: "2042-07-25T16:42:24Z" "2042-07-25T16:53:30+00:11" "2042-07-25T15:31:42-01:10" "25 Jul 42 16:42 UTC" "25 Jul 42 16:53 WTF" "25 Jul 42 15:31 LOL" "Fri, 25 Jul 2042 16:42:24 +0000" "Fri, 25 Jul 2042 16:53:30 +0011" "Fri, 25 Jul 2042 15:31:42 -0110" "2042-07-25T16:42:24.00006785Z" "2042-07-25T16:53:30.00006785+00:11" "2042-07-25T15:31:42.00006785-01:10"
func UnixTime ¶
func UnixTime() Option
UnixTime configures an encoder to encode time.Time values as Unix timestamps. This option, when used, has precedence over any time layout confiured.
Example ¶
package main import ( "log" "os" "time" "github.com/alesanro/jettison" ) func main() { t := time.Date(2024, time.December, 24, 12, 24, 42, 0, time.UTC) b, err := jettison.MarshalOpts(t, jettison.UnixTime()) if err != nil { log.Fatal(err) } os.Stdout.Write(b) }
Output: 1735043082
func UnsortedMap ¶
func UnsortedMap() Option
UnsortedMap configures an encoder to skip the sort of map keys.
Example ¶
package main import ( "encoding/json" "log" "os" "github.com/alesanro/jettison" ) func main() { m := map[int]string{ 3: "three", 1: "one", 2: "two", } b, err := jettison.MarshalOpts(m, jettison.UnsortedMap()) if err != nil { log.Fatal(err) } var sorted map[int]string if err := json.Unmarshal(b, &sorted); err != nil { log.Fatal(err) } b, err = jettison.Marshal(sorted) if err != nil { log.Fatal(err) } os.Stdout.Write(b) }
Output: {"1":"one","2":"two","3":"three"}
func WithContext ¶
WithContext sets the context to use during encoding. The context will be passed in to the AppendJSONContext method of types that implement the AppendMarshalerCtx interface.
Example ¶
package main import ( "context" "fmt" "log" "strconv" "github.com/alesanro/jettison" ) type ( secret string ctxKey string ) const obfuscateKey = ctxKey("_obfuscate_") // AppendJSONContext implements the jettison.AppendMarshalerCtx interface. func (s secret) AppendJSONContext(ctx context.Context, dst []byte) ([]byte, error) { out := string(s) if v := ctx.Value(obfuscateKey); v != nil { if hide, ok := v.(bool); ok && hide { out = "**__SECRET__**" } } dst = append(dst, strconv.Quote(out)...) return dst, nil } func main() { sec := secret("v3ryS3nSitiv3P4ssWord") b, err := jettison.Marshal(sec) if err != nil { log.Fatal(err) } fmt.Printf("%s\n", string(b)) ctx := context.WithValue(context.Background(), obfuscateKey, true, ) b, err = jettison.MarshalOpts(sec, jettison.WithContext(ctx)) if err != nil { log.Fatal(err) } fmt.Printf("%s\n", string(b)) }
Output: "v3ryS3nSitiv3P4ssWord" "**__SECRET__**"
type SyntaxError ¶
type SyntaxError struct { Offset int64 // contains filtered or unexported fields }
A SyntaxError is a description of a JSON syntax error. Unlike its equivalent in the encoding/json package, the Error method implemented does not return a meaningful message, and the Offset field is always zero. It is present merely for consistency.
func (*SyntaxError) Error ¶
func (e *SyntaxError) Error() string
Error implements the builtin error interface.
type UnsupportedTypeError ¶
UnsupportedTypeError is the error returned by Marshal when attempting to encode an unsupported value type.
func (*UnsupportedTypeError) Error ¶
func (e *UnsupportedTypeError) Error() string
Error implements the bultin error interface.
type UnsupportedValueError ¶
UnsupportedValueError is the error returned by Marshal when attempting to encode an unsupported value.
func (*UnsupportedValueError) Error ¶
func (e *UnsupportedValueError) Error() string
Error implements the builtin error interface.