mirror of
https://github.com/tomnomnom/gron
synced 2024-10-18 08:42:21 +00:00
Adds .UseNumber() to JSON decoding; fixes #6
This commit is contained in:
parent
502a311052
commit
7408c49515
|
@ -1,5 +1,14 @@
|
|||
# Changelog
|
||||
|
||||
## 0.2.4
|
||||
- Fixes handling of large integers (issue #6)
|
||||
|
||||
## 0.2.3
|
||||
- Switches Windows binary packaging to zip instead of tgz
|
||||
|
||||
## 0.2.2
|
||||
- Tweaks release automation, no user-facing changes
|
||||
|
||||
## 0.2.1
|
||||
- Adds windows binary
|
||||
|
||||
|
|
|
@ -177,11 +177,10 @@ Exit Codes:
|
|||
0 OK
|
||||
1 Failed to open file
|
||||
2 Failed to read input
|
||||
3 Failed to decode JSON
|
||||
4 Failed to form statements
|
||||
5 Failed to fetch URL
|
||||
6 Failed to parse statements
|
||||
7 Failed to encode JSON
|
||||
3 Failed to form statements
|
||||
4 Failed to fetch URL
|
||||
5 Failed to parse statements
|
||||
6 Failed to encode JSON
|
||||
|
||||
Examples:
|
||||
gron /tmp/apiresponse.json
|
||||
|
|
19
main.go
19
main.go
|
@ -6,7 +6,6 @@ import (
|
|||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"sort"
|
||||
)
|
||||
|
@ -15,7 +14,6 @@ const (
|
|||
exitOK = iota
|
||||
exitOpenFile
|
||||
exitReadInput
|
||||
exitJSONDecode
|
||||
exitFormStatements
|
||||
exitFetchURL
|
||||
exitParseStatements
|
||||
|
@ -36,7 +34,6 @@ func init() {
|
|||
h += fmt.Sprintf(" %d\t%s\n", exitOK, "OK")
|
||||
h += fmt.Sprintf(" %d\t%s\n", exitOpenFile, "Failed to open file")
|
||||
h += fmt.Sprintf(" %d\t%s\n", exitReadInput, "Failed to read input")
|
||||
h += fmt.Sprintf(" %d\t%s\n", exitJSONDecode, "Failed to decode JSON")
|
||||
h += fmt.Sprintf(" %d\t%s\n", exitFormStatements, "Failed to form statements")
|
||||
h += fmt.Sprintf(" %d\t%s\n", exitFetchURL, "Failed to fetch URL")
|
||||
h += fmt.Sprintf(" %d\t%s\n", exitParseStatements, "Failed to parse statements")
|
||||
|
@ -99,21 +96,7 @@ func main() {
|
|||
|
||||
func gron(r io.Reader, w io.Writer) (int, error) {
|
||||
|
||||
b, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
return exitReadInput, fmt.Errorf("failed to read input: %s", err)
|
||||
}
|
||||
|
||||
// The 'JSON' might be an object, array or scalar, so the
|
||||
// best we can do for now is an empty interface type
|
||||
var top interface{}
|
||||
|
||||
err = json.Unmarshal(b, &top)
|
||||
if err != nil {
|
||||
return exitJSONDecode, fmt.Errorf("failed to decode JSON: %s", err)
|
||||
}
|
||||
|
||||
ss, err := makeStatements("json", top)
|
||||
ss, err := makeStatementsFromJSON(r)
|
||||
if err != nil {
|
||||
return exitFormStatements, fmt.Errorf("failed to form statements: %s", err)
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package main
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
@ -154,6 +155,19 @@ func (ss statements) Contains(search string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// makeStatementsFromJSON takes an io.Reader containing JSON
|
||||
// and returns statements or an error on failure
|
||||
func makeStatementsFromJSON(r io.Reader) (statements, error) {
|
||||
var top interface{}
|
||||
d := json.NewDecoder(r)
|
||||
d.UseNumber()
|
||||
err := d.Decode(&top)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return makeStatements("json", top)
|
||||
}
|
||||
|
||||
// makeStatements takes a prefix and interface value and returns
|
||||
// a statements list or an error on failure
|
||||
func makeStatements(prefix string, v interface{}) (statements, error) {
|
||||
|
@ -193,7 +207,12 @@ func makeStatements(prefix string, v interface{}) (statements, error) {
|
|||
ss.AddMulti(extra)
|
||||
}
|
||||
|
||||
case json.Number:
|
||||
ss.Add(prefix, vv.String())
|
||||
|
||||
case float64:
|
||||
// This case *should* be handled by json.Number
|
||||
// but is left just in case
|
||||
ss.Add(prefix, formatValue(vv))
|
||||
|
||||
case string:
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"sort"
|
||||
|
@ -19,16 +20,11 @@ func TestStatementsSimple(t *testing.T) {
|
|||
"anob": {
|
||||
"foo": "bar"
|
||||
},
|
||||
"else": 1
|
||||
"else": 1,
|
||||
"id": 66912849
|
||||
}`)
|
||||
|
||||
var top interface{}
|
||||
err := json.Unmarshal(j, &top)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to unmarshal test file: %s", err)
|
||||
}
|
||||
|
||||
ss, err := makeStatements("json", top)
|
||||
ss, err := makeStatementsFromJSON(bytes.NewReader(j))
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Want nil error from makeStatements() but got %s", err)
|
||||
|
@ -47,8 +43,10 @@ func TestStatementsSimple(t *testing.T) {
|
|||
`json.anob = {};`,
|
||||
`json.anob.foo = "bar";`,
|
||||
`json["else"] = 1;`,
|
||||
`json.id = 66912849;`,
|
||||
}
|
||||
|
||||
t.Logf("Have: %#v", ss)
|
||||
for _, want := range wants {
|
||||
if !ss.Contains(want) {
|
||||
t.Errorf("Statement group should contain `%s` but doesn't", want)
|
||||
|
|
3
testdata/one.json
vendored
3
testdata/one.json
vendored
|
@ -11,5 +11,6 @@
|
|||
},
|
||||
"abool": true,
|
||||
"abool2": false,
|
||||
"isnull": null
|
||||
"isnull": null,
|
||||
"id": 66912849
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue