Skip to content

Commit 82169e2

Browse files
committed
adding a preliminary walker interface
1 parent be57243 commit 82169e2

File tree

3 files changed

+77
-26
lines changed

3 files changed

+77
-26
lines changed

README.md

+25-12
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,26 @@ type Address struct {
1818
StreetName string
1919
City string
2020
State string
21+
GateCode int
2122
}
2223

2324
val := jsonast.Parse(`{
2425
"street_num":1,
2526
"street_name": "Microsoft Way",
2627
"city": "Redmond",
27-
"state": "WA"
28+
"state": "WA",
29+
"other_info": {
30+
"needs_signature": false,
31+
"gate_codes": ["abcd", "efgh"]
32+
}
2833
}`)
2934

3035
walked := val.
3136
Walk().
3237
Field("street_num").
33-
And().Field("street_name")
34-
And().Field("city").
35-
And().Field("state").Validate(func(v Value) bool {
38+
.Field("street_name")
39+
.Field("city").
40+
.Field("state").Validate(func(v Value) bool {
3641
str, ok := v.(jsonast.String)
3742
if !ok {
3843
return false
@@ -43,20 +48,28 @@ walked := val.
4348
str.String() == "WA" ||
4449
str.String() == "OR" ||
4550
str.String() == "CA"
46-
})
51+
}).
52+
Path(
53+
jsonast.NewStringPathElt("other_info"),
54+
jsonast.NewStringPathElt("gate_codes"),
55+
jsonast.NewIntPathElt(0),
56+
)
4757

4858
if transformer.Err() != nil {
4959
log.Fatal(transformer.Err())
5060
}
5161

52-
// transformer now has 3 jsonast.String fields in its Strings property
53-
// and 1 jsonast.Number field in its Numbers property.
62+
// walked now has the following fields in the following properties:
5463
//
55-
// you can now validate on these fields
64+
// - .Strings has 3 jsonast.String values (street_name, city, state)
65+
// - .Numbers has 2 jsonast.Number values (street_num, other_info.gate_codes[0])
66+
//
67+
// you can now create an Address from these fields
5668
address := Address{
57-
StreetNum: transformer.Numbers[0],
58-
StreetName: transformer.Strings[0],
59-
City: transformer.Strings[1],
60-
State: transformer.Strings[2],
69+
StreetNum: walked.Numbers[0],
70+
StreetName: walked.Strings[0],
71+
City: walked.Strings[1],
72+
State: walked.Strings[2],
73+
GateCode: walked.Numbers[1],
6174
}
6275
```

path.go

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package jsonast
2+
3+
import (
4+
"fmt"
5+
)
6+
7+
// PathElt is a container for a single element of a json path
8+
type PathElt interface {
9+
fmt.Stringer
10+
}
11+
12+
type stringPathElt struct {
13+
str string
14+
}
15+
16+
func (s stringPathElt) String() string {
17+
return fmt.Sprintf("StringPathElt(%s)", s.str)
18+
}
19+
20+
type intPathElt struct {
21+
i int
22+
}
23+
24+
func (i intPathElt) String() string {
25+
return fmt.Sprintf("IntPathElt(%d)", i)
26+
}
27+
28+
// NewStringPathElt creates a new PathElt from s
29+
func NewStringPathElt(s string) PathElt {
30+
return stringPathElt{str: s}
31+
}
32+
33+
// NewIntPathElt creates a new PathElt from i
34+
func NewIntPathElt(i int) PathElt {
35+
return intPathElt{i: i}
36+
}

walker.go

+16-14
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,13 @@ import (
77
// Walker is a utility for walking the JSON tree with a few function calls,
88
// and transforming the JSON that was walked into a type
99
type Walker struct {
10-
path string
11-
values []Value
12-
err error
10+
latestValue Value
11+
Nulls []Null
12+
Strings []String
13+
Numbers []Number
14+
Objects []Object
15+
Arrays []Array
16+
err error
1317
}
1418

1519
// Elt picks out the ith element of the current array
@@ -25,30 +29,28 @@ func (w Walker) Elt(i int) Walker {
2529
return w
2630
}
2731

28-
// Field picks out the key s in the current dictionary
29-
func (w Walker) Field(s string) Walker {
32+
// Path picks out the value pointed to by all the given path elements
33+
// and puts it into the next value
34+
func (w Walker) Path(pathElt PathElt, pathElts ...PathElt) Walker {
3035
if w.err != nil {
3136
return w
3237
}
3338
// TODO
34-
return w
39+
return nil
3540
}
36-
func (w Walker) And() Walker {
41+
42+
// Field picks out the key s in the current dictionary
43+
func (w Walker) Field(s string) Walker {
3744
if w.err != nil {
3845
return w
3946
}
40-
// TODO
41-
return w
47+
return w.Path(NewStringPathElt(s))
4248
}
4349

50+
// Validate validates the latest fetched value in w
4451
func (w Walker) Validate(fn func(Value) bool) Walker {
4552
if w.err != nil {
4653
return w
4754
}
4855
fn(values)
4956
}
50-
51-
func (w Walker) curValue() Value {
52-
// TODO: handle the case when there are no values
53-
return w.values[len(w.values)-1]
54-
}

0 commit comments

Comments
 (0)