github.com/goshafaq/sonic@v0.0.0-20231026082336-871835fb94c6/api.go (about) 1 /* 2 * Copyright 2021 ByteDance Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package sonic 18 19 import ( 20 "io" 21 22 "github.com/goshafaq/sonic/ast" 23 ) 24 25 // Config is a combination of sonic/encoder.Options and sonic/decoder.Options 26 type Config struct { 27 // EscapeHTML indicates encoder to escape all HTML characters 28 // after serializing into JSON (see https://pkg.go.dev/encoding/json#HTMLEscape). 29 // WARNING: This hurts performance A LOT, USE WITH CARE. 30 EscapeHTML bool 31 32 // SortMapKeys indicates encoder that the keys of a map needs to be sorted 33 // before serializing into JSON. 34 // WARNING: This hurts performance A LOT, USE WITH CARE. 35 SortMapKeys bool 36 37 // CompactMarshaler indicates encoder that the output JSON from json.Marshaler 38 // is always compact and needs no validation 39 CompactMarshaler bool 40 41 // NoQuoteTextMarshaler indicates encoder that the output text from encoding.TextMarshaler 42 // is always escaped string and needs no quoting 43 NoQuoteTextMarshaler bool 44 45 // NoNullSliceOrMap indicates encoder that all empty Array or Object are encoded as '[]' or '{}', 46 // instead of 'null' 47 NoNullSliceOrMap bool 48 49 // UseInt64 indicates decoder to unmarshal an integer into an interface{} as an 50 // int64 instead of as a float64. 51 UseInt64 bool 52 53 // UseNumber indicates decoder to unmarshal a number into an interface{} as a 54 // json.Number instead of as a float64. 55 UseNumber bool 56 57 // UseUnicodeErrors indicates decoder to return an error when encounter invalid 58 // UTF-8 escape sequences. 59 UseUnicodeErrors bool 60 61 // DisallowUnknownFields indicates decoder to return an error when the destination 62 // is a struct and the input contains object keys which do not match any 63 // non-ignored, exported fields in the destination. 64 DisallowUnknownFields bool 65 66 // CopyString indicates decoder to decode string values by copying instead of referring. 67 CopyString bool 68 69 // ValidateString indicates decoder and encoder to valid string values: decoder will return errors 70 // when unescaped control chars(\u0000-\u001f) in the string value of JSON. 71 ValidateString bool 72 73 // NoValidateJSONMarshaler indicates that the encoder should not validate the output string 74 // after encoding the JSONMarshaler to JSON. 75 NoValidateJSONMarshaler bool 76 } 77 78 var ( 79 // ConfigDefault is the default config of APIs, aiming at efficiency and safty. 80 ConfigDefault = Config{}.Froze() 81 82 // ConfigStd is the standard config of APIs, aiming at being compatible with encoding/json. 83 ConfigStd = Config{ 84 EscapeHTML: true, 85 SortMapKeys: true, 86 CompactMarshaler: true, 87 CopyString: true, 88 ValidateString: true, 89 }.Froze() 90 91 // ConfigFastest is the fastest config of APIs, aiming at speed. 92 ConfigFastest = Config{ 93 NoQuoteTextMarshaler: true, 94 NoValidateJSONMarshaler: true, 95 }.Froze() 96 ) 97 98 // API is a binding of specific config. 99 // This interface is inspired by github.com/json-iterator/go, 100 // and has same behaviors under equavilent config. 101 type API interface { 102 // MarshalToString returns the JSON encoding string of v 103 MarshalToString(v interface{}) (string, error) 104 // Marshal returns the JSON encoding bytes of v. 105 Marshal(v interface{}) ([]byte, error) 106 // MarshalIndent returns the JSON encoding bytes with indent and prefix. 107 MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) 108 // UnmarshalFromString parses the JSON-encoded bytes and stores the result in the value pointed to by v. 109 UnmarshalFromString(str string, v interface{}) error 110 // Unmarshal parses the JSON-encoded string and stores the result in the value pointed to by v. 111 Unmarshal(data []byte, v interface{}) error 112 // NewEncoder create a Encoder holding writer 113 NewEncoder(writer io.Writer) Encoder 114 // NewDecoder create a Decoder holding reader 115 NewDecoder(reader io.Reader) Decoder 116 // Valid validates the JSON-encoded bytes and reportes if it is valid 117 Valid(data []byte) bool 118 } 119 120 // Encoder encodes JSON into io.Writer 121 type Encoder interface { 122 // Encode writes the JSON encoding of v to the stream, followed by a newline character. 123 Encode(val interface{}) error 124 // SetEscapeHTML specifies whether problematic HTML characters 125 // should be escaped inside JSON quoted strings. 126 // The default behavior NOT ESCAPE 127 SetEscapeHTML(on bool) 128 // SetIndent instructs the encoder to format each subsequent encoded value 129 // as if indented by the package-level function Indent(dst, src, prefix, indent). 130 // Calling SetIndent("", "") disables indentation 131 SetIndent(prefix, indent string) 132 } 133 134 // Decoder decodes JSON from io.Read 135 type Decoder interface { 136 // Decode reads the next JSON-encoded value from its input and stores it in the value pointed to by v. 137 Decode(val interface{}) error 138 // Buffered returns a reader of the data remaining in the Decoder's buffer. 139 // The reader is valid until the next call to Decode. 140 Buffered() io.Reader 141 // DisallowUnknownFields causes the Decoder to return an error when the destination is a struct 142 // and the input contains object keys which do not match any non-ignored, exported fields in the destination. 143 DisallowUnknownFields() 144 // More reports whether there is another element in the current array or object being parsed. 145 More() bool 146 // UseNumber causes the Decoder to unmarshal a number into an interface{} as a Number instead of as a float64. 147 UseNumber() 148 } 149 150 // Marshal returns the JSON encoding bytes of v. 151 func Marshal(val interface{}) ([]byte, error) { 152 return ConfigDefault.Marshal(val) 153 } 154 155 // MarshalString returns the JSON encoding string of v. 156 func MarshalString(val interface{}) (string, error) { 157 return ConfigDefault.MarshalToString(val) 158 } 159 160 // Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v. 161 // NOTICE: This API copies given buffer by default, 162 // if you want to pass JSON more efficiently, use UnmarshalString instead. 163 func Unmarshal(buf []byte, val interface{}) error { 164 return ConfigDefault.Unmarshal(buf, val) 165 } 166 167 // UnmarshalString is like Unmarshal, except buf is a string. 168 func UnmarshalString(buf string, val interface{}) error { 169 return ConfigDefault.UnmarshalFromString(buf, val) 170 } 171 172 // Get searches the given path from json, 173 // and returns its representing ast.Node. 174 // 175 // Each path arg must be integer or string: 176 // - Integer is target index(>=0), means searching current node as array. 177 // - String is target key, means searching current node as object. 178 // 179 // Note, the api expects the json is well-formed at least, 180 // otherwise it may return unexpected result. 181 func Get(src []byte, path ...interface{}) (ast.Node, error) { 182 return GetFromString(string(src), path...) 183 } 184 185 // GetFromString is same with Get except src is string, 186 // which can reduce unnecessary memory copy. 187 func GetFromString(src string, path ...interface{}) (ast.Node, error) { 188 return ast.NewSearcher(src).GetByPath(path...) 189 } 190 191 // Valid reports whether data is a valid JSON encoding. 192 func Valid(data []byte) bool { 193 return ConfigDefault.Valid(data) 194 }