-
Notifications
You must be signed in to change notification settings - Fork 370
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
389 additions
and
151 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
// package json | ||
|
||
// type NodeBuilder struct { | ||
// node *Node | ||
// } | ||
|
||
// func Builder() *NodeBuilder { | ||
// return &NodeBuilder{node: ObjectNode("", nil)} | ||
// } | ||
|
||
// func (b *NodeBuilder) WriteString(key, value string) *NodeBuilder { | ||
// b.node.AppendObject(key, StringNode("", value)) | ||
// return b | ||
// } | ||
|
||
// func (b *NodeBuilder) WriteNumber(key string, value interface{}) *NodeBuilder { | ||
// switch v := value.(type) { | ||
// case int: | ||
// b.node.AppendObject(key, NumberNode("", float64(v))) | ||
// case float64: | ||
// b.node.AppendObject(key, NumberNode("", v)) | ||
// } | ||
// return b | ||
// } | ||
|
||
// func (b *NodeBuilder) WriteBool(key string, value bool) *NodeBuilder { | ||
// b.node.AppendObject(key, BoolNode("", value)) | ||
// return b | ||
// } | ||
|
||
// func (b *NodeBuilder) WriteObject(key string, value *Node) *NodeBuilder { | ||
// b.node.AppendObject(key, value) | ||
// return b | ||
// } | ||
|
||
// func (b *NodeBuilder) WriteArray(key string, value []*Node) *NodeBuilder { | ||
// b.node.AppendObject(key, ArrayNode("", value)) | ||
// return b | ||
// } | ||
|
||
// func (b *NodeBuilder) WriteNull(key string) *NodeBuilder { | ||
// b.node.AppendObject(key, NullNode("")) | ||
// return b | ||
// } | ||
|
||
// func (b *NodeBuilder) Node() *Node { | ||
// return b.node | ||
// } | ||
|
||
package json | ||
|
||
type NodeBuilder struct { | ||
node *Node | ||
} | ||
|
||
func Builder() *NodeBuilder { | ||
return &NodeBuilder{node: ObjectNode("", nil)} | ||
} | ||
|
||
func (b *NodeBuilder) WriteString(key, value string) *NodeBuilder { | ||
b.node.AppendObject(key, StringNode("", value)) | ||
return b | ||
} | ||
|
||
func (b *NodeBuilder) WriteNumber(key string, value float64) *NodeBuilder { | ||
b.node.AppendObject(key, NumberNode("", value)) | ||
return b | ||
} | ||
|
||
func (b *NodeBuilder) WriteInt(key string, value int) *NodeBuilder { | ||
return b.WriteNumber(key, float64(value)) | ||
} | ||
|
||
func (b *NodeBuilder) WriteBool(key string, value bool) *NodeBuilder { | ||
b.node.AppendObject(key, BoolNode("", value)) | ||
return b | ||
} | ||
|
||
func (b *NodeBuilder) WriteNull(key string) *NodeBuilder { | ||
b.node.AppendObject(key, NullNode("")) | ||
return b | ||
} | ||
|
||
func (b *NodeBuilder) WriteObject(key string, fn func(*NodeBuilder)) *NodeBuilder { | ||
nestedBuilder := &NodeBuilder{node: ObjectNode("", nil)} | ||
fn(nestedBuilder) | ||
b.node.AppendObject(key, nestedBuilder.node) | ||
return b | ||
} | ||
|
||
func (b *NodeBuilder) WriteArray(key string, fn func(*ArrayBuilder)) *NodeBuilder { | ||
arrayBuilder := &ArrayBuilder{nodes: []*Node{}} | ||
fn(arrayBuilder) | ||
b.node.AppendObject(key, ArrayNode("", arrayBuilder.nodes)) | ||
return b | ||
} | ||
|
||
func (b *NodeBuilder) Node() *Node { | ||
return b.node | ||
} | ||
|
||
type ArrayBuilder struct { | ||
nodes []*Node | ||
} | ||
|
||
func (ab *ArrayBuilder) WriteString(value string) *ArrayBuilder { | ||
ab.nodes = append(ab.nodes, StringNode("", value)) | ||
return ab | ||
} | ||
|
||
func (ab *ArrayBuilder) WriteNumber(value float64) *ArrayBuilder { | ||
ab.nodes = append(ab.nodes, NumberNode("", value)) | ||
return ab | ||
} | ||
|
||
func (ab *ArrayBuilder) WriteInt(value int) *ArrayBuilder { | ||
return ab.WriteNumber(float64(value)) | ||
} | ||
|
||
func (ab *ArrayBuilder) WriteBool(value bool) *ArrayBuilder { | ||
ab.nodes = append(ab.nodes, BoolNode("", value)) | ||
return ab | ||
} | ||
|
||
func (ab *ArrayBuilder) WriteNull() *ArrayBuilder { | ||
ab.nodes = append(ab.nodes, NullNode("")) | ||
return ab | ||
} | ||
|
||
func (ab *ArrayBuilder) WriteObject(fn func(*NodeBuilder)) *ArrayBuilder { | ||
nestedBuilder := &NodeBuilder{node: ObjectNode("", nil)} | ||
fn(nestedBuilder) | ||
ab.nodes = append(ab.nodes, nestedBuilder.node) | ||
return ab | ||
} | ||
|
||
func (ab *ArrayBuilder) WriteArray(fn func(*ArrayBuilder)) *ArrayBuilder { | ||
nestedArrayBuilder := &ArrayBuilder{nodes: []*Node{}} | ||
fn(nestedArrayBuilder) | ||
ab.nodes = append(ab.nodes, ArrayNode("", nestedArrayBuilder.nodes)) | ||
return ab | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
package json | ||
|
||
import ( | ||
"testing" | ||
) | ||
|
||
func TestNodeBuilder(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
build func() *Node | ||
expected string | ||
}{ | ||
{ | ||
name: "plain object", | ||
build: func() *Node { | ||
return Builder(). | ||
WriteString("name", "Alice"). | ||
WriteNumber("age", 30). | ||
WriteBool("is_student", false). | ||
Node() | ||
}, | ||
expected: `{"name":"Alice","age":30,"is_student":false}`, | ||
}, | ||
{ | ||
name: "nested object", | ||
build: func() *Node { | ||
return Builder(). | ||
WriteString("name", "Alice"). | ||
WriteObject("address", func(b *NodeBuilder) { | ||
b.WriteString("city", "New York"). | ||
WriteNumber("zipcode", 10001) | ||
}). | ||
Node() | ||
}, | ||
expected: `{"name":"Alice","address":{"city":"New York","zipcode":10001}}`, | ||
}, | ||
{ | ||
name: "null node", | ||
build: func() *Node { | ||
return Builder().WriteNull("foo").Node() | ||
}, | ||
expected: `{"foo":null}`, | ||
}, | ||
{ | ||
name: "array node", | ||
build: func() *Node { | ||
return Builder(). | ||
WriteArray("items", func(ab *ArrayBuilder) { | ||
ab.WriteString("item1"). | ||
WriteString("item2"). | ||
WriteString("item3") | ||
}). | ||
Node() | ||
}, | ||
expected: `{"items":["item1","item2","item3"]}`, | ||
}, | ||
{ | ||
name: "array with objects", | ||
build: func() *Node { | ||
return Builder(). | ||
WriteArray("users", func(ab *ArrayBuilder) { | ||
ab.WriteObject(func(b *NodeBuilder) { | ||
b.WriteString("name", "Bob"). | ||
WriteInt("age", 25) | ||
}). | ||
WriteObject(func(b *NodeBuilder) { | ||
b.WriteString("name", "Carol"). | ||
WriteInt("age", 27) | ||
}) | ||
}). | ||
Node() | ||
}, | ||
expected: `{"users":[{"name":"Bob","age":25},{"name":"Carol","age":27}]}`, | ||
}, | ||
{ | ||
name: "array with various types", | ||
build: func() *Node { | ||
return Builder(). | ||
WriteArray("values", func(ab *ArrayBuilder) { | ||
ab.WriteString("item1"). | ||
WriteNumber(123). | ||
WriteBool(true). | ||
WriteNull() | ||
}). | ||
Node() | ||
}, | ||
expected: `{"values":["item1",123,true,null]}`, | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
node := tt.build() | ||
value, err := Marshal(node) | ||
if err != nil { | ||
t.Errorf("unexpected error: %s", err) | ||
} | ||
if string(value) != tt.expected { | ||
t.Errorf("expected %s, got %s", tt.expected, string(value)) | ||
} | ||
}) | ||
} | ||
} |
Oops, something went wrong.