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 }