-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjsonquote.go
116 lines (108 loc) · 2.38 KB
/
jsonquote.go
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
package main
import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io"
"os"
"strconv"
"strings"
)
func expandJSONQuotes(_ context.Context, pqs []*pullQuote) ([]*expanded, error) {
exp := make([]*expanded, 0, len(pqs))
for _, pq := range pqs {
parts := strings.SplitN(pq.objPath, "#", 2)
pat, sym := parts[0], parts[1]
s, err := func() (string, error) {
f, err := os.Open(pat)
if err != nil {
return "", err
}
return parse(f, sym, pq.flags&noRealignTabs != 0)
}()
if err != nil {
return nil, err
}
exp = append(exp, &expanded{String: s})
}
return exp, nil
}
func parse(r io.Reader, jsonPath string, noRealign bool) (string, error) {
parts := strings.Split(jsonPath, "/")
if len(parts) != 0 && parts[0] == "" {
parts = parts[1:]
}
for dec := json.NewDecoder(r); ; {
if len(parts) == 0 {
var val json.RawMessage
if err := dec.Decode(&val); err != nil {
return "", fmt.Errorf("dec.Decode: %w", err)
}
if noRealign {
return string(val), nil
}
var buf bytes.Buffer
if err := json.Indent(&buf, val, "", " "); err != nil {
return "", err
}
return buf.String(), nil
}
tok, err := dec.Token()
if err != nil {
return "", fmt.Errorf("dec.Token: %w", err)
}
switch tok {
case json.Delim('{'):
err := func() error {
for dec.More() {
var (
key json.Token
keyS string
ok bool
)
if key, err = dec.Token(); err != nil {
return fmt.Errorf("parse key: %w", err)
}
if keyS, ok = key.(string); !ok {
return fmt.Errorf("expected string, got %v", key)
}
if parts[0] == keyS {
parts = parts[1:]
return nil
}
// discard value
var j json.RawMessage
if err = dec.Decode(&j); err != nil {
return fmt.Errorf("parse value: %w", err)
}
}
return errors.New("no such value")
}()
if err != nil {
return "", fmt.Errorf("couldn't parse obj: %w", err)
}
case json.Delim('['):
idx, err := strconv.Atoi(parts[0])
if err != nil {
return "", err
}
err = func() error {
for i := 0; i <= idx && dec.More(); i++ {
if i == idx {
parts = parts[1:]
return nil
}
// discard value
var j json.RawMessage
_ = dec.Decode(&j)
}
return errors.New("no such value")
}()
if err != nil {
return "", fmt.Errorf("couldn't parse array: %w", err)
}
}
}
}