Files
opencloud/vendor/github.com/gookit/goutil/jsonutil/jsonutil.go
dependabot[bot] 5ebc596352 Bump github.com/gookit/config/v2 from 2.1.8 to 2.2.2
Bumps [github.com/gookit/config/v2](https://github.com/gookit/config) from 2.1.8 to 2.2.2.
- [Release notes](https://github.com/gookit/config/releases)
- [Commits](https://github.com/gookit/config/compare/v2.1.8...v2.2.2)

---
updated-dependencies:
- dependency-name: github.com/gookit/config/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-13 10:54:58 +02:00

166 lines
3.6 KiB
Go

// Package jsonutil provide some util functions for quick operate JSON data
package jsonutil
import (
"bytes"
"encoding/json"
"io"
"os"
"regexp"
"strings"
"text/scanner"
)
// WriteFile write data to JSON file
func WriteFile(filePath string, data any) error {
jsonBytes, err := Encode(data)
if err != nil {
return err
}
return os.WriteFile(filePath, jsonBytes, 0664)
}
// WritePretty write pretty data to JSON file
func WritePretty(filePath string, data any) error {
bs, err := json.MarshalIndent(data, "", " ")
if err != nil {
return err
}
return os.WriteFile(filePath, bs, 0664)
}
// ReadFile Read JSON file data
func ReadFile(filePath string, v any) error {
file, err := os.Open(filePath)
if err != nil {
return err
}
defer file.Close()
return json.NewDecoder(file).Decode(v)
}
// Pretty JSON string and return
func Pretty(v any) (string, error) {
out, err := json.MarshalIndent(v, "", " ")
return string(out), err
}
// Encode data to json bytes.
func Encode(v any) ([]byte, error) {
return json.Marshal(v)
}
// EncodePretty encode pretty JSON data to json bytes.
func EncodePretty(v any) ([]byte, error) {
return json.MarshalIndent(v, "", " ")
}
// EncodeToWriter encode data to writer.
func EncodeToWriter(v any, w io.Writer) error {
return json.NewEncoder(w).Encode(v)
}
// EncodeUnescapeHTML data to json bytes. will close escape HTML
func EncodeUnescapeHTML(v any) ([]byte, error) {
buf := &bytes.Buffer{}
enc := json.NewEncoder(buf)
enc.SetEscapeHTML(false)
if err := enc.Encode(v); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
// Decode json bytes to data ptr.
func Decode(bts []byte, ptr any) error {
return json.Unmarshal(bts, ptr)
}
// DecodeString json string to data ptr.
func DecodeString(str string, ptr any) error {
return json.Unmarshal([]byte(str), ptr)
}
// DecodeReader decode JSON from io reader.
func DecodeReader(r io.Reader, ptr any) error {
return json.NewDecoder(r).Decode(ptr)
}
// Mapping src data(map,struct) to dst struct use json tags.
//
// On src, dst both is struct, equivalent to merging two structures (src should be a subset of dsc)
func Mapping(src, dst any) error {
bts, err := Encode(src)
if err != nil {
return err
}
return Decode(bts, dst)
}
// IsJSON check if the string is valid JSON. (Note: uses json.Unmarshal)
func IsJSON(s string) bool {
if s == "" {
return false
}
var js json.RawMessage
return json.Unmarshal([]byte(s), &js) == nil
}
// IsJSONFast simple and fast check input string is valid JSON.
func IsJSONFast(s string) bool {
ln := len(s)
if ln < 2 {
return false
}
if ln == 2 {
return s == "{}" || s == "[]"
}
// object
if s[0] == '{' {
return s[ln-1] == '}' && s[1] == '"'
}
// array
return s[0] == '[' && s[ln-1] == ']'
}
// `(?s:` enable match multi line
var jsonMLComments = regexp.MustCompile(`(?s:/\*.*?\*/\s*)`)
// StripComments strip comments for a JSON string
func StripComments(src string) string {
// multi line comments
if strings.Contains(src, "/*") {
src = jsonMLComments.ReplaceAllString(src, "")
}
// single line comments
if !strings.Contains(src, "//") {
return strings.TrimSpace(src)
}
// strip inline comments
var s scanner.Scanner
s.Init(strings.NewReader(src))
s.Filename = "comments"
s.Mode ^= scanner.SkipComments // don't skip comments
buf := new(bytes.Buffer)
for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() {
txt := s.TokenText()
if !strings.HasPrefix(txt, "//") && !strings.HasPrefix(txt, "/*") {
buf.WriteString(txt)
// } else {
// fmt.Printf("%s: %s\n", s.Position, txt)
}
}
return buf.String()
}