github.com/wI2L/jettison@v0.7.5-0.20230106001914-c70014c6417a/example_test.go (about)

     1  package jettison_test
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"fmt"
     7  	"log"
     8  	"os"
     9  	"strconv"
    10  	"time"
    11  
    12  	"github.com/wI2L/jettison"
    13  )
    14  
    15  func ExampleMarshal() {
    16  	type X struct {
    17  		A string   `json:"a"`
    18  		B int64    `json:"b"`
    19  		C []string `json:"colors"`
    20  	}
    21  	x := X{
    22  		A: "Loreum",
    23  		B: -42,
    24  		C: []string{"blue", "white", "red"},
    25  	}
    26  	b, err := jettison.Marshal(x)
    27  	if err != nil {
    28  		log.Fatal(err)
    29  	}
    30  	os.Stdout.Write(b)
    31  	// Output:
    32  	// {"a":"Loreum","b":-42,"colors":["blue","white","red"]}
    33  }
    34  
    35  func ExampleAppend() {
    36  	type X struct {
    37  		A bool              `json:"a"`
    38  		B uint32            `json:"b"`
    39  		C map[string]string `json:"users"`
    40  	}
    41  	x := X{
    42  		A: true,
    43  		B: 42,
    44  		C: map[string]string{
    45  			"bob":   "admin",
    46  			"jerry": "user",
    47  		},
    48  	}
    49  	buf, err := jettison.Append([]byte(nil), x)
    50  	if err != nil {
    51  		log.Fatal(err)
    52  	}
    53  	os.Stdout.Write(buf)
    54  	// Output:
    55  	// {"a":true,"b":42,"users":{"bob":"admin","jerry":"user"}}
    56  }
    57  
    58  func ExampleAppendOpts() {
    59  	for _, v := range []interface{}{
    60  		nil, 2 * time.Second,
    61  	} {
    62  		buf, err := jettison.AppendOpts([]byte(nil), v,
    63  			jettison.DurationFormat(jettison.DurationString),
    64  		)
    65  		if err != nil {
    66  			log.Fatal(err)
    67  		}
    68  		fmt.Printf("%s\n", string(buf))
    69  	}
    70  	// Output:
    71  	// null
    72  	// "2s"
    73  }
    74  
    75  type Animal int
    76  
    77  const (
    78  	Unknown Animal = iota
    79  	Gopher
    80  	Zebra
    81  )
    82  
    83  // AppendJSON implements the jettison.AppendMarshaler interface.
    84  func (a Animal) AppendJSON(dst []byte) ([]byte, error) {
    85  	var s string
    86  	switch a {
    87  	default:
    88  		s = "unknown"
    89  	case Gopher:
    90  		s = "gopher"
    91  	case Zebra:
    92  		s = "zebra"
    93  	}
    94  	dst = append(dst, strconv.Quote(s)...)
    95  	return dst, nil
    96  }
    97  
    98  func Example_customMarshaler() {
    99  	zoo := []Animal{
   100  		Unknown,
   101  		Zebra,
   102  		Gopher,
   103  	}
   104  	b, err := jettison.Marshal(zoo)
   105  	if err != nil {
   106  		log.Fatal(err)
   107  	}
   108  	os.Stdout.Write(b)
   109  	// Output:
   110  	// ["unknown","zebra","gopher"]
   111  }
   112  
   113  func ExampleRawByteSlice() {
   114  	bs := []byte("Loreum Ipsum")
   115  
   116  	for _, opt := range []jettison.Option{
   117  		nil, jettison.RawByteSlice(),
   118  	} {
   119  		b, err := jettison.MarshalOpts(bs, opt)
   120  		if err != nil {
   121  			log.Fatal(err)
   122  		}
   123  		fmt.Printf("%s\n", string(b))
   124  	}
   125  	// Output:
   126  	// "TG9yZXVtIElwc3Vt"
   127  	// "Loreum Ipsum"
   128  }
   129  
   130  func ExampleByteArrayAsString() {
   131  	b1 := [6]byte{'L', 'o', 'r', 'e', 'u', 'm'}
   132  	b2 := [6]*byte{&b1[0], &b1[1], &b1[2], &b1[3], &b1[4], &b1[5]}
   133  
   134  	for _, opt := range []jettison.Option{
   135  		nil, jettison.ByteArrayAsString(),
   136  	} {
   137  		for _, v := range []interface{}{b1, b2} {
   138  			b, err := jettison.MarshalOpts(v, opt)
   139  			if err != nil {
   140  				log.Fatal(err)
   141  			}
   142  			fmt.Printf("%s\n", string(b))
   143  		}
   144  	}
   145  	// Output:
   146  	// [76,111,114,101,117,109]
   147  	// [76,111,114,101,117,109]
   148  	// "Loreum"
   149  	// [76,111,114,101,117,109]
   150  }
   151  
   152  func ExampleNilMapEmpty() {
   153  	type X struct {
   154  		M1 map[string]int
   155  		M2 map[int]string
   156  	}
   157  	x := X{
   158  		M1: map[string]int{},
   159  		M2: nil,
   160  	}
   161  	for _, opt := range []jettison.Option{
   162  		nil, jettison.NilMapEmpty(),
   163  	} {
   164  		b, err := jettison.MarshalOpts(x, opt)
   165  		if err != nil {
   166  			log.Fatal(err)
   167  		}
   168  		fmt.Printf("%s\n", string(b))
   169  	}
   170  	// Output:
   171  	// {"M1":{},"M2":null}
   172  	// {"M1":{},"M2":{}}
   173  }
   174  
   175  func ExampleNilSliceEmpty() {
   176  	type X struct {
   177  		S1 []int
   178  		S2 []string
   179  	}
   180  	x := X{
   181  		S1: []int{},
   182  		S2: nil,
   183  	}
   184  	for _, opt := range []jettison.Option{
   185  		nil, jettison.NilSliceEmpty(),
   186  	} {
   187  		b, err := jettison.MarshalOpts(x, opt)
   188  		if err != nil {
   189  			log.Fatal(err)
   190  		}
   191  		fmt.Printf("%s\n", string(b))
   192  	}
   193  	// Output:
   194  	// {"S1":[],"S2":null}
   195  	// {"S1":[],"S2":[]}
   196  }
   197  
   198  func ExampleUnixTime() {
   199  	t := time.Date(2024, time.December, 24, 12, 24, 42, 0, time.UTC)
   200  
   201  	b, err := jettison.MarshalOpts(t, jettison.UnixTime())
   202  	if err != nil {
   203  		log.Fatal(err)
   204  	}
   205  	os.Stdout.Write(b)
   206  	// Output:
   207  	// 1735043082
   208  }
   209  
   210  func ExampleTimeLayout() {
   211  	t := time.Date(2042, time.July, 25, 16, 42, 24, 67850, time.UTC)
   212  
   213  	locs := []*time.Location{
   214  		time.UTC, time.FixedZone("WTF", 666), time.FixedZone("LOL", -4242),
   215  	}
   216  	for _, layout := range []string{
   217  		time.RFC3339,
   218  		time.RFC822,
   219  		time.RFC1123Z,
   220  		time.RFC3339Nano, // default
   221  	} {
   222  		for _, loc := range locs {
   223  			b, err := jettison.MarshalOpts(t.In(loc), jettison.TimeLayout(layout))
   224  			if err != nil {
   225  				log.Fatal(err)
   226  			}
   227  			fmt.Printf("%s\n", string(b))
   228  		}
   229  	}
   230  	// Output:
   231  	// "2042-07-25T16:42:24Z"
   232  	// "2042-07-25T16:53:30+00:11"
   233  	// "2042-07-25T15:31:42-01:10"
   234  	// "25 Jul 42 16:42 UTC"
   235  	// "25 Jul 42 16:53 WTF"
   236  	// "25 Jul 42 15:31 LOL"
   237  	// "Fri, 25 Jul 2042 16:42:24 +0000"
   238  	// "Fri, 25 Jul 2042 16:53:30 +0011"
   239  	// "Fri, 25 Jul 2042 15:31:42 -0110"
   240  	// "2042-07-25T16:42:24.00006785Z"
   241  	// "2042-07-25T16:53:30.00006785+00:11"
   242  	// "2042-07-25T15:31:42.00006785-01:10"
   243  }
   244  
   245  func ExampleDurationFormat() {
   246  	d := 1*time.Hour + 3*time.Minute + 2*time.Second + 66*time.Millisecond
   247  
   248  	for _, format := range []jettison.DurationFmt{
   249  		jettison.DurationString,
   250  		jettison.DurationMinutes,
   251  		jettison.DurationSeconds,
   252  		jettison.DurationMilliseconds,
   253  		jettison.DurationMicroseconds,
   254  		jettison.DurationNanoseconds,
   255  	} {
   256  		b, err := jettison.MarshalOpts(d, jettison.DurationFormat(format))
   257  		if err != nil {
   258  			log.Fatal(err)
   259  		}
   260  		fmt.Printf("%s\n", string(b))
   261  	}
   262  	// Output:
   263  	// "1h3m2.066s"
   264  	// 63.03443333333333
   265  	// 3782.066
   266  	// 3782066
   267  	// 3782066000
   268  	// 3782066000000
   269  }
   270  
   271  func ExampleUnsortedMap() {
   272  	m := map[int]string{
   273  		3: "three",
   274  		1: "one",
   275  		2: "two",
   276  	}
   277  	b, err := jettison.MarshalOpts(m, jettison.UnsortedMap())
   278  	if err != nil {
   279  		log.Fatal(err)
   280  	}
   281  	var sorted map[int]string
   282  	if err := json.Unmarshal(b, &sorted); err != nil {
   283  		log.Fatal(err)
   284  	}
   285  	b, err = jettison.Marshal(sorted)
   286  	if err != nil {
   287  		log.Fatal(err)
   288  	}
   289  	os.Stdout.Write(b)
   290  	// Output:
   291  	// {"1":"one","2":"two","3":"three"}
   292  }
   293  
   294  func ExampleNoCompact() {
   295  	rm := json.RawMessage(`{ "a":"b" }`)
   296  	for _, opt := range []jettison.Option{
   297  		nil, jettison.NoCompact(),
   298  	} {
   299  		b, err := jettison.MarshalOpts(rm, opt)
   300  		if err != nil {
   301  			log.Fatal(err)
   302  		}
   303  		fmt.Printf("%s\n", string(b))
   304  	}
   305  	// Output:
   306  	// {"a":"b"}
   307  	// { "a":"b" }
   308  }
   309  
   310  func ExampleAllowList() {
   311  	type Z struct {
   312  		Omega int `json:"ω"`
   313  	}
   314  	type Y struct {
   315  		Pi string `json:"π"`
   316  	}
   317  	type X struct {
   318  		Z     Z      `json:"Z"`
   319  		Alpha string `json:"α"`
   320  		Beta  string `json:"β"`
   321  		Gamma string
   322  		Y
   323  	}
   324  	x := X{
   325  		Z:     Z{Omega: 42},
   326  		Alpha: "1",
   327  		Beta:  "2",
   328  		Gamma: "3",
   329  		Y:     Y{Pi: "4"},
   330  	}
   331  	for _, opt := range []jettison.Option{
   332  		nil, jettison.AllowList([]string{"Z", "β", "Gamma", "π"}),
   333  	} {
   334  		b, err := jettison.MarshalOpts(x, opt)
   335  		if err != nil {
   336  			log.Fatal(err)
   337  		}
   338  		fmt.Printf("%s\n", string(b))
   339  	}
   340  	// Output:
   341  	// {"Z":{"ω":42},"α":"1","β":"2","Gamma":"3","π":"4"}
   342  	// {"Z":{},"β":"2","Gamma":"3","π":"4"}
   343  }
   344  
   345  func ExampleDenyList() {
   346  	type X struct {
   347  		A int  `json:"aaAh"`
   348  		B bool `json:"buzz"`
   349  		C string
   350  		D uint
   351  	}
   352  	x := X{
   353  		A: -42,
   354  		B: true,
   355  		C: "Loreum",
   356  		D: 42,
   357  	}
   358  	for _, opt := range []jettison.Option{
   359  		nil, jettison.DenyList([]string{"buzz", "D"}),
   360  	} {
   361  		b, err := jettison.MarshalOpts(x, opt)
   362  		if err != nil {
   363  			log.Fatal(err)
   364  		}
   365  		fmt.Printf("%s\n", string(b))
   366  	}
   367  	// Output:
   368  	// {"aaAh":-42,"buzz":true,"C":"Loreum","D":42}
   369  	// {"aaAh":-42,"C":"Loreum"}
   370  }
   371  
   372  type (
   373  	secret string
   374  	ctxKey string
   375  )
   376  
   377  const obfuscateKey = ctxKey("_obfuscate_")
   378  
   379  // AppendJSONContext implements the jettison.AppendMarshalerCtx interface.
   380  func (s secret) AppendJSONContext(ctx context.Context, dst []byte) ([]byte, error) {
   381  	out := string(s)
   382  	if v := ctx.Value(obfuscateKey); v != nil {
   383  		if hide, ok := v.(bool); ok && hide {
   384  			out = "**__SECRET__**"
   385  		}
   386  	}
   387  	dst = append(dst, strconv.Quote(out)...)
   388  	return dst, nil
   389  }
   390  
   391  func ExampleWithContext() {
   392  	sec := secret("v3ryS3nSitiv3P4ssWord")
   393  
   394  	b, err := jettison.Marshal(sec)
   395  	if err != nil {
   396  		log.Fatal(err)
   397  	}
   398  	fmt.Printf("%s\n", string(b))
   399  
   400  	ctx := context.WithValue(context.Background(),
   401  		obfuscateKey, true,
   402  	)
   403  	b, err = jettison.MarshalOpts(sec, jettison.WithContext(ctx))
   404  	if err != nil {
   405  		log.Fatal(err)
   406  	}
   407  	fmt.Printf("%s\n", string(b))
   408  	// Output:
   409  	// "v3ryS3nSitiv3P4ssWord"
   410  	// "**__SECRET__**"
   411  }