summaryrefslogtreecommitdiffstats
path: root/modules/json/json.go
blob: be42b6ae6c44184e78da311416c7c2bc70056972 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Copyright 2020 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package json

import (
	"bytes"
	"encoding/json"
	"io"

	jsoniter "github.com/json-iterator/go"
)

// Encoder represents an encoder for json
type Encoder interface {
	Encode(v interface{}) error
}

// Decoder represents a decoder for json
type Decoder interface {
	Decode(v interface{}) error
}

// Interface represents an interface to handle json data
type Interface interface {
	Marshal(v interface{}) ([]byte, error)
	Unmarshal(data []byte, v interface{}) error
	NewEncoder(writer io.Writer) Encoder
	NewDecoder(reader io.Reader) Decoder
	Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error
}

var (
	// DefaultJSONHandler default json handler
	DefaultJSONHandler Interface = JSONiter{jsoniter.ConfigCompatibleWithStandardLibrary}

	_ Interface = StdJSON{}
	_ Interface = JSONiter{}
)

// StdJSON implements Interface via encoding/json
type StdJSON struct{}

// Marshal implements Interface
func (StdJSON) Marshal(v interface{}) ([]byte, error) {
	return json.Marshal(v)
}

// Unmarshal implements Interface
func (StdJSON) Unmarshal(data []byte, v interface{}) error {
	return json.Unmarshal(data, v)
}

// NewEncoder implements Interface
func (StdJSON) NewEncoder(writer io.Writer) Encoder {
	return json.NewEncoder(writer)
}

// NewDecoder implements Interface
func (StdJSON) NewDecoder(reader io.Reader) Decoder {
	return json.NewDecoder(reader)
}

// Indent implements Interface
func (StdJSON) Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error {
	return json.Indent(dst, src, prefix, indent)
}

// JSONiter implements Interface via jsoniter
type JSONiter struct {
	jsoniter.API
}

// Marshal implements Interface
func (j JSONiter) Marshal(v interface{}) ([]byte, error) {
	return j.API.Marshal(v)
}

// Unmarshal implements Interface
func (j JSONiter) Unmarshal(data []byte, v interface{}) error {
	return j.API.Unmarshal(data, v)
}

// NewEncoder implements Interface
func (j JSONiter) NewEncoder(writer io.Writer) Encoder {
	return j.API.NewEncoder(writer)
}

// NewDecoder implements Interface
func (j JSONiter) NewDecoder(reader io.Reader) Decoder {
	return j.API.NewDecoder(reader)
}

// Indent implements Interface, since jsoniter don't support Indent, just use encoding/json's
func (j JSONiter) Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error {
	return json.Indent(dst, src, prefix, indent)
}

// Marshal converts object as bytes
func Marshal(v interface{}) ([]byte, error) {
	return DefaultJSONHandler.Marshal(v)
}

// Unmarshal decodes object from bytes
func Unmarshal(data []byte, v interface{}) error {
	return DefaultJSONHandler.Unmarshal(data, v)
}

// NewEncoder creates an encoder to write objects to writer
func NewEncoder(writer io.Writer) Encoder {
	return DefaultJSONHandler.NewEncoder(writer)
}

// NewDecoder creates a decoder to read objects from reader
func NewDecoder(reader io.Reader) Decoder {
	return DefaultJSONHandler.NewDecoder(reader)
}

// Indent appends to dst an indented form of the JSON-encoded src.
func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error {
	return DefaultJSONHandler.Indent(dst, src, prefix, indent)
}

// MarshalIndent copied from encoding/json
func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
	b, err := Marshal(v)
	if err != nil {
		return nil, err
	}
	var buf bytes.Buffer
	err = Indent(&buf, b, prefix, indent)
	if err != nil {
		return nil, err
	}
	return buf.Bytes(), nil
}

// Valid proxy to json.Valid
func Valid(data []byte) bool {
	return json.Valid(data)
}