-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstream_json_array.go
More file actions
121 lines (108 loc) · 2.37 KB
/
stream_json_array.go
File metadata and controls
121 lines (108 loc) · 2.37 KB
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
package jsonstream
import (
"errors"
"fmt"
"io"
)
var (
ErrBadJSONArray = errors.New("bad JSON Array")
)
type (
jsonArraySender struct {
writer io.Writer
encoder JSONEncoder
committed bool
}
jsonArrayReceiver struct {
reader io.Reader
decoder JSONDecoder
committed bool
}
)
var (
_ Sender = (*jsonArraySender)(nil)
_ Receiver = (*jsonArrayReceiver)(nil)
)
func NewJSONArrayEncoder(out io.Writer, cfg *Config) Sender {
return NewJSONArrayEncoderWithConfig(out, DefaultConfig)
}
func NewJSONArrayEncoderWithConfig(out io.Writer, cfg *Config) Sender {
if cfg == nil {
cfg = DefaultConfig
}
return &jsonArraySender{
writer: out,
encoder: cfg.NewEncoder(out),
}
}
func (s *jsonArraySender) Send(data any) error {
if !s.committed {
s.committed = true
_, err := s.writer.Write([]byte("[\n"))
if err != nil {
return err
}
} else if _, err := s.writer.Write([]byte(",")); err != nil {
return err
}
return s.encoder.Encode(data)
}
func (s *jsonArraySender) Done() error {
if !s.committed {
_, err := s.writer.Write([]byte("[]\n"))
return err
}
_, err := s.writer.Write([]byte("]\n"))
if err != nil {
return err
}
s.committed = false
return nil
}
func NewJSONArrayDecoder(in io.Reader) Receiver {
return NewJSONArrayDecoderWithConfig(in, DefaultConfig)
}
func NewJSONArrayDecoderWithConfig(in io.Reader, cfg *Config) Receiver {
if cfg == nil {
cfg = DefaultConfig
}
return &jsonArrayReceiver{
reader: in,
decoder: cfg.NewDecoder(in),
}
}
func (r *jsonArrayReceiver) Receive(data any) error {
if !r.committed {
r.committed = true
token, others, err := r.decoder.RuneToken()
if err != nil {
return err
}
if others != nil {
return fmt.Errorf("%w: expect '[' but got %T(%v)", ErrBadJSONArray, others, others)
}
if token != '[' {
return fmt.Errorf("%w: expect '[' but got %q", ErrBadJSONArray, token)
}
}
if !r.decoder.More() {
token, others, err := r.decoder.RuneToken()
if err != nil {
if err == io.EOF {
return fmt.Errorf("%w: expect ']' but got EOF", ErrBadJSONArray)
}
return err
}
if others != nil {
return fmt.Errorf("%w: expect '[' but got %T(%v)", ErrBadJSONArray, others, others)
}
if token != ']' {
return fmt.Errorf("%w: expect '[' but got %q", ErrBadJSONArray, token)
}
return io.EOF
}
if err := r.decoder.Decode(&data); err != nil {
return err
}
return nil
}