github.com/mitranim/gg@v0.1.17/json.go (about) 1 package gg 2 3 import ( 4 "encoding/json" 5 "io" 6 "os" 7 "path/filepath" 8 "strings" 9 ) 10 11 // Uses `json.Marshal` to encode the given value as JSON, panicking on error. 12 func JsonBytes[A any](val A) []byte { 13 return Try1(JsonBytesCatch(val)) 14 } 15 16 /* 17 Uses `json.MarshalIndent` to encode the given value as JSON with indentation 18 controlled by the `Indent` variable, panicking on error. 19 */ 20 func JsonBytesIndent[A any](val A) []byte { 21 return Try1(JsonBytesIndentCatch(val)) 22 } 23 24 /* 25 Same as `json.Marshal` but sometimes marginally more efficient. Avoids spurious 26 heap escape of the input. 27 */ 28 func JsonBytesCatch[A any](val A) ([]byte, error) { 29 return json.Marshal(AnyNoEscUnsafe(val)) 30 } 31 32 /* 33 Same as `json.MarshalIndent`, but uses the default indentation controlled by the 34 `Indent` variable. Also sometimes marginally more efficient. Avoids spurious 35 heap escape of the input. 36 */ 37 func JsonBytesIndentCatch[A any](val A) ([]byte, error) { 38 return json.MarshalIndent(AnyNoEscUnsafe(val), ``, Indent) 39 } 40 41 // Encodes the input as a JSON string, panicking on error. 42 func JsonString[A any](val A) string { return ToString(JsonBytes(val)) } 43 44 /* 45 Encodes the input as a JSON string, using default indentation controlled by the 46 `Indent` variable. 47 */ 48 func JsonStringIndent[A any](val A) string { return ToString(JsonBytesIndent(val)) } 49 50 /* 51 Shortcut for implementing JSON encoding of `Nullable` types. 52 Mostly for internal use. 53 */ 54 func JsonBytesNullCatch[A any, B NullableValGetter[A]](val B) ([]byte, error) { 55 if val.IsNull() { 56 return ToBytes(`null`), nil 57 } 58 return JsonBytesCatch(val.Get()) 59 } 60 61 /* 62 Shortcut for parsing the given string or byte slice into a value of the given 63 type. Panics on errors. 64 */ 65 func JsonParseTo[Out any, Src Text](src Src) (out Out) { 66 JsonParse(src, &out) 67 return 68 } 69 70 /* 71 Shortcut for parsing the given string or byte slice into a pointer of the given 72 type. Panics on errors. 73 */ 74 func JsonParse[Out any, Src Text](src Src, out *Out) { 75 Try(JsonParseCatch(src, out)) 76 } 77 78 /* 79 Parses the given string or byte slice into a pointer of the given type. Similar 80 to `json.Unmarshal`, but avoids the overhead of byte-string conversion and 81 spurious escapes. 82 */ 83 func JsonParseCatch[Out any, Src Text](src Src, out *Out) error { 84 if out != nil { 85 return json.Unmarshal(ToBytes(src), AnyNoEscUnsafe(out)) 86 } 87 return nil 88 } 89 90 /* 91 Shortcut for decoding the content of the given file into a value of the given 92 type. Panics on error. 93 */ 94 func JsonDecodeFileTo[A any](path string) (out A) { 95 JsonDecodeFile(path, &out) 96 return 97 } 98 99 /* 100 Shortcut for decoding the content of the given file into a pointer of the given 101 type. Panics on error. 102 */ 103 func JsonDecodeFile[A any](path string, out *A) { 104 if out != nil { 105 JsonDecodeClose(Try1(os.Open(path)), NoEscUnsafe(out)) 106 } 107 } 108 109 /* 110 Shortcut for writing the JSON encoding of the given value to a file at the given 111 path. Intermediary directories are created automatically. Any existing file is 112 truncated. 113 */ 114 func JsonEncodeFile[A any](path string, src A) { 115 MkdirAll(filepath.Dir(path)) 116 117 file := Try1(os.Create(path)) 118 defer file.Close() 119 120 Try(json.NewEncoder(file).Encode(src)) 121 Try(file.Close()) 122 } 123 124 /* 125 Uses `json.Decoder` to decode one JSON entry/line from the reader, writing to 126 the given output. Always closes the reader. Panics on errors. 127 */ 128 func JsonDecodeClose[A any](src io.ReadCloser, out *A) { 129 defer Close(src) 130 if out != nil { 131 Try(json.NewDecoder(NoEscUnsafe(src)).Decode(AnyNoEscUnsafe(out))) 132 } 133 } 134 135 // True if the input is "null" or blank. Ignores whitespace. 136 func IsJsonEmpty[A Text](val A) bool { 137 src := strings.TrimSpace(ToString(val)) 138 return src == `` || src == `null` 139 }