├── .editorconfig
├── .travis.yml
├── Godeps
├── Godeps.json
├── Readme
└── _workspace
│ ├── .gitignore
│ └── src
│ └── github.com
│ └── stretchr
│ └── objx
│ ├── .gitignore
│ ├── LICENSE.md
│ ├── README.md
│ ├── accessors.go
│ ├── accessors_test.go
│ ├── codegen
│ ├── array-access.txt
│ ├── index.html
│ ├── template.txt
│ └── types_list.txt
│ ├── constants.go
│ ├── conversions.go
│ ├── conversions_test.go
│ ├── doc.go
│ ├── fixture_test.go
│ ├── map.go
│ ├── map_for_test.go
│ ├── map_test.go
│ ├── mutations.go
│ ├── mutations_test.go
│ ├── security.go
│ ├── security_test.go
│ ├── simple_example_test.go
│ ├── tests.go
│ ├── tests_test.go
│ ├── type_specific_codegen.go
│ ├── type_specific_codegen_test.go
│ ├── value.go
│ └── value_test.go
├── LICENSE
├── README.md
├── chat
├── color.go
├── component.go
└── event.go
├── protocol
├── connection.go
├── connection_test.go
├── dealer.go
├── dealer_test.go
├── packet
│ ├── holder.go
│ ├── packet.go
│ ├── packets_handshake.go
│ └── packets_status.go
├── packets.go
├── state.go
└── types
│ ├── json.go
│ ├── long.go
│ ├── string.go
│ ├── type.go
│ ├── ushort.go
│ ├── uvarint.go
│ └── varint.go
├── server.go
└── util
├── encoding.go
├── reader.go
└── reader_test.go
/.editorconfig:
--------------------------------------------------------------------------------
1 | # editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | end_of_line = lf
7 | insert_final_newline = true
8 | max_line_length = 80
9 | trim_trailing_whitespace = true
10 |
11 | [*.go]
12 | indent_size = 8
13 | indent_style = tab
14 |
15 | [*.md]
16 | indent_size = 2
17 | indent_style = space
18 |
19 | [COMMIT_EDITMSG]
20 | max_line_length = 0
21 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: go
2 | go:
3 | - 1.5
4 |
--------------------------------------------------------------------------------
/Godeps/Godeps.json:
--------------------------------------------------------------------------------
1 | {
2 | "ImportPath": "github.com/ttaylorr/minecraft",
3 | "GoVersion": "go1.5.1",
4 | "Packages": [
5 | "github.com/stretchr/testify"
6 | ],
7 | "Deps": [
8 | {
9 | "ImportPath": "github.com/stretchr/objx",
10 | "Rev": "1a9d0bb9f541897e62256577b352fdbc1fb4fd94"
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/Godeps/Readme:
--------------------------------------------------------------------------------
1 | This directory tree is generated automatically by godep.
2 |
3 | Please do not edit.
4 |
5 | See https://github.com/tools/godep for more information.
6 |
--------------------------------------------------------------------------------
/Godeps/_workspace/.gitignore:
--------------------------------------------------------------------------------
1 | /pkg
2 | /bin
3 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/objx/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled Object files, Static and Dynamic libs (Shared Objects)
2 | *.o
3 | *.a
4 | *.so
5 |
6 | # Folders
7 | _obj
8 | _test
9 |
10 | # Architecture specific extensions/prefixes
11 | *.[568vq]
12 | [568vq].out
13 |
14 | *.cgo1.go
15 | *.cgo2.c
16 | _cgo_defun.c
17 | _cgo_gotypes.go
18 | _cgo_export.*
19 |
20 | _testmain.go
21 |
22 | *.exe
23 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/objx/LICENSE.md:
--------------------------------------------------------------------------------
1 | objx - by Mat Ryer and Tyler Bunnell
2 |
3 | The MIT License (MIT)
4 |
5 | Copyright (c) 2014 Stretchr, Inc.
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining a copy
8 | of this software and associated documentation files (the "Software"), to deal
9 | in the Software without restriction, including without limitation the rights
10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | copies of the Software, and to permit persons to whom the Software is
12 | furnished to do so, subject to the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included in all
15 | copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | SOFTWARE.
24 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/objx/README.md:
--------------------------------------------------------------------------------
1 | # objx
2 |
3 | * Jump into the [API Documentation](http://godoc.org/github.com/stretchr/objx)
4 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/objx/accessors.go:
--------------------------------------------------------------------------------
1 | package objx
2 |
3 | import (
4 | "fmt"
5 | "regexp"
6 | "strconv"
7 | "strings"
8 | )
9 |
10 | // arrayAccesRegexString is the regex used to extract the array number
11 | // from the access path
12 | const arrayAccesRegexString = `^(.+)\[([0-9]+)\]$`
13 |
14 | // arrayAccesRegex is the compiled arrayAccesRegexString
15 | var arrayAccesRegex = regexp.MustCompile(arrayAccesRegexString)
16 |
17 | // Get gets the value using the specified selector and
18 | // returns it inside a new Obj object.
19 | //
20 | // If it cannot find the value, Get will return a nil
21 | // value inside an instance of Obj.
22 | //
23 | // Get can only operate directly on map[string]interface{} and []interface.
24 | //
25 | // Example
26 | //
27 | // To access the title of the third chapter of the second book, do:
28 | //
29 | // o.Get("books[1].chapters[2].title")
30 | func (m Map) Get(selector string) *Value {
31 | rawObj := access(m, selector, nil, false, false)
32 | return &Value{data: rawObj}
33 | }
34 |
35 | // Set sets the value using the specified selector and
36 | // returns the object on which Set was called.
37 | //
38 | // Set can only operate directly on map[string]interface{} and []interface
39 | //
40 | // Example
41 | //
42 | // To set the title of the third chapter of the second book, do:
43 | //
44 | // o.Set("books[1].chapters[2].title","Time to Go")
45 | func (m Map) Set(selector string, value interface{}) Map {
46 | access(m, selector, value, true, false)
47 | return m
48 | }
49 |
50 | // access accesses the object using the selector and performs the
51 | // appropriate action.
52 | func access(current, selector, value interface{}, isSet, panics bool) interface{} {
53 |
54 | switch selector.(type) {
55 | case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
56 |
57 | if array, ok := current.([]interface{}); ok {
58 | index := intFromInterface(selector)
59 |
60 | if index >= len(array) {
61 | if panics {
62 | panic(fmt.Sprintf("objx: Index %d is out of range. Slice only contains %d items.", index, len(array)))
63 | }
64 | return nil
65 | }
66 |
67 | return array[index]
68 | }
69 |
70 | return nil
71 |
72 | case string:
73 |
74 | selStr := selector.(string)
75 | selSegs := strings.SplitN(selStr, PathSeparator, 2)
76 | thisSel := selSegs[0]
77 | index := -1
78 | var err error
79 |
80 | // https://github.com/stretchr/objx/issues/12
81 | if strings.Contains(thisSel, "[") {
82 |
83 | arrayMatches := arrayAccesRegex.FindStringSubmatch(thisSel)
84 |
85 | if len(arrayMatches) > 0 {
86 |
87 | // Get the key into the map
88 | thisSel = arrayMatches[1]
89 |
90 | // Get the index into the array at the key
91 | index, err = strconv.Atoi(arrayMatches[2])
92 |
93 | if err != nil {
94 | // This should never happen. If it does, something has gone
95 | // seriously wrong. Panic.
96 | panic("objx: Array index is not an integer. Must use array[int].")
97 | }
98 |
99 | }
100 | }
101 |
102 | if curMap, ok := current.(Map); ok {
103 | current = map[string]interface{}(curMap)
104 | }
105 |
106 | // get the object in question
107 | switch current.(type) {
108 | case map[string]interface{}:
109 | curMSI := current.(map[string]interface{})
110 | if len(selSegs) <= 1 && isSet {
111 | curMSI[thisSel] = value
112 | return nil
113 | } else {
114 | current = curMSI[thisSel]
115 | }
116 | default:
117 | current = nil
118 | }
119 |
120 | if current == nil && panics {
121 | panic(fmt.Sprintf("objx: '%v' invalid on object.", selector))
122 | }
123 |
124 | // do we need to access the item of an array?
125 | if index > -1 {
126 | if array, ok := current.([]interface{}); ok {
127 | if index < len(array) {
128 | current = array[index]
129 | } else {
130 | if panics {
131 | panic(fmt.Sprintf("objx: Index %d is out of range. Slice only contains %d items.", index, len(array)))
132 | }
133 | current = nil
134 | }
135 | }
136 | }
137 |
138 | if len(selSegs) > 1 {
139 | current = access(current, selSegs[1], value, isSet, panics)
140 | }
141 |
142 | }
143 |
144 | return current
145 |
146 | }
147 |
148 | // intFromInterface converts an interface object to the largest
149 | // representation of an unsigned integer using a type switch and
150 | // assertions
151 | func intFromInterface(selector interface{}) int {
152 | var value int
153 | switch selector.(type) {
154 | case int:
155 | value = selector.(int)
156 | case int8:
157 | value = int(selector.(int8))
158 | case int16:
159 | value = int(selector.(int16))
160 | case int32:
161 | value = int(selector.(int32))
162 | case int64:
163 | value = int(selector.(int64))
164 | case uint:
165 | value = int(selector.(uint))
166 | case uint8:
167 | value = int(selector.(uint8))
168 | case uint16:
169 | value = int(selector.(uint16))
170 | case uint32:
171 | value = int(selector.(uint32))
172 | case uint64:
173 | value = int(selector.(uint64))
174 | default:
175 | panic("objx: array access argument is not an integer type (this should never happen)")
176 | }
177 |
178 | return value
179 | }
180 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/objx/accessors_test.go:
--------------------------------------------------------------------------------
1 | package objx
2 |
3 | import (
4 | "github.com/stretchr/testify/assert"
5 | "testing"
6 | )
7 |
8 | func TestAccessorsAccessGetSingleField(t *testing.T) {
9 |
10 | current := map[string]interface{}{"name": "Tyler"}
11 | assert.Equal(t, "Tyler", access(current, "name", nil, false, true))
12 |
13 | }
14 | func TestAccessorsAccessGetDeep(t *testing.T) {
15 |
16 | current := map[string]interface{}{"name": map[string]interface{}{"first": "Tyler", "last": "Bunnell"}}
17 | assert.Equal(t, "Tyler", access(current, "name.first", nil, false, true))
18 | assert.Equal(t, "Bunnell", access(current, "name.last", nil, false, true))
19 |
20 | }
21 | func TestAccessorsAccessGetDeepDeep(t *testing.T) {
22 |
23 | current := map[string]interface{}{"one": map[string]interface{}{"two": map[string]interface{}{"three": map[string]interface{}{"four": 4}}}}
24 | assert.Equal(t, 4, access(current, "one.two.three.four", nil, false, true))
25 |
26 | }
27 | func TestAccessorsAccessGetInsideArray(t *testing.T) {
28 |
29 | current := map[string]interface{}{"names": []interface{}{map[string]interface{}{"first": "Tyler", "last": "Bunnell"}, map[string]interface{}{"first": "Capitol", "last": "Bollocks"}}}
30 | assert.Equal(t, "Tyler", access(current, "names[0].first", nil, false, true))
31 | assert.Equal(t, "Bunnell", access(current, "names[0].last", nil, false, true))
32 | assert.Equal(t, "Capitol", access(current, "names[1].first", nil, false, true))
33 | assert.Equal(t, "Bollocks", access(current, "names[1].last", nil, false, true))
34 |
35 | assert.Panics(t, func() {
36 | access(current, "names[2]", nil, false, true)
37 | })
38 | assert.Nil(t, access(current, "names[2]", nil, false, false))
39 |
40 | }
41 |
42 | func TestAccessorsAccessGetFromArrayWithInt(t *testing.T) {
43 |
44 | current := []interface{}{map[string]interface{}{"first": "Tyler", "last": "Bunnell"}, map[string]interface{}{"first": "Capitol", "last": "Bollocks"}}
45 | one := access(current, 0, nil, false, false)
46 | two := access(current, 1, nil, false, false)
47 | three := access(current, 2, nil, false, false)
48 |
49 | assert.Equal(t, "Tyler", one.(map[string]interface{})["first"])
50 | assert.Equal(t, "Capitol", two.(map[string]interface{})["first"])
51 | assert.Nil(t, three)
52 |
53 | }
54 |
55 | func TestAccessorsGet(t *testing.T) {
56 |
57 | current := New(map[string]interface{}{"name": "Tyler"})
58 | assert.Equal(t, "Tyler", current.Get("name").data)
59 |
60 | }
61 |
62 | func TestAccessorsAccessSetSingleField(t *testing.T) {
63 |
64 | current := map[string]interface{}{"name": "Tyler"}
65 | access(current, "name", "Mat", true, false)
66 | assert.Equal(t, current["name"], "Mat")
67 |
68 | access(current, "age", 29, true, true)
69 | assert.Equal(t, current["age"], 29)
70 |
71 | }
72 |
73 | func TestAccessorsAccessSetSingleFieldNotExisting(t *testing.T) {
74 |
75 | current := map[string]interface{}{}
76 | access(current, "name", "Mat", true, false)
77 | assert.Equal(t, current["name"], "Mat")
78 |
79 | }
80 |
81 | func TestAccessorsAccessSetDeep(t *testing.T) {
82 |
83 | current := map[string]interface{}{"name": map[string]interface{}{"first": "Tyler", "last": "Bunnell"}}
84 |
85 | access(current, "name.first", "Mat", true, true)
86 | access(current, "name.last", "Ryer", true, true)
87 |
88 | assert.Equal(t, "Mat", access(current, "name.first", nil, false, true))
89 | assert.Equal(t, "Ryer", access(current, "name.last", nil, false, true))
90 |
91 | }
92 | func TestAccessorsAccessSetDeepDeep(t *testing.T) {
93 |
94 | current := map[string]interface{}{"one": map[string]interface{}{"two": map[string]interface{}{"three": map[string]interface{}{"four": 4}}}}
95 |
96 | access(current, "one.two.three.four", 5, true, true)
97 |
98 | assert.Equal(t, 5, access(current, "one.two.three.four", nil, false, true))
99 |
100 | }
101 | func TestAccessorsAccessSetArray(t *testing.T) {
102 |
103 | current := map[string]interface{}{"names": []interface{}{"Tyler"}}
104 |
105 | access(current, "names[0]", "Mat", true, true)
106 |
107 | assert.Equal(t, "Mat", access(current, "names[0]", nil, false, true))
108 |
109 | }
110 | func TestAccessorsAccessSetInsideArray(t *testing.T) {
111 |
112 | current := map[string]interface{}{"names": []interface{}{map[string]interface{}{"first": "Tyler", "last": "Bunnell"}, map[string]interface{}{"first": "Capitol", "last": "Bollocks"}}}
113 |
114 | access(current, "names[0].first", "Mat", true, true)
115 | access(current, "names[0].last", "Ryer", true, true)
116 | access(current, "names[1].first", "Captain", true, true)
117 | access(current, "names[1].last", "Underpants", true, true)
118 |
119 | assert.Equal(t, "Mat", access(current, "names[0].first", nil, false, true))
120 | assert.Equal(t, "Ryer", access(current, "names[0].last", nil, false, true))
121 | assert.Equal(t, "Captain", access(current, "names[1].first", nil, false, true))
122 | assert.Equal(t, "Underpants", access(current, "names[1].last", nil, false, true))
123 |
124 | }
125 |
126 | func TestAccessorsAccessSetFromArrayWithInt(t *testing.T) {
127 |
128 | current := []interface{}{map[string]interface{}{"first": "Tyler", "last": "Bunnell"}, map[string]interface{}{"first": "Capitol", "last": "Bollocks"}}
129 | one := access(current, 0, nil, false, false)
130 | two := access(current, 1, nil, false, false)
131 | three := access(current, 2, nil, false, false)
132 |
133 | assert.Equal(t, "Tyler", one.(map[string]interface{})["first"])
134 | assert.Equal(t, "Capitol", two.(map[string]interface{})["first"])
135 | assert.Nil(t, three)
136 |
137 | }
138 |
139 | func TestAccessorsSet(t *testing.T) {
140 |
141 | current := New(map[string]interface{}{"name": "Tyler"})
142 | current.Set("name", "Mat")
143 | assert.Equal(t, "Mat", current.Get("name").data)
144 |
145 | }
146 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/objx/codegen/array-access.txt:
--------------------------------------------------------------------------------
1 | case []{1}:
2 | a := object.([]{1})
3 | if isSet {
4 | a[index] = value.({1})
5 | } else {
6 | if index >= len(a) {
7 | if panics {
8 | panic(fmt.Sprintf("objx: Index %d is out of range because the []{1} only contains %d items.", index, len(a)))
9 | }
10 | return nil
11 | } else {
12 | return a[index]
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/objx/codegen/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Codegen
5 |
6 |
17 |
18 |
19 |
20 |
21 | Template
22 |
23 |
24 | Use {x}
as a placeholder for each argument.
25 |
26 |
27 |
28 |
29 | Arguments (comma separated)
30 |
31 |
32 | One block per line
33 |
34 |
35 |
36 |
37 | Output
38 |
39 |
40 |
41 |
42 |
43 |
44 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/objx/codegen/template.txt:
--------------------------------------------------------------------------------
1 | /*
2 | {4} ({1} and []{1})
3 | --------------------------------------------------
4 | */
5 |
6 | // {4} gets the value as a {1}, returns the optionalDefault
7 | // value or a system default object if the value is the wrong type.
8 | func (v *Value) {4}(optionalDefault ...{1}) {1} {
9 | if s, ok := v.data.({1}); ok {
10 | return s
11 | }
12 | if len(optionalDefault) == 1 {
13 | return optionalDefault[0]
14 | }
15 | return {3}
16 | }
17 |
18 | // Must{4} gets the value as a {1}.
19 | //
20 | // Panics if the object is not a {1}.
21 | func (v *Value) Must{4}() {1} {
22 | return v.data.({1})
23 | }
24 |
25 | // {4}Slice gets the value as a []{1}, returns the optionalDefault
26 | // value or nil if the value is not a []{1}.
27 | func (v *Value) {4}Slice(optionalDefault ...[]{1}) []{1} {
28 | if s, ok := v.data.([]{1}); ok {
29 | return s
30 | }
31 | if len(optionalDefault) == 1 {
32 | return optionalDefault[0]
33 | }
34 | return nil
35 | }
36 |
37 | // Must{4}Slice gets the value as a []{1}.
38 | //
39 | // Panics if the object is not a []{1}.
40 | func (v *Value) Must{4}Slice() []{1} {
41 | return v.data.([]{1})
42 | }
43 |
44 | // Is{4} gets whether the object contained is a {1} or not.
45 | func (v *Value) Is{4}() bool {
46 | _, ok := v.data.({1})
47 | return ok
48 | }
49 |
50 | // Is{4}Slice gets whether the object contained is a []{1} or not.
51 | func (v *Value) Is{4}Slice() bool {
52 | _, ok := v.data.([]{1})
53 | return ok
54 | }
55 |
56 | // Each{4} calls the specified callback for each object
57 | // in the []{1}.
58 | //
59 | // Panics if the object is the wrong type.
60 | func (v *Value) Each{4}(callback func(int, {1}) bool) *Value {
61 |
62 | for index, val := range v.Must{4}Slice() {
63 | carryon := callback(index, val)
64 | if carryon == false {
65 | break
66 | }
67 | }
68 |
69 | return v
70 |
71 | }
72 |
73 | // Where{4} uses the specified decider function to select items
74 | // from the []{1}. The object contained in the result will contain
75 | // only the selected items.
76 | func (v *Value) Where{4}(decider func(int, {1}) bool) *Value {
77 |
78 | var selected []{1}
79 |
80 | v.Each{4}(func(index int, val {1}) bool {
81 | shouldSelect := decider(index, val)
82 | if shouldSelect == false {
83 | selected = append(selected, val)
84 | }
85 | return true
86 | })
87 |
88 | return &Value{data:selected}
89 |
90 | }
91 |
92 | // Group{4} uses the specified grouper function to group the items
93 | // keyed by the return of the grouper. The object contained in the
94 | // result will contain a map[string][]{1}.
95 | func (v *Value) Group{4}(grouper func(int, {1}) string) *Value {
96 |
97 | groups := make(map[string][]{1})
98 |
99 | v.Each{4}(func(index int, val {1}) bool {
100 | group := grouper(index, val)
101 | if _, ok := groups[group]; !ok {
102 | groups[group] = make([]{1}, 0)
103 | }
104 | groups[group] = append(groups[group], val)
105 | return true
106 | })
107 |
108 | return &Value{data:groups}
109 |
110 | }
111 |
112 | // Replace{4} uses the specified function to replace each {1}s
113 | // by iterating each item. The data in the returned result will be a
114 | // []{1} containing the replaced items.
115 | func (v *Value) Replace{4}(replacer func(int, {1}) {1}) *Value {
116 |
117 | arr := v.Must{4}Slice()
118 | replaced := make([]{1}, len(arr))
119 |
120 | v.Each{4}(func(index int, val {1}) bool {
121 | replaced[index] = replacer(index, val)
122 | return true
123 | })
124 |
125 | return &Value{data:replaced}
126 |
127 | }
128 |
129 | // Collect{4} uses the specified collector function to collect a value
130 | // for each of the {1}s in the slice. The data returned will be a
131 | // []interface{}.
132 | func (v *Value) Collect{4}(collector func(int, {1}) interface{}) *Value {
133 |
134 | arr := v.Must{4}Slice()
135 | collected := make([]interface{}, len(arr))
136 |
137 | v.Each{4}(func(index int, val {1}) bool {
138 | collected[index] = collector(index, val)
139 | return true
140 | })
141 |
142 | return &Value{data:collected}
143 | }
144 |
145 | // ************************************************************
146 | // TESTS
147 | // ************************************************************
148 |
149 | func Test{4}(t *testing.T) {
150 |
151 | val := {1}( {2} )
152 | m := map[string]interface{}{"value": val, "nothing": nil}
153 | assert.Equal(t, val, New(m).Get("value").{4}())
154 | assert.Equal(t, val, New(m).Get("value").Must{4}())
155 | assert.Equal(t, {1}({3}), New(m).Get("nothing").{4}())
156 | assert.Equal(t, val, New(m).Get("nothing").{4}({2}))
157 |
158 | assert.Panics(t, func() {
159 | New(m).Get("age").Must{4}()
160 | })
161 |
162 | }
163 |
164 | func Test{4}Slice(t *testing.T) {
165 |
166 | val := {1}( {2} )
167 | m := map[string]interface{}{"value": []{1}{ val }, "nothing": nil}
168 | assert.Equal(t, val, New(m).Get("value").{4}Slice()[0])
169 | assert.Equal(t, val, New(m).Get("value").Must{4}Slice()[0])
170 | assert.Equal(t, []{1}(nil), New(m).Get("nothing").{4}Slice())
171 | assert.Equal(t, val, New(m).Get("nothing").{4}Slice( []{1}{ {1}({2}) } )[0])
172 |
173 | assert.Panics(t, func() {
174 | New(m).Get("nothing").Must{4}Slice()
175 | })
176 |
177 | }
178 |
179 | func TestIs{4}(t *testing.T) {
180 |
181 | var v *Value
182 |
183 | v = &Value{data: {1}({2})}
184 | assert.True(t, v.Is{4}())
185 |
186 | v = &Value{data: []{1}{ {1}({2}) }}
187 | assert.True(t, v.Is{4}Slice())
188 |
189 | }
190 |
191 | func TestEach{4}(t *testing.T) {
192 |
193 | v := &Value{data: []{1}{ {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}) }}
194 | count := 0
195 | replacedVals := make([]{1}, 0)
196 | assert.Equal(t, v, v.Each{4}(func(i int, val {1}) bool {
197 |
198 | count++
199 | replacedVals = append(replacedVals, val)
200 |
201 | // abort early
202 | if i == 2 {
203 | return false
204 | }
205 |
206 | return true
207 |
208 | }))
209 |
210 | assert.Equal(t, count, 3)
211 | assert.Equal(t, replacedVals[0], v.Must{4}Slice()[0])
212 | assert.Equal(t, replacedVals[1], v.Must{4}Slice()[1])
213 | assert.Equal(t, replacedVals[2], v.Must{4}Slice()[2])
214 |
215 | }
216 |
217 | func TestWhere{4}(t *testing.T) {
218 |
219 | v := &Value{data: []{1}{ {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}) }}
220 |
221 | selected := v.Where{4}(func(i int, val {1}) bool {
222 | return i%2==0
223 | }).Must{4}Slice()
224 |
225 | assert.Equal(t, 3, len(selected))
226 |
227 | }
228 |
229 | func TestGroup{4}(t *testing.T) {
230 |
231 | v := &Value{data: []{1}{ {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}) }}
232 |
233 | grouped := v.Group{4}(func(i int, val {1}) string {
234 | return fmt.Sprintf("%v", i%2==0)
235 | }).data.(map[string][]{1})
236 |
237 | assert.Equal(t, 2, len(grouped))
238 | assert.Equal(t, 3, len(grouped["true"]))
239 | assert.Equal(t, 3, len(grouped["false"]))
240 |
241 | }
242 |
243 | func TestReplace{4}(t *testing.T) {
244 |
245 | v := &Value{data: []{1}{ {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}) }}
246 |
247 | rawArr := v.Must{4}Slice()
248 |
249 | replaced := v.Replace{4}(func(index int, val {1}) {1} {
250 | if index < len(rawArr)-1 {
251 | return rawArr[index+1]
252 | }
253 | return rawArr[0]
254 | })
255 |
256 | replacedArr := replaced.Must{4}Slice()
257 | if assert.Equal(t, 6, len(replacedArr)) {
258 | assert.Equal(t, replacedArr[0], rawArr[1])
259 | assert.Equal(t, replacedArr[1], rawArr[2])
260 | assert.Equal(t, replacedArr[2], rawArr[3])
261 | assert.Equal(t, replacedArr[3], rawArr[4])
262 | assert.Equal(t, replacedArr[4], rawArr[5])
263 | assert.Equal(t, replacedArr[5], rawArr[0])
264 | }
265 |
266 | }
267 |
268 | func TestCollect{4}(t *testing.T) {
269 |
270 | v := &Value{data: []{1}{ {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}), {1}({2}) }}
271 |
272 | collected := v.Collect{4}(func(index int, val {1}) interface{} {
273 | return index
274 | })
275 |
276 | collectedArr := collected.MustInterSlice()
277 | if assert.Equal(t, 6, len(collectedArr)) {
278 | assert.Equal(t, collectedArr[0], 0)
279 | assert.Equal(t, collectedArr[1], 1)
280 | assert.Equal(t, collectedArr[2], 2)
281 | assert.Equal(t, collectedArr[3], 3)
282 | assert.Equal(t, collectedArr[4], 4)
283 | assert.Equal(t, collectedArr[5], 5)
284 | }
285 |
286 | }
287 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/objx/codegen/types_list.txt:
--------------------------------------------------------------------------------
1 | Interface,interface{},"something",nil,Inter
2 | Map,map[string]interface{},map[string]interface{}{"name":"Tyler"},nil,MSI
3 | ObjxMap,(Map),New(1),New(nil),ObjxMap
4 | Bool,bool,true,false,Bool
5 | String,string,"hello","",Str
6 | Int,int,1,0,Int
7 | Int8,int8,1,0,Int8
8 | Int16,int16,1,0,Int16
9 | Int32,int32,1,0,Int32
10 | Int64,int64,1,0,Int64
11 | Uint,uint,1,0,Uint
12 | Uint8,uint8,1,0,Uint8
13 | Uint16,uint16,1,0,Uint16
14 | Uint32,uint32,1,0,Uint32
15 | Uint64,uint64,1,0,Uint64
16 | Uintptr,uintptr,1,0,Uintptr
17 | Float32,float32,1,0,Float32
18 | Float64,float64,1,0,Float64
19 | Complex64,complex64,1,0,Complex64
20 | Complex128,complex128,1,0,Complex128
21 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/objx/constants.go:
--------------------------------------------------------------------------------
1 | package objx
2 |
3 | const (
4 | // PathSeparator is the character used to separate the elements
5 | // of the keypath.
6 | //
7 | // For example, `location.address.city`
8 | PathSeparator string = "."
9 |
10 | // SignatureSeparator is the character that is used to
11 | // separate the Base64 string from the security signature.
12 | SignatureSeparator = "_"
13 | )
14 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/objx/conversions.go:
--------------------------------------------------------------------------------
1 | package objx
2 |
3 | import (
4 | "bytes"
5 | "encoding/base64"
6 | "encoding/json"
7 | "errors"
8 | "fmt"
9 | "net/url"
10 | )
11 |
12 | // JSON converts the contained object to a JSON string
13 | // representation
14 | func (m Map) JSON() (string, error) {
15 |
16 | result, err := json.Marshal(m)
17 |
18 | if err != nil {
19 | err = errors.New("objx: JSON encode failed with: " + err.Error())
20 | }
21 |
22 | return string(result), err
23 |
24 | }
25 |
26 | // MustJSON converts the contained object to a JSON string
27 | // representation and panics if there is an error
28 | func (m Map) MustJSON() string {
29 | result, err := m.JSON()
30 | if err != nil {
31 | panic(err.Error())
32 | }
33 | return result
34 | }
35 |
36 | // Base64 converts the contained object to a Base64 string
37 | // representation of the JSON string representation
38 | func (m Map) Base64() (string, error) {
39 |
40 | var buf bytes.Buffer
41 |
42 | jsonData, err := m.JSON()
43 | if err != nil {
44 | return "", err
45 | }
46 |
47 | encoder := base64.NewEncoder(base64.StdEncoding, &buf)
48 | encoder.Write([]byte(jsonData))
49 | encoder.Close()
50 |
51 | return buf.String(), nil
52 |
53 | }
54 |
55 | // MustBase64 converts the contained object to a Base64 string
56 | // representation of the JSON string representation and panics
57 | // if there is an error
58 | func (m Map) MustBase64() string {
59 | result, err := m.Base64()
60 | if err != nil {
61 | panic(err.Error())
62 | }
63 | return result
64 | }
65 |
66 | // SignedBase64 converts the contained object to a Base64 string
67 | // representation of the JSON string representation and signs it
68 | // using the provided key.
69 | func (m Map) SignedBase64(key string) (string, error) {
70 |
71 | base64, err := m.Base64()
72 | if err != nil {
73 | return "", err
74 | }
75 |
76 | sig := HashWithKey(base64, key)
77 |
78 | return base64 + SignatureSeparator + sig, nil
79 |
80 | }
81 |
82 | // MustSignedBase64 converts the contained object to a Base64 string
83 | // representation of the JSON string representation and signs it
84 | // using the provided key and panics if there is an error
85 | func (m Map) MustSignedBase64(key string) string {
86 | result, err := m.SignedBase64(key)
87 | if err != nil {
88 | panic(err.Error())
89 | }
90 | return result
91 | }
92 |
93 | /*
94 | URL Query
95 | ------------------------------------------------
96 | */
97 |
98 | // URLValues creates a url.Values object from an Obj. This
99 | // function requires that the wrapped object be a map[string]interface{}
100 | func (m Map) URLValues() url.Values {
101 |
102 | vals := make(url.Values)
103 |
104 | for k, v := range m {
105 | //TODO: can this be done without sprintf?
106 | vals.Set(k, fmt.Sprintf("%v", v))
107 | }
108 |
109 | return vals
110 | }
111 |
112 | // URLQuery gets an encoded URL query representing the given
113 | // Obj. This function requires that the wrapped object be a
114 | // map[string]interface{}
115 | func (m Map) URLQuery() (string, error) {
116 | return m.URLValues().Encode(), nil
117 | }
118 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/objx/conversions_test.go:
--------------------------------------------------------------------------------
1 | package objx
2 |
3 | import (
4 | "github.com/stretchr/testify/assert"
5 | "testing"
6 | )
7 |
8 | func TestConversionJSON(t *testing.T) {
9 |
10 | jsonString := `{"name":"Mat"}`
11 | o := MustFromJSON(jsonString)
12 |
13 | result, err := o.JSON()
14 |
15 | if assert.NoError(t, err) {
16 | assert.Equal(t, jsonString, result)
17 | }
18 |
19 | assert.Equal(t, jsonString, o.MustJSON())
20 |
21 | }
22 |
23 | func TestConversionJSONWithError(t *testing.T) {
24 |
25 | o := MSI()
26 | o["test"] = func() {}
27 |
28 | assert.Panics(t, func() {
29 | o.MustJSON()
30 | })
31 |
32 | _, err := o.JSON()
33 |
34 | assert.Error(t, err)
35 |
36 | }
37 |
38 | func TestConversionBase64(t *testing.T) {
39 |
40 | o := New(map[string]interface{}{"name": "Mat"})
41 |
42 | result, err := o.Base64()
43 |
44 | if assert.NoError(t, err) {
45 | assert.Equal(t, "eyJuYW1lIjoiTWF0In0=", result)
46 | }
47 |
48 | assert.Equal(t, "eyJuYW1lIjoiTWF0In0=", o.MustBase64())
49 |
50 | }
51 |
52 | func TestConversionBase64WithError(t *testing.T) {
53 |
54 | o := MSI()
55 | o["test"] = func() {}
56 |
57 | assert.Panics(t, func() {
58 | o.MustBase64()
59 | })
60 |
61 | _, err := o.Base64()
62 |
63 | assert.Error(t, err)
64 |
65 | }
66 |
67 | func TestConversionSignedBase64(t *testing.T) {
68 |
69 | o := New(map[string]interface{}{"name": "Mat"})
70 |
71 | result, err := o.SignedBase64("key")
72 |
73 | if assert.NoError(t, err) {
74 | assert.Equal(t, "eyJuYW1lIjoiTWF0In0=_67ee82916f90b2c0d68c903266e8998c9ef0c3d6", result)
75 | }
76 |
77 | assert.Equal(t, "eyJuYW1lIjoiTWF0In0=_67ee82916f90b2c0d68c903266e8998c9ef0c3d6", o.MustSignedBase64("key"))
78 |
79 | }
80 |
81 | func TestConversionSignedBase64WithError(t *testing.T) {
82 |
83 | o := MSI()
84 | o["test"] = func() {}
85 |
86 | assert.Panics(t, func() {
87 | o.MustSignedBase64("key")
88 | })
89 |
90 | _, err := o.SignedBase64("key")
91 |
92 | assert.Error(t, err)
93 |
94 | }
95 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/objx/doc.go:
--------------------------------------------------------------------------------
1 | // objx - Go package for dealing with maps, slices, JSON and other data.
2 | //
3 | // Overview
4 | //
5 | // Objx provides the `objx.Map` type, which is a `map[string]interface{}` that exposes
6 | // a powerful `Get` method (among others) that allows you to easily and quickly get
7 | // access to data within the map, without having to worry too much about type assertions,
8 | // missing data, default values etc.
9 | //
10 | // Pattern
11 | //
12 | // Objx uses a preditable pattern to make access data from within `map[string]interface{}'s
13 | // easy.
14 | //
15 | // Call one of the `objx.` functions to create your `objx.Map` to get going:
16 | //
17 | // m, err := objx.FromJSON(json)
18 | //
19 | // NOTE: Any methods or functions with the `Must` prefix will panic if something goes wrong,
20 | // the rest will be optimistic and try to figure things out without panicking.
21 | //
22 | // Use `Get` to access the value you're interested in. You can use dot and array
23 | // notation too:
24 | //
25 | // m.Get("places[0].latlng")
26 | //
27 | // Once you have saught the `Value` you're interested in, you can use the `Is*` methods
28 | // to determine its type.
29 | //
30 | // if m.Get("code").IsStr() { /* ... */ }
31 | //
32 | // Or you can just assume the type, and use one of the strong type methods to
33 | // extract the real value:
34 | //
35 | // m.Get("code").Int()
36 | //
37 | // If there's no value there (or if it's the wrong type) then a default value
38 | // will be returned, or you can be explicit about the default value.
39 | //
40 | // Get("code").Int(-1)
41 | //
42 | // If you're dealing with a slice of data as a value, Objx provides many useful
43 | // methods for iterating, manipulating and selecting that data. You can find out more
44 | // by exploring the index below.
45 | //
46 | // Reading data
47 | //
48 | // A simple example of how to use Objx:
49 | //
50 | // // use MustFromJSON to make an objx.Map from some JSON
51 | // m := objx.MustFromJSON(`{"name": "Mat", "age": 30}`)
52 | //
53 | // // get the details
54 | // name := m.Get("name").Str()
55 | // age := m.Get("age").Int()
56 | //
57 | // // get their nickname (or use their name if they
58 | // // don't have one)
59 | // nickname := m.Get("nickname").Str(name)
60 | //
61 | // Ranging
62 | //
63 | // Since `objx.Map` is a `map[string]interface{}` you can treat it as such. For
64 | // example, to `range` the data, do what you would expect:
65 | //
66 | // m := objx.MustFromJSON(json)
67 | // for key, value := range m {
68 | //
69 | // /* ... do your magic ... */
70 | //
71 | // }
72 | package objx
73 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/objx/fixture_test.go:
--------------------------------------------------------------------------------
1 | package objx
2 |
3 | import (
4 | "github.com/stretchr/testify/assert"
5 | "testing"
6 | )
7 |
8 | var fixtures = []struct {
9 | // name is the name of the fixture (used for reporting
10 | // failures)
11 | name string
12 | // data is the JSON data to be worked on
13 | data string
14 | // get is the argument(s) to pass to Get
15 | get interface{}
16 | // output is the expected output
17 | output interface{}
18 | }{
19 | {
20 | name: "Simple get",
21 | data: `{"name": "Mat"}`,
22 | get: "name",
23 | output: "Mat",
24 | },
25 | {
26 | name: "Get with dot notation",
27 | data: `{"address": {"city": "Boulder"}}`,
28 | get: "address.city",
29 | output: "Boulder",
30 | },
31 | {
32 | name: "Deep get with dot notation",
33 | data: `{"one": {"two": {"three": {"four": "hello"}}}}`,
34 | get: "one.two.three.four",
35 | output: "hello",
36 | },
37 | {
38 | name: "Get missing with dot notation",
39 | data: `{"one": {"two": {"three": {"four": "hello"}}}}`,
40 | get: "one.ten",
41 | output: nil,
42 | },
43 | {
44 | name: "Get with array notation",
45 | data: `{"tags": ["one", "two", "three"]}`,
46 | get: "tags[1]",
47 | output: "two",
48 | },
49 | {
50 | name: "Get with array and dot notation",
51 | data: `{"types": { "tags": ["one", "two", "three"]}}`,
52 | get: "types.tags[1]",
53 | output: "two",
54 | },
55 | {
56 | name: "Get with array and dot notation - field after array",
57 | data: `{"tags": [{"name":"one"}, {"name":"two"}, {"name":"three"}]}`,
58 | get: "tags[1].name",
59 | output: "two",
60 | },
61 | {
62 | name: "Complex get with array and dot notation",
63 | data: `{"tags": [{"list": [{"one":"pizza"}]}]}`,
64 | get: "tags[0].list[0].one",
65 | output: "pizza",
66 | },
67 | {
68 | name: "Get field from within string should be nil",
69 | data: `{"name":"Tyler"}`,
70 | get: "name.something",
71 | output: nil,
72 | },
73 | {
74 | name: "Get field from within string (using array accessor) should be nil",
75 | data: `{"numbers":["one", "two", "three"]}`,
76 | get: "numbers[0].nope",
77 | output: nil,
78 | },
79 | }
80 |
81 | func TestFixtures(t *testing.T) {
82 |
83 | for _, fixture := range fixtures {
84 |
85 | m := MustFromJSON(fixture.data)
86 |
87 | // get the value
88 | t.Logf("Running get fixture: \"%s\" (%v)", fixture.name, fixture)
89 | value := m.Get(fixture.get.(string))
90 |
91 | // make sure it matches
92 | assert.Equal(t, fixture.output, value.data,
93 | "Get fixture \"%s\" failed: %v", fixture.name, fixture,
94 | )
95 |
96 | }
97 |
98 | }
99 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/objx/map.go:
--------------------------------------------------------------------------------
1 | package objx
2 |
3 | import (
4 | "encoding/base64"
5 | "encoding/json"
6 | "errors"
7 | "io/ioutil"
8 | "net/url"
9 | "strings"
10 | )
11 |
12 | // MSIConvertable is an interface that defines methods for converting your
13 | // custom types to a map[string]interface{} representation.
14 | type MSIConvertable interface {
15 | // MSI gets a map[string]interface{} (msi) representing the
16 | // object.
17 | MSI() map[string]interface{}
18 | }
19 |
20 | // Map provides extended functionality for working with
21 | // untyped data, in particular map[string]interface (msi).
22 | type Map map[string]interface{}
23 |
24 | // Value returns the internal value instance
25 | func (m Map) Value() *Value {
26 | return &Value{data: m}
27 | }
28 |
29 | // Nil represents a nil Map.
30 | var Nil Map = New(nil)
31 |
32 | // New creates a new Map containing the map[string]interface{} in the data argument.
33 | // If the data argument is not a map[string]interface, New attempts to call the
34 | // MSI() method on the MSIConvertable interface to create one.
35 | func New(data interface{}) Map {
36 | if _, ok := data.(map[string]interface{}); !ok {
37 | if converter, ok := data.(MSIConvertable); ok {
38 | data = converter.MSI()
39 | } else {
40 | return nil
41 | }
42 | }
43 | return Map(data.(map[string]interface{}))
44 | }
45 |
46 | // MSI creates a map[string]interface{} and puts it inside a new Map.
47 | //
48 | // The arguments follow a key, value pattern.
49 | //
50 | // Panics
51 | //
52 | // Panics if any key arugment is non-string or if there are an odd number of arguments.
53 | //
54 | // Example
55 | //
56 | // To easily create Maps:
57 | //
58 | // m := objx.MSI("name", "Mat", "age", 29, "subobj", objx.MSI("active", true))
59 | //
60 | // // creates an Map equivalent to
61 | // m := objx.New(map[string]interface{}{"name": "Mat", "age": 29, "subobj": map[string]interface{}{"active": true}})
62 | func MSI(keyAndValuePairs ...interface{}) Map {
63 |
64 | newMap := make(map[string]interface{})
65 | keyAndValuePairsLen := len(keyAndValuePairs)
66 |
67 | if keyAndValuePairsLen%2 != 0 {
68 | panic("objx: MSI must have an even number of arguments following the 'key, value' pattern.")
69 | }
70 |
71 | for i := 0; i < keyAndValuePairsLen; i = i + 2 {
72 |
73 | key := keyAndValuePairs[i]
74 | value := keyAndValuePairs[i+1]
75 |
76 | // make sure the key is a string
77 | keyString, keyStringOK := key.(string)
78 | if !keyStringOK {
79 | panic("objx: MSI must follow 'string, interface{}' pattern. " + keyString + " is not a valid key.")
80 | }
81 |
82 | newMap[keyString] = value
83 |
84 | }
85 |
86 | return New(newMap)
87 | }
88 |
89 | // ****** Conversion Constructors
90 |
91 | // MustFromJSON creates a new Map containing the data specified in the
92 | // jsonString.
93 | //
94 | // Panics if the JSON is invalid.
95 | func MustFromJSON(jsonString string) Map {
96 | o, err := FromJSON(jsonString)
97 |
98 | if err != nil {
99 | panic("objx: MustFromJSON failed with error: " + err.Error())
100 | }
101 |
102 | return o
103 | }
104 |
105 | // FromJSON creates a new Map containing the data specified in the
106 | // jsonString.
107 | //
108 | // Returns an error if the JSON is invalid.
109 | func FromJSON(jsonString string) (Map, error) {
110 |
111 | var data interface{}
112 | err := json.Unmarshal([]byte(jsonString), &data)
113 |
114 | if err != nil {
115 | return Nil, err
116 | }
117 |
118 | return New(data), nil
119 |
120 | }
121 |
122 | // FromBase64 creates a new Obj containing the data specified
123 | // in the Base64 string.
124 | //
125 | // The string is an encoded JSON string returned by Base64
126 | func FromBase64(base64String string) (Map, error) {
127 |
128 | decoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(base64String))
129 |
130 | decoded, err := ioutil.ReadAll(decoder)
131 | if err != nil {
132 | return nil, err
133 | }
134 |
135 | return FromJSON(string(decoded))
136 | }
137 |
138 | // MustFromBase64 creates a new Obj containing the data specified
139 | // in the Base64 string and panics if there is an error.
140 | //
141 | // The string is an encoded JSON string returned by Base64
142 | func MustFromBase64(base64String string) Map {
143 |
144 | result, err := FromBase64(base64String)
145 |
146 | if err != nil {
147 | panic("objx: MustFromBase64 failed with error: " + err.Error())
148 | }
149 |
150 | return result
151 | }
152 |
153 | // FromSignedBase64 creates a new Obj containing the data specified
154 | // in the Base64 string.
155 | //
156 | // The string is an encoded JSON string returned by SignedBase64
157 | func FromSignedBase64(base64String, key string) (Map, error) {
158 | parts := strings.Split(base64String, SignatureSeparator)
159 | if len(parts) != 2 {
160 | return nil, errors.New("objx: Signed base64 string is malformed.")
161 | }
162 |
163 | sig := HashWithKey(parts[0], key)
164 | if parts[1] != sig {
165 | return nil, errors.New("objx: Signature for base64 data does not match.")
166 | }
167 |
168 | return FromBase64(parts[0])
169 | }
170 |
171 | // MustFromSignedBase64 creates a new Obj containing the data specified
172 | // in the Base64 string and panics if there is an error.
173 | //
174 | // The string is an encoded JSON string returned by Base64
175 | func MustFromSignedBase64(base64String, key string) Map {
176 |
177 | result, err := FromSignedBase64(base64String, key)
178 |
179 | if err != nil {
180 | panic("objx: MustFromSignedBase64 failed with error: " + err.Error())
181 | }
182 |
183 | return result
184 | }
185 |
186 | // FromURLQuery generates a new Obj by parsing the specified
187 | // query.
188 | //
189 | // For queries with multiple values, the first value is selected.
190 | func FromURLQuery(query string) (Map, error) {
191 |
192 | vals, err := url.ParseQuery(query)
193 |
194 | if err != nil {
195 | return nil, err
196 | }
197 |
198 | m := make(map[string]interface{})
199 | for k, vals := range vals {
200 | m[k] = vals[0]
201 | }
202 |
203 | return New(m), nil
204 | }
205 |
206 | // MustFromURLQuery generates a new Obj by parsing the specified
207 | // query.
208 | //
209 | // For queries with multiple values, the first value is selected.
210 | //
211 | // Panics if it encounters an error
212 | func MustFromURLQuery(query string) Map {
213 |
214 | o, err := FromURLQuery(query)
215 |
216 | if err != nil {
217 | panic("objx: MustFromURLQuery failed with error: " + err.Error())
218 | }
219 |
220 | return o
221 |
222 | }
223 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/objx/map_for_test.go:
--------------------------------------------------------------------------------
1 | package objx
2 |
3 | var TestMap map[string]interface{} = map[string]interface{}{
4 | "name": "Tyler",
5 | "address": map[string]interface{}{
6 | "city": "Salt Lake City",
7 | "state": "UT",
8 | },
9 | "numbers": []interface{}{"one", "two", "three", "four", "five"},
10 | }
11 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/objx/map_test.go:
--------------------------------------------------------------------------------
1 | package objx
2 |
3 | import (
4 | "github.com/stretchr/testify/assert"
5 | "testing"
6 | )
7 |
8 | type Convertable struct {
9 | name string
10 | }
11 |
12 | func (c *Convertable) MSI() map[string]interface{} {
13 | return map[string]interface{}{"name": c.name}
14 | }
15 |
16 | type Unconvertable struct {
17 | name string
18 | }
19 |
20 | func TestMapCreation(t *testing.T) {
21 |
22 | o := New(nil)
23 | assert.Nil(t, o)
24 |
25 | o = New("Tyler")
26 | assert.Nil(t, o)
27 |
28 | unconvertable := &Unconvertable{name: "Tyler"}
29 | o = New(unconvertable)
30 | assert.Nil(t, o)
31 |
32 | convertable := &Convertable{name: "Tyler"}
33 | o = New(convertable)
34 | if assert.NotNil(t, convertable) {
35 | assert.Equal(t, "Tyler", o["name"], "Tyler")
36 | }
37 |
38 | o = MSI()
39 | if assert.NotNil(t, o) {
40 | assert.NotNil(t, o)
41 | }
42 |
43 | o = MSI("name", "Tyler")
44 | if assert.NotNil(t, o) {
45 | if assert.NotNil(t, o) {
46 | assert.Equal(t, o["name"], "Tyler")
47 | }
48 | }
49 |
50 | }
51 |
52 | func TestMapMustFromJSONWithError(t *testing.T) {
53 |
54 | _, err := FromJSON(`"name":"Mat"}`)
55 | assert.Error(t, err)
56 |
57 | }
58 |
59 | func TestMapFromJSON(t *testing.T) {
60 |
61 | o := MustFromJSON(`{"name":"Mat"}`)
62 |
63 | if assert.NotNil(t, o) {
64 | if assert.NotNil(t, o) {
65 | assert.Equal(t, "Mat", o["name"])
66 | }
67 | }
68 |
69 | }
70 |
71 | func TestMapFromJSONWithError(t *testing.T) {
72 |
73 | var m Map
74 |
75 | assert.Panics(t, func() {
76 | m = MustFromJSON(`"name":"Mat"}`)
77 | })
78 |
79 | assert.Nil(t, m)
80 |
81 | }
82 |
83 | func TestMapFromBase64String(t *testing.T) {
84 |
85 | base64String := "eyJuYW1lIjoiTWF0In0="
86 |
87 | o, err := FromBase64(base64String)
88 |
89 | if assert.NoError(t, err) {
90 | assert.Equal(t, o.Get("name").Str(), "Mat")
91 | }
92 |
93 | assert.Equal(t, MustFromBase64(base64String).Get("name").Str(), "Mat")
94 |
95 | }
96 |
97 | func TestMapFromBase64StringWithError(t *testing.T) {
98 |
99 | base64String := "eyJuYW1lIjoiTWFasd0In0="
100 |
101 | _, err := FromBase64(base64String)
102 |
103 | assert.Error(t, err)
104 |
105 | assert.Panics(t, func() {
106 | MustFromBase64(base64String)
107 | })
108 |
109 | }
110 |
111 | func TestMapFromSignedBase64String(t *testing.T) {
112 |
113 | base64String := "eyJuYW1lIjoiTWF0In0=_67ee82916f90b2c0d68c903266e8998c9ef0c3d6"
114 |
115 | o, err := FromSignedBase64(base64String, "key")
116 |
117 | if assert.NoError(t, err) {
118 | assert.Equal(t, o.Get("name").Str(), "Mat")
119 | }
120 |
121 | assert.Equal(t, MustFromSignedBase64(base64String, "key").Get("name").Str(), "Mat")
122 |
123 | }
124 |
125 | func TestMapFromSignedBase64StringWithError(t *testing.T) {
126 |
127 | base64String := "eyJuYW1lasdIjoiTWF0In0=_67ee82916f90b2c0d68c903266e8998c9ef0c3d6"
128 |
129 | _, err := FromSignedBase64(base64String, "key")
130 |
131 | assert.Error(t, err)
132 |
133 | assert.Panics(t, func() {
134 | MustFromSignedBase64(base64String, "key")
135 | })
136 |
137 | }
138 |
139 | func TestMapFromURLQuery(t *testing.T) {
140 |
141 | m, err := FromURLQuery("name=tyler&state=UT")
142 | if assert.NoError(t, err) && assert.NotNil(t, m) {
143 | assert.Equal(t, "tyler", m.Get("name").Str())
144 | assert.Equal(t, "UT", m.Get("state").Str())
145 | }
146 |
147 | }
148 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/objx/mutations.go:
--------------------------------------------------------------------------------
1 | package objx
2 |
3 | // Exclude returns a new Map with the keys in the specified []string
4 | // excluded.
5 | func (d Map) Exclude(exclude []string) Map {
6 |
7 | excluded := make(Map)
8 | for k, v := range d {
9 | var shouldInclude bool = true
10 | for _, toExclude := range exclude {
11 | if k == toExclude {
12 | shouldInclude = false
13 | break
14 | }
15 | }
16 | if shouldInclude {
17 | excluded[k] = v
18 | }
19 | }
20 |
21 | return excluded
22 | }
23 |
24 | // Copy creates a shallow copy of the Obj.
25 | func (m Map) Copy() Map {
26 | copied := make(map[string]interface{})
27 | for k, v := range m {
28 | copied[k] = v
29 | }
30 | return New(copied)
31 | }
32 |
33 | // Merge blends the specified map with a copy of this map and returns the result.
34 | //
35 | // Keys that appear in both will be selected from the specified map.
36 | // This method requires that the wrapped object be a map[string]interface{}
37 | func (m Map) Merge(merge Map) Map {
38 | return m.Copy().MergeHere(merge)
39 | }
40 |
41 | // Merge blends the specified map with this map and returns the current map.
42 | //
43 | // Keys that appear in both will be selected from the specified map. The original map
44 | // will be modified. This method requires that
45 | // the wrapped object be a map[string]interface{}
46 | func (m Map) MergeHere(merge Map) Map {
47 |
48 | for k, v := range merge {
49 | m[k] = v
50 | }
51 |
52 | return m
53 |
54 | }
55 |
56 | // Transform builds a new Obj giving the transformer a chance
57 | // to change the keys and values as it goes. This method requires that
58 | // the wrapped object be a map[string]interface{}
59 | func (m Map) Transform(transformer func(key string, value interface{}) (string, interface{})) Map {
60 | newMap := make(map[string]interface{})
61 | for k, v := range m {
62 | modifiedKey, modifiedVal := transformer(k, v)
63 | newMap[modifiedKey] = modifiedVal
64 | }
65 | return New(newMap)
66 | }
67 |
68 | // TransformKeys builds a new map using the specified key mapping.
69 | //
70 | // Unspecified keys will be unaltered.
71 | // This method requires that the wrapped object be a map[string]interface{}
72 | func (m Map) TransformKeys(mapping map[string]string) Map {
73 | return m.Transform(func(key string, value interface{}) (string, interface{}) {
74 |
75 | if newKey, ok := mapping[key]; ok {
76 | return newKey, value
77 | }
78 |
79 | return key, value
80 | })
81 | }
82 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/objx/mutations_test.go:
--------------------------------------------------------------------------------
1 | package objx
2 |
3 | import (
4 | "github.com/stretchr/testify/assert"
5 | "testing"
6 | )
7 |
8 | func TestExclude(t *testing.T) {
9 |
10 | d := make(Map)
11 | d["name"] = "Mat"
12 | d["age"] = 29
13 | d["secret"] = "ABC"
14 |
15 | excluded := d.Exclude([]string{"secret"})
16 |
17 | assert.Equal(t, d["name"], excluded["name"])
18 | assert.Equal(t, d["age"], excluded["age"])
19 | assert.False(t, excluded.Has("secret"), "secret should be excluded")
20 |
21 | }
22 |
23 | func TestCopy(t *testing.T) {
24 |
25 | d1 := make(map[string]interface{})
26 | d1["name"] = "Tyler"
27 | d1["location"] = "UT"
28 |
29 | d1Obj := New(d1)
30 | d2Obj := d1Obj.Copy()
31 |
32 | d2Obj["name"] = "Mat"
33 |
34 | assert.Equal(t, d1Obj.Get("name").Str(), "Tyler")
35 | assert.Equal(t, d2Obj.Get("name").Str(), "Mat")
36 |
37 | }
38 |
39 | func TestMerge(t *testing.T) {
40 |
41 | d := make(map[string]interface{})
42 | d["name"] = "Mat"
43 |
44 | d1 := make(map[string]interface{})
45 | d1["name"] = "Tyler"
46 | d1["location"] = "UT"
47 |
48 | dObj := New(d)
49 | d1Obj := New(d1)
50 |
51 | merged := dObj.Merge(d1Obj)
52 |
53 | assert.Equal(t, merged.Get("name").Str(), d1Obj.Get("name").Str())
54 | assert.Equal(t, merged.Get("location").Str(), d1Obj.Get("location").Str())
55 | assert.Empty(t, dObj.Get("location").Str())
56 |
57 | }
58 |
59 | func TestMergeHere(t *testing.T) {
60 |
61 | d := make(map[string]interface{})
62 | d["name"] = "Mat"
63 |
64 | d1 := make(map[string]interface{})
65 | d1["name"] = "Tyler"
66 | d1["location"] = "UT"
67 |
68 | dObj := New(d)
69 | d1Obj := New(d1)
70 |
71 | merged := dObj.MergeHere(d1Obj)
72 |
73 | assert.Equal(t, dObj, merged, "With MergeHere, it should return the first modified map")
74 | assert.Equal(t, merged.Get("name").Str(), d1Obj.Get("name").Str())
75 | assert.Equal(t, merged.Get("location").Str(), d1Obj.Get("location").Str())
76 | assert.Equal(t, merged.Get("location").Str(), dObj.Get("location").Str())
77 | }
78 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/objx/security.go:
--------------------------------------------------------------------------------
1 | package objx
2 |
3 | import (
4 | "crypto/sha1"
5 | "encoding/hex"
6 | )
7 |
8 | // HashWithKey hashes the specified string using the security
9 | // key.
10 | func HashWithKey(data, key string) string {
11 | hash := sha1.New()
12 | hash.Write([]byte(data + ":" + key))
13 | return hex.EncodeToString(hash.Sum(nil))
14 | }
15 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/objx/security_test.go:
--------------------------------------------------------------------------------
1 | package objx
2 |
3 | import (
4 | "github.com/stretchr/testify/assert"
5 | "testing"
6 | )
7 |
8 | func TestHashWithKey(t *testing.T) {
9 |
10 | assert.Equal(t, "0ce84d8d01f2c7b6e0882b784429c54d280ea2d9", HashWithKey("abc", "def"))
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/objx/simple_example_test.go:
--------------------------------------------------------------------------------
1 | package objx
2 |
3 | import (
4 | "github.com/stretchr/testify/assert"
5 | "testing"
6 | )
7 |
8 | func TestSimpleExample(t *testing.T) {
9 |
10 | // build a map from a JSON object
11 | o := MustFromJSON(`{"name":"Mat","foods":["indian","chinese"], "location":{"county":"hobbiton","city":"the shire"}}`)
12 |
13 | // Map can be used as a straight map[string]interface{}
14 | assert.Equal(t, o["name"], "Mat")
15 |
16 | // Get an Value object
17 | v := o.Get("name")
18 | assert.Equal(t, v, &Value{data: "Mat"})
19 |
20 | // Test the contained value
21 | assert.False(t, v.IsInt())
22 | assert.False(t, v.IsBool())
23 | assert.True(t, v.IsStr())
24 |
25 | // Get the contained value
26 | assert.Equal(t, v.Str(), "Mat")
27 |
28 | // Get a default value if the contained value is not of the expected type or does not exist
29 | assert.Equal(t, 1, v.Int(1))
30 |
31 | // Get a value by using array notation
32 | assert.Equal(t, "indian", o.Get("foods[0]").Data())
33 |
34 | // Set a value by using array notation
35 | o.Set("foods[0]", "italian")
36 | assert.Equal(t, "italian", o.Get("foods[0]").Str())
37 |
38 | // Get a value by using dot notation
39 | assert.Equal(t, "hobbiton", o.Get("location.county").Str())
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/objx/tests.go:
--------------------------------------------------------------------------------
1 | package objx
2 |
3 | // Has gets whether there is something at the specified selector
4 | // or not.
5 | //
6 | // If m is nil, Has will always return false.
7 | func (m Map) Has(selector string) bool {
8 | if m == nil {
9 | return false
10 | }
11 | return !m.Get(selector).IsNil()
12 | }
13 |
14 | // IsNil gets whether the data is nil or not.
15 | func (v *Value) IsNil() bool {
16 | return v == nil || v.data == nil
17 | }
18 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/objx/tests_test.go:
--------------------------------------------------------------------------------
1 | package objx
2 |
3 | import (
4 | "github.com/stretchr/testify/assert"
5 | "testing"
6 | )
7 |
8 | func TestHas(t *testing.T) {
9 |
10 | m := New(TestMap)
11 |
12 | assert.True(t, m.Has("name"))
13 | assert.True(t, m.Has("address.state"))
14 | assert.True(t, m.Has("numbers[4]"))
15 |
16 | assert.False(t, m.Has("address.state.nope"))
17 | assert.False(t, m.Has("address.nope"))
18 | assert.False(t, m.Has("nope"))
19 | assert.False(t, m.Has("numbers[5]"))
20 |
21 | m = nil
22 | assert.False(t, m.Has("nothing"))
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/objx/type_specific_codegen.go:
--------------------------------------------------------------------------------
1 | package objx
2 |
3 | /*
4 | Inter (interface{} and []interface{})
5 | --------------------------------------------------
6 | */
7 |
8 | // Inter gets the value as a interface{}, returns the optionalDefault
9 | // value or a system default object if the value is the wrong type.
10 | func (v *Value) Inter(optionalDefault ...interface{}) interface{} {
11 | if s, ok := v.data.(interface{}); ok {
12 | return s
13 | }
14 | if len(optionalDefault) == 1 {
15 | return optionalDefault[0]
16 | }
17 | return nil
18 | }
19 |
20 | // MustInter gets the value as a interface{}.
21 | //
22 | // Panics if the object is not a interface{}.
23 | func (v *Value) MustInter() interface{} {
24 | return v.data.(interface{})
25 | }
26 |
27 | // InterSlice gets the value as a []interface{}, returns the optionalDefault
28 | // value or nil if the value is not a []interface{}.
29 | func (v *Value) InterSlice(optionalDefault ...[]interface{}) []interface{} {
30 | if s, ok := v.data.([]interface{}); ok {
31 | return s
32 | }
33 | if len(optionalDefault) == 1 {
34 | return optionalDefault[0]
35 | }
36 | return nil
37 | }
38 |
39 | // MustInterSlice gets the value as a []interface{}.
40 | //
41 | // Panics if the object is not a []interface{}.
42 | func (v *Value) MustInterSlice() []interface{} {
43 | return v.data.([]interface{})
44 | }
45 |
46 | // IsInter gets whether the object contained is a interface{} or not.
47 | func (v *Value) IsInter() bool {
48 | _, ok := v.data.(interface{})
49 | return ok
50 | }
51 |
52 | // IsInterSlice gets whether the object contained is a []interface{} or not.
53 | func (v *Value) IsInterSlice() bool {
54 | _, ok := v.data.([]interface{})
55 | return ok
56 | }
57 |
58 | // EachInter calls the specified callback for each object
59 | // in the []interface{}.
60 | //
61 | // Panics if the object is the wrong type.
62 | func (v *Value) EachInter(callback func(int, interface{}) bool) *Value {
63 |
64 | for index, val := range v.MustInterSlice() {
65 | carryon := callback(index, val)
66 | if carryon == false {
67 | break
68 | }
69 | }
70 |
71 | return v
72 |
73 | }
74 |
75 | // WhereInter uses the specified decider function to select items
76 | // from the []interface{}. The object contained in the result will contain
77 | // only the selected items.
78 | func (v *Value) WhereInter(decider func(int, interface{}) bool) *Value {
79 |
80 | var selected []interface{}
81 |
82 | v.EachInter(func(index int, val interface{}) bool {
83 | shouldSelect := decider(index, val)
84 | if shouldSelect == false {
85 | selected = append(selected, val)
86 | }
87 | return true
88 | })
89 |
90 | return &Value{data: selected}
91 |
92 | }
93 |
94 | // GroupInter uses the specified grouper function to group the items
95 | // keyed by the return of the grouper. The object contained in the
96 | // result will contain a map[string][]interface{}.
97 | func (v *Value) GroupInter(grouper func(int, interface{}) string) *Value {
98 |
99 | groups := make(map[string][]interface{})
100 |
101 | v.EachInter(func(index int, val interface{}) bool {
102 | group := grouper(index, val)
103 | if _, ok := groups[group]; !ok {
104 | groups[group] = make([]interface{}, 0)
105 | }
106 | groups[group] = append(groups[group], val)
107 | return true
108 | })
109 |
110 | return &Value{data: groups}
111 |
112 | }
113 |
114 | // ReplaceInter uses the specified function to replace each interface{}s
115 | // by iterating each item. The data in the returned result will be a
116 | // []interface{} containing the replaced items.
117 | func (v *Value) ReplaceInter(replacer func(int, interface{}) interface{}) *Value {
118 |
119 | arr := v.MustInterSlice()
120 | replaced := make([]interface{}, len(arr))
121 |
122 | v.EachInter(func(index int, val interface{}) bool {
123 | replaced[index] = replacer(index, val)
124 | return true
125 | })
126 |
127 | return &Value{data: replaced}
128 |
129 | }
130 |
131 | // CollectInter uses the specified collector function to collect a value
132 | // for each of the interface{}s in the slice. The data returned will be a
133 | // []interface{}.
134 | func (v *Value) CollectInter(collector func(int, interface{}) interface{}) *Value {
135 |
136 | arr := v.MustInterSlice()
137 | collected := make([]interface{}, len(arr))
138 |
139 | v.EachInter(func(index int, val interface{}) bool {
140 | collected[index] = collector(index, val)
141 | return true
142 | })
143 |
144 | return &Value{data: collected}
145 | }
146 |
147 | /*
148 | MSI (map[string]interface{} and []map[string]interface{})
149 | --------------------------------------------------
150 | */
151 |
152 | // MSI gets the value as a map[string]interface{}, returns the optionalDefault
153 | // value or a system default object if the value is the wrong type.
154 | func (v *Value) MSI(optionalDefault ...map[string]interface{}) map[string]interface{} {
155 | if s, ok := v.data.(map[string]interface{}); ok {
156 | return s
157 | }
158 | if len(optionalDefault) == 1 {
159 | return optionalDefault[0]
160 | }
161 | return nil
162 | }
163 |
164 | // MustMSI gets the value as a map[string]interface{}.
165 | //
166 | // Panics if the object is not a map[string]interface{}.
167 | func (v *Value) MustMSI() map[string]interface{} {
168 | return v.data.(map[string]interface{})
169 | }
170 |
171 | // MSISlice gets the value as a []map[string]interface{}, returns the optionalDefault
172 | // value or nil if the value is not a []map[string]interface{}.
173 | func (v *Value) MSISlice(optionalDefault ...[]map[string]interface{}) []map[string]interface{} {
174 | if s, ok := v.data.([]map[string]interface{}); ok {
175 | return s
176 | }
177 | if len(optionalDefault) == 1 {
178 | return optionalDefault[0]
179 | }
180 | return nil
181 | }
182 |
183 | // MustMSISlice gets the value as a []map[string]interface{}.
184 | //
185 | // Panics if the object is not a []map[string]interface{}.
186 | func (v *Value) MustMSISlice() []map[string]interface{} {
187 | return v.data.([]map[string]interface{})
188 | }
189 |
190 | // IsMSI gets whether the object contained is a map[string]interface{} or not.
191 | func (v *Value) IsMSI() bool {
192 | _, ok := v.data.(map[string]interface{})
193 | return ok
194 | }
195 |
196 | // IsMSISlice gets whether the object contained is a []map[string]interface{} or not.
197 | func (v *Value) IsMSISlice() bool {
198 | _, ok := v.data.([]map[string]interface{})
199 | return ok
200 | }
201 |
202 | // EachMSI calls the specified callback for each object
203 | // in the []map[string]interface{}.
204 | //
205 | // Panics if the object is the wrong type.
206 | func (v *Value) EachMSI(callback func(int, map[string]interface{}) bool) *Value {
207 |
208 | for index, val := range v.MustMSISlice() {
209 | carryon := callback(index, val)
210 | if carryon == false {
211 | break
212 | }
213 | }
214 |
215 | return v
216 |
217 | }
218 |
219 | // WhereMSI uses the specified decider function to select items
220 | // from the []map[string]interface{}. The object contained in the result will contain
221 | // only the selected items.
222 | func (v *Value) WhereMSI(decider func(int, map[string]interface{}) bool) *Value {
223 |
224 | var selected []map[string]interface{}
225 |
226 | v.EachMSI(func(index int, val map[string]interface{}) bool {
227 | shouldSelect := decider(index, val)
228 | if shouldSelect == false {
229 | selected = append(selected, val)
230 | }
231 | return true
232 | })
233 |
234 | return &Value{data: selected}
235 |
236 | }
237 |
238 | // GroupMSI uses the specified grouper function to group the items
239 | // keyed by the return of the grouper. The object contained in the
240 | // result will contain a map[string][]map[string]interface{}.
241 | func (v *Value) GroupMSI(grouper func(int, map[string]interface{}) string) *Value {
242 |
243 | groups := make(map[string][]map[string]interface{})
244 |
245 | v.EachMSI(func(index int, val map[string]interface{}) bool {
246 | group := grouper(index, val)
247 | if _, ok := groups[group]; !ok {
248 | groups[group] = make([]map[string]interface{}, 0)
249 | }
250 | groups[group] = append(groups[group], val)
251 | return true
252 | })
253 |
254 | return &Value{data: groups}
255 |
256 | }
257 |
258 | // ReplaceMSI uses the specified function to replace each map[string]interface{}s
259 | // by iterating each item. The data in the returned result will be a
260 | // []map[string]interface{} containing the replaced items.
261 | func (v *Value) ReplaceMSI(replacer func(int, map[string]interface{}) map[string]interface{}) *Value {
262 |
263 | arr := v.MustMSISlice()
264 | replaced := make([]map[string]interface{}, len(arr))
265 |
266 | v.EachMSI(func(index int, val map[string]interface{}) bool {
267 | replaced[index] = replacer(index, val)
268 | return true
269 | })
270 |
271 | return &Value{data: replaced}
272 |
273 | }
274 |
275 | // CollectMSI uses the specified collector function to collect a value
276 | // for each of the map[string]interface{}s in the slice. The data returned will be a
277 | // []interface{}.
278 | func (v *Value) CollectMSI(collector func(int, map[string]interface{}) interface{}) *Value {
279 |
280 | arr := v.MustMSISlice()
281 | collected := make([]interface{}, len(arr))
282 |
283 | v.EachMSI(func(index int, val map[string]interface{}) bool {
284 | collected[index] = collector(index, val)
285 | return true
286 | })
287 |
288 | return &Value{data: collected}
289 | }
290 |
291 | /*
292 | ObjxMap ((Map) and [](Map))
293 | --------------------------------------------------
294 | */
295 |
296 | // ObjxMap gets the value as a (Map), returns the optionalDefault
297 | // value or a system default object if the value is the wrong type.
298 | func (v *Value) ObjxMap(optionalDefault ...(Map)) Map {
299 | if s, ok := v.data.((Map)); ok {
300 | return s
301 | }
302 | if len(optionalDefault) == 1 {
303 | return optionalDefault[0]
304 | }
305 | return New(nil)
306 | }
307 |
308 | // MustObjxMap gets the value as a (Map).
309 | //
310 | // Panics if the object is not a (Map).
311 | func (v *Value) MustObjxMap() Map {
312 | return v.data.((Map))
313 | }
314 |
315 | // ObjxMapSlice gets the value as a [](Map), returns the optionalDefault
316 | // value or nil if the value is not a [](Map).
317 | func (v *Value) ObjxMapSlice(optionalDefault ...[](Map)) [](Map) {
318 | if s, ok := v.data.([](Map)); ok {
319 | return s
320 | }
321 | if len(optionalDefault) == 1 {
322 | return optionalDefault[0]
323 | }
324 | return nil
325 | }
326 |
327 | // MustObjxMapSlice gets the value as a [](Map).
328 | //
329 | // Panics if the object is not a [](Map).
330 | func (v *Value) MustObjxMapSlice() [](Map) {
331 | return v.data.([](Map))
332 | }
333 |
334 | // IsObjxMap gets whether the object contained is a (Map) or not.
335 | func (v *Value) IsObjxMap() bool {
336 | _, ok := v.data.((Map))
337 | return ok
338 | }
339 |
340 | // IsObjxMapSlice gets whether the object contained is a [](Map) or not.
341 | func (v *Value) IsObjxMapSlice() bool {
342 | _, ok := v.data.([](Map))
343 | return ok
344 | }
345 |
346 | // EachObjxMap calls the specified callback for each object
347 | // in the [](Map).
348 | //
349 | // Panics if the object is the wrong type.
350 | func (v *Value) EachObjxMap(callback func(int, Map) bool) *Value {
351 |
352 | for index, val := range v.MustObjxMapSlice() {
353 | carryon := callback(index, val)
354 | if carryon == false {
355 | break
356 | }
357 | }
358 |
359 | return v
360 |
361 | }
362 |
363 | // WhereObjxMap uses the specified decider function to select items
364 | // from the [](Map). The object contained in the result will contain
365 | // only the selected items.
366 | func (v *Value) WhereObjxMap(decider func(int, Map) bool) *Value {
367 |
368 | var selected [](Map)
369 |
370 | v.EachObjxMap(func(index int, val Map) bool {
371 | shouldSelect := decider(index, val)
372 | if shouldSelect == false {
373 | selected = append(selected, val)
374 | }
375 | return true
376 | })
377 |
378 | return &Value{data: selected}
379 |
380 | }
381 |
382 | // GroupObjxMap uses the specified grouper function to group the items
383 | // keyed by the return of the grouper. The object contained in the
384 | // result will contain a map[string][](Map).
385 | func (v *Value) GroupObjxMap(grouper func(int, Map) string) *Value {
386 |
387 | groups := make(map[string][](Map))
388 |
389 | v.EachObjxMap(func(index int, val Map) bool {
390 | group := grouper(index, val)
391 | if _, ok := groups[group]; !ok {
392 | groups[group] = make([](Map), 0)
393 | }
394 | groups[group] = append(groups[group], val)
395 | return true
396 | })
397 |
398 | return &Value{data: groups}
399 |
400 | }
401 |
402 | // ReplaceObjxMap uses the specified function to replace each (Map)s
403 | // by iterating each item. The data in the returned result will be a
404 | // [](Map) containing the replaced items.
405 | func (v *Value) ReplaceObjxMap(replacer func(int, Map) Map) *Value {
406 |
407 | arr := v.MustObjxMapSlice()
408 | replaced := make([](Map), len(arr))
409 |
410 | v.EachObjxMap(func(index int, val Map) bool {
411 | replaced[index] = replacer(index, val)
412 | return true
413 | })
414 |
415 | return &Value{data: replaced}
416 |
417 | }
418 |
419 | // CollectObjxMap uses the specified collector function to collect a value
420 | // for each of the (Map)s in the slice. The data returned will be a
421 | // []interface{}.
422 | func (v *Value) CollectObjxMap(collector func(int, Map) interface{}) *Value {
423 |
424 | arr := v.MustObjxMapSlice()
425 | collected := make([]interface{}, len(arr))
426 |
427 | v.EachObjxMap(func(index int, val Map) bool {
428 | collected[index] = collector(index, val)
429 | return true
430 | })
431 |
432 | return &Value{data: collected}
433 | }
434 |
435 | /*
436 | Bool (bool and []bool)
437 | --------------------------------------------------
438 | */
439 |
440 | // Bool gets the value as a bool, returns the optionalDefault
441 | // value or a system default object if the value is the wrong type.
442 | func (v *Value) Bool(optionalDefault ...bool) bool {
443 | if s, ok := v.data.(bool); ok {
444 | return s
445 | }
446 | if len(optionalDefault) == 1 {
447 | return optionalDefault[0]
448 | }
449 | return false
450 | }
451 |
452 | // MustBool gets the value as a bool.
453 | //
454 | // Panics if the object is not a bool.
455 | func (v *Value) MustBool() bool {
456 | return v.data.(bool)
457 | }
458 |
459 | // BoolSlice gets the value as a []bool, returns the optionalDefault
460 | // value or nil if the value is not a []bool.
461 | func (v *Value) BoolSlice(optionalDefault ...[]bool) []bool {
462 | if s, ok := v.data.([]bool); ok {
463 | return s
464 | }
465 | if len(optionalDefault) == 1 {
466 | return optionalDefault[0]
467 | }
468 | return nil
469 | }
470 |
471 | // MustBoolSlice gets the value as a []bool.
472 | //
473 | // Panics if the object is not a []bool.
474 | func (v *Value) MustBoolSlice() []bool {
475 | return v.data.([]bool)
476 | }
477 |
478 | // IsBool gets whether the object contained is a bool or not.
479 | func (v *Value) IsBool() bool {
480 | _, ok := v.data.(bool)
481 | return ok
482 | }
483 |
484 | // IsBoolSlice gets whether the object contained is a []bool or not.
485 | func (v *Value) IsBoolSlice() bool {
486 | _, ok := v.data.([]bool)
487 | return ok
488 | }
489 |
490 | // EachBool calls the specified callback for each object
491 | // in the []bool.
492 | //
493 | // Panics if the object is the wrong type.
494 | func (v *Value) EachBool(callback func(int, bool) bool) *Value {
495 |
496 | for index, val := range v.MustBoolSlice() {
497 | carryon := callback(index, val)
498 | if carryon == false {
499 | break
500 | }
501 | }
502 |
503 | return v
504 |
505 | }
506 |
507 | // WhereBool uses the specified decider function to select items
508 | // from the []bool. The object contained in the result will contain
509 | // only the selected items.
510 | func (v *Value) WhereBool(decider func(int, bool) bool) *Value {
511 |
512 | var selected []bool
513 |
514 | v.EachBool(func(index int, val bool) bool {
515 | shouldSelect := decider(index, val)
516 | if shouldSelect == false {
517 | selected = append(selected, val)
518 | }
519 | return true
520 | })
521 |
522 | return &Value{data: selected}
523 |
524 | }
525 |
526 | // GroupBool uses the specified grouper function to group the items
527 | // keyed by the return of the grouper. The object contained in the
528 | // result will contain a map[string][]bool.
529 | func (v *Value) GroupBool(grouper func(int, bool) string) *Value {
530 |
531 | groups := make(map[string][]bool)
532 |
533 | v.EachBool(func(index int, val bool) bool {
534 | group := grouper(index, val)
535 | if _, ok := groups[group]; !ok {
536 | groups[group] = make([]bool, 0)
537 | }
538 | groups[group] = append(groups[group], val)
539 | return true
540 | })
541 |
542 | return &Value{data: groups}
543 |
544 | }
545 |
546 | // ReplaceBool uses the specified function to replace each bools
547 | // by iterating each item. The data in the returned result will be a
548 | // []bool containing the replaced items.
549 | func (v *Value) ReplaceBool(replacer func(int, bool) bool) *Value {
550 |
551 | arr := v.MustBoolSlice()
552 | replaced := make([]bool, len(arr))
553 |
554 | v.EachBool(func(index int, val bool) bool {
555 | replaced[index] = replacer(index, val)
556 | return true
557 | })
558 |
559 | return &Value{data: replaced}
560 |
561 | }
562 |
563 | // CollectBool uses the specified collector function to collect a value
564 | // for each of the bools in the slice. The data returned will be a
565 | // []interface{}.
566 | func (v *Value) CollectBool(collector func(int, bool) interface{}) *Value {
567 |
568 | arr := v.MustBoolSlice()
569 | collected := make([]interface{}, len(arr))
570 |
571 | v.EachBool(func(index int, val bool) bool {
572 | collected[index] = collector(index, val)
573 | return true
574 | })
575 |
576 | return &Value{data: collected}
577 | }
578 |
579 | /*
580 | Str (string and []string)
581 | --------------------------------------------------
582 | */
583 |
584 | // Str gets the value as a string, returns the optionalDefault
585 | // value or a system default object if the value is the wrong type.
586 | func (v *Value) Str(optionalDefault ...string) string {
587 | if s, ok := v.data.(string); ok {
588 | return s
589 | }
590 | if len(optionalDefault) == 1 {
591 | return optionalDefault[0]
592 | }
593 | return ""
594 | }
595 |
596 | // MustStr gets the value as a string.
597 | //
598 | // Panics if the object is not a string.
599 | func (v *Value) MustStr() string {
600 | return v.data.(string)
601 | }
602 |
603 | // StrSlice gets the value as a []string, returns the optionalDefault
604 | // value or nil if the value is not a []string.
605 | func (v *Value) StrSlice(optionalDefault ...[]string) []string {
606 | if s, ok := v.data.([]string); ok {
607 | return s
608 | }
609 | if len(optionalDefault) == 1 {
610 | return optionalDefault[0]
611 | }
612 | return nil
613 | }
614 |
615 | // MustStrSlice gets the value as a []string.
616 | //
617 | // Panics if the object is not a []string.
618 | func (v *Value) MustStrSlice() []string {
619 | return v.data.([]string)
620 | }
621 |
622 | // IsStr gets whether the object contained is a string or not.
623 | func (v *Value) IsStr() bool {
624 | _, ok := v.data.(string)
625 | return ok
626 | }
627 |
628 | // IsStrSlice gets whether the object contained is a []string or not.
629 | func (v *Value) IsStrSlice() bool {
630 | _, ok := v.data.([]string)
631 | return ok
632 | }
633 |
634 | // EachStr calls the specified callback for each object
635 | // in the []string.
636 | //
637 | // Panics if the object is the wrong type.
638 | func (v *Value) EachStr(callback func(int, string) bool) *Value {
639 |
640 | for index, val := range v.MustStrSlice() {
641 | carryon := callback(index, val)
642 | if carryon == false {
643 | break
644 | }
645 | }
646 |
647 | return v
648 |
649 | }
650 |
651 | // WhereStr uses the specified decider function to select items
652 | // from the []string. The object contained in the result will contain
653 | // only the selected items.
654 | func (v *Value) WhereStr(decider func(int, string) bool) *Value {
655 |
656 | var selected []string
657 |
658 | v.EachStr(func(index int, val string) bool {
659 | shouldSelect := decider(index, val)
660 | if shouldSelect == false {
661 | selected = append(selected, val)
662 | }
663 | return true
664 | })
665 |
666 | return &Value{data: selected}
667 |
668 | }
669 |
670 | // GroupStr uses the specified grouper function to group the items
671 | // keyed by the return of the grouper. The object contained in the
672 | // result will contain a map[string][]string.
673 | func (v *Value) GroupStr(grouper func(int, string) string) *Value {
674 |
675 | groups := make(map[string][]string)
676 |
677 | v.EachStr(func(index int, val string) bool {
678 | group := grouper(index, val)
679 | if _, ok := groups[group]; !ok {
680 | groups[group] = make([]string, 0)
681 | }
682 | groups[group] = append(groups[group], val)
683 | return true
684 | })
685 |
686 | return &Value{data: groups}
687 |
688 | }
689 |
690 | // ReplaceStr uses the specified function to replace each strings
691 | // by iterating each item. The data in the returned result will be a
692 | // []string containing the replaced items.
693 | func (v *Value) ReplaceStr(replacer func(int, string) string) *Value {
694 |
695 | arr := v.MustStrSlice()
696 | replaced := make([]string, len(arr))
697 |
698 | v.EachStr(func(index int, val string) bool {
699 | replaced[index] = replacer(index, val)
700 | return true
701 | })
702 |
703 | return &Value{data: replaced}
704 |
705 | }
706 |
707 | // CollectStr uses the specified collector function to collect a value
708 | // for each of the strings in the slice. The data returned will be a
709 | // []interface{}.
710 | func (v *Value) CollectStr(collector func(int, string) interface{}) *Value {
711 |
712 | arr := v.MustStrSlice()
713 | collected := make([]interface{}, len(arr))
714 |
715 | v.EachStr(func(index int, val string) bool {
716 | collected[index] = collector(index, val)
717 | return true
718 | })
719 |
720 | return &Value{data: collected}
721 | }
722 |
723 | /*
724 | Int (int and []int)
725 | --------------------------------------------------
726 | */
727 |
728 | // Int gets the value as a int, returns the optionalDefault
729 | // value or a system default object if the value is the wrong type.
730 | func (v *Value) Int(optionalDefault ...int) int {
731 | if s, ok := v.data.(int); ok {
732 | return s
733 | }
734 | if len(optionalDefault) == 1 {
735 | return optionalDefault[0]
736 | }
737 | return 0
738 | }
739 |
740 | // MustInt gets the value as a int.
741 | //
742 | // Panics if the object is not a int.
743 | func (v *Value) MustInt() int {
744 | return v.data.(int)
745 | }
746 |
747 | // IntSlice gets the value as a []int, returns the optionalDefault
748 | // value or nil if the value is not a []int.
749 | func (v *Value) IntSlice(optionalDefault ...[]int) []int {
750 | if s, ok := v.data.([]int); ok {
751 | return s
752 | }
753 | if len(optionalDefault) == 1 {
754 | return optionalDefault[0]
755 | }
756 | return nil
757 | }
758 |
759 | // MustIntSlice gets the value as a []int.
760 | //
761 | // Panics if the object is not a []int.
762 | func (v *Value) MustIntSlice() []int {
763 | return v.data.([]int)
764 | }
765 |
766 | // IsInt gets whether the object contained is a int or not.
767 | func (v *Value) IsInt() bool {
768 | _, ok := v.data.(int)
769 | return ok
770 | }
771 |
772 | // IsIntSlice gets whether the object contained is a []int or not.
773 | func (v *Value) IsIntSlice() bool {
774 | _, ok := v.data.([]int)
775 | return ok
776 | }
777 |
778 | // EachInt calls the specified callback for each object
779 | // in the []int.
780 | //
781 | // Panics if the object is the wrong type.
782 | func (v *Value) EachInt(callback func(int, int) bool) *Value {
783 |
784 | for index, val := range v.MustIntSlice() {
785 | carryon := callback(index, val)
786 | if carryon == false {
787 | break
788 | }
789 | }
790 |
791 | return v
792 |
793 | }
794 |
795 | // WhereInt uses the specified decider function to select items
796 | // from the []int. The object contained in the result will contain
797 | // only the selected items.
798 | func (v *Value) WhereInt(decider func(int, int) bool) *Value {
799 |
800 | var selected []int
801 |
802 | v.EachInt(func(index int, val int) bool {
803 | shouldSelect := decider(index, val)
804 | if shouldSelect == false {
805 | selected = append(selected, val)
806 | }
807 | return true
808 | })
809 |
810 | return &Value{data: selected}
811 |
812 | }
813 |
814 | // GroupInt uses the specified grouper function to group the items
815 | // keyed by the return of the grouper. The object contained in the
816 | // result will contain a map[string][]int.
817 | func (v *Value) GroupInt(grouper func(int, int) string) *Value {
818 |
819 | groups := make(map[string][]int)
820 |
821 | v.EachInt(func(index int, val int) bool {
822 | group := grouper(index, val)
823 | if _, ok := groups[group]; !ok {
824 | groups[group] = make([]int, 0)
825 | }
826 | groups[group] = append(groups[group], val)
827 | return true
828 | })
829 |
830 | return &Value{data: groups}
831 |
832 | }
833 |
834 | // ReplaceInt uses the specified function to replace each ints
835 | // by iterating each item. The data in the returned result will be a
836 | // []int containing the replaced items.
837 | func (v *Value) ReplaceInt(replacer func(int, int) int) *Value {
838 |
839 | arr := v.MustIntSlice()
840 | replaced := make([]int, len(arr))
841 |
842 | v.EachInt(func(index int, val int) bool {
843 | replaced[index] = replacer(index, val)
844 | return true
845 | })
846 |
847 | return &Value{data: replaced}
848 |
849 | }
850 |
851 | // CollectInt uses the specified collector function to collect a value
852 | // for each of the ints in the slice. The data returned will be a
853 | // []interface{}.
854 | func (v *Value) CollectInt(collector func(int, int) interface{}) *Value {
855 |
856 | arr := v.MustIntSlice()
857 | collected := make([]interface{}, len(arr))
858 |
859 | v.EachInt(func(index int, val int) bool {
860 | collected[index] = collector(index, val)
861 | return true
862 | })
863 |
864 | return &Value{data: collected}
865 | }
866 |
867 | /*
868 | Int8 (int8 and []int8)
869 | --------------------------------------------------
870 | */
871 |
872 | // Int8 gets the value as a int8, returns the optionalDefault
873 | // value or a system default object if the value is the wrong type.
874 | func (v *Value) Int8(optionalDefault ...int8) int8 {
875 | if s, ok := v.data.(int8); ok {
876 | return s
877 | }
878 | if len(optionalDefault) == 1 {
879 | return optionalDefault[0]
880 | }
881 | return 0
882 | }
883 |
884 | // MustInt8 gets the value as a int8.
885 | //
886 | // Panics if the object is not a int8.
887 | func (v *Value) MustInt8() int8 {
888 | return v.data.(int8)
889 | }
890 |
891 | // Int8Slice gets the value as a []int8, returns the optionalDefault
892 | // value or nil if the value is not a []int8.
893 | func (v *Value) Int8Slice(optionalDefault ...[]int8) []int8 {
894 | if s, ok := v.data.([]int8); ok {
895 | return s
896 | }
897 | if len(optionalDefault) == 1 {
898 | return optionalDefault[0]
899 | }
900 | return nil
901 | }
902 |
903 | // MustInt8Slice gets the value as a []int8.
904 | //
905 | // Panics if the object is not a []int8.
906 | func (v *Value) MustInt8Slice() []int8 {
907 | return v.data.([]int8)
908 | }
909 |
910 | // IsInt8 gets whether the object contained is a int8 or not.
911 | func (v *Value) IsInt8() bool {
912 | _, ok := v.data.(int8)
913 | return ok
914 | }
915 |
916 | // IsInt8Slice gets whether the object contained is a []int8 or not.
917 | func (v *Value) IsInt8Slice() bool {
918 | _, ok := v.data.([]int8)
919 | return ok
920 | }
921 |
922 | // EachInt8 calls the specified callback for each object
923 | // in the []int8.
924 | //
925 | // Panics if the object is the wrong type.
926 | func (v *Value) EachInt8(callback func(int, int8) bool) *Value {
927 |
928 | for index, val := range v.MustInt8Slice() {
929 | carryon := callback(index, val)
930 | if carryon == false {
931 | break
932 | }
933 | }
934 |
935 | return v
936 |
937 | }
938 |
939 | // WhereInt8 uses the specified decider function to select items
940 | // from the []int8. The object contained in the result will contain
941 | // only the selected items.
942 | func (v *Value) WhereInt8(decider func(int, int8) bool) *Value {
943 |
944 | var selected []int8
945 |
946 | v.EachInt8(func(index int, val int8) bool {
947 | shouldSelect := decider(index, val)
948 | if shouldSelect == false {
949 | selected = append(selected, val)
950 | }
951 | return true
952 | })
953 |
954 | return &Value{data: selected}
955 |
956 | }
957 |
958 | // GroupInt8 uses the specified grouper function to group the items
959 | // keyed by the return of the grouper. The object contained in the
960 | // result will contain a map[string][]int8.
961 | func (v *Value) GroupInt8(grouper func(int, int8) string) *Value {
962 |
963 | groups := make(map[string][]int8)
964 |
965 | v.EachInt8(func(index int, val int8) bool {
966 | group := grouper(index, val)
967 | if _, ok := groups[group]; !ok {
968 | groups[group] = make([]int8, 0)
969 | }
970 | groups[group] = append(groups[group], val)
971 | return true
972 | })
973 |
974 | return &Value{data: groups}
975 |
976 | }
977 |
978 | // ReplaceInt8 uses the specified function to replace each int8s
979 | // by iterating each item. The data in the returned result will be a
980 | // []int8 containing the replaced items.
981 | func (v *Value) ReplaceInt8(replacer func(int, int8) int8) *Value {
982 |
983 | arr := v.MustInt8Slice()
984 | replaced := make([]int8, len(arr))
985 |
986 | v.EachInt8(func(index int, val int8) bool {
987 | replaced[index] = replacer(index, val)
988 | return true
989 | })
990 |
991 | return &Value{data: replaced}
992 |
993 | }
994 |
995 | // CollectInt8 uses the specified collector function to collect a value
996 | // for each of the int8s in the slice. The data returned will be a
997 | // []interface{}.
998 | func (v *Value) CollectInt8(collector func(int, int8) interface{}) *Value {
999 |
1000 | arr := v.MustInt8Slice()
1001 | collected := make([]interface{}, len(arr))
1002 |
1003 | v.EachInt8(func(index int, val int8) bool {
1004 | collected[index] = collector(index, val)
1005 | return true
1006 | })
1007 |
1008 | return &Value{data: collected}
1009 | }
1010 |
1011 | /*
1012 | Int16 (int16 and []int16)
1013 | --------------------------------------------------
1014 | */
1015 |
1016 | // Int16 gets the value as a int16, returns the optionalDefault
1017 | // value or a system default object if the value is the wrong type.
1018 | func (v *Value) Int16(optionalDefault ...int16) int16 {
1019 | if s, ok := v.data.(int16); ok {
1020 | return s
1021 | }
1022 | if len(optionalDefault) == 1 {
1023 | return optionalDefault[0]
1024 | }
1025 | return 0
1026 | }
1027 |
1028 | // MustInt16 gets the value as a int16.
1029 | //
1030 | // Panics if the object is not a int16.
1031 | func (v *Value) MustInt16() int16 {
1032 | return v.data.(int16)
1033 | }
1034 |
1035 | // Int16Slice gets the value as a []int16, returns the optionalDefault
1036 | // value or nil if the value is not a []int16.
1037 | func (v *Value) Int16Slice(optionalDefault ...[]int16) []int16 {
1038 | if s, ok := v.data.([]int16); ok {
1039 | return s
1040 | }
1041 | if len(optionalDefault) == 1 {
1042 | return optionalDefault[0]
1043 | }
1044 | return nil
1045 | }
1046 |
1047 | // MustInt16Slice gets the value as a []int16.
1048 | //
1049 | // Panics if the object is not a []int16.
1050 | func (v *Value) MustInt16Slice() []int16 {
1051 | return v.data.([]int16)
1052 | }
1053 |
1054 | // IsInt16 gets whether the object contained is a int16 or not.
1055 | func (v *Value) IsInt16() bool {
1056 | _, ok := v.data.(int16)
1057 | return ok
1058 | }
1059 |
1060 | // IsInt16Slice gets whether the object contained is a []int16 or not.
1061 | func (v *Value) IsInt16Slice() bool {
1062 | _, ok := v.data.([]int16)
1063 | return ok
1064 | }
1065 |
1066 | // EachInt16 calls the specified callback for each object
1067 | // in the []int16.
1068 | //
1069 | // Panics if the object is the wrong type.
1070 | func (v *Value) EachInt16(callback func(int, int16) bool) *Value {
1071 |
1072 | for index, val := range v.MustInt16Slice() {
1073 | carryon := callback(index, val)
1074 | if carryon == false {
1075 | break
1076 | }
1077 | }
1078 |
1079 | return v
1080 |
1081 | }
1082 |
1083 | // WhereInt16 uses the specified decider function to select items
1084 | // from the []int16. The object contained in the result will contain
1085 | // only the selected items.
1086 | func (v *Value) WhereInt16(decider func(int, int16) bool) *Value {
1087 |
1088 | var selected []int16
1089 |
1090 | v.EachInt16(func(index int, val int16) bool {
1091 | shouldSelect := decider(index, val)
1092 | if shouldSelect == false {
1093 | selected = append(selected, val)
1094 | }
1095 | return true
1096 | })
1097 |
1098 | return &Value{data: selected}
1099 |
1100 | }
1101 |
1102 | // GroupInt16 uses the specified grouper function to group the items
1103 | // keyed by the return of the grouper. The object contained in the
1104 | // result will contain a map[string][]int16.
1105 | func (v *Value) GroupInt16(grouper func(int, int16) string) *Value {
1106 |
1107 | groups := make(map[string][]int16)
1108 |
1109 | v.EachInt16(func(index int, val int16) bool {
1110 | group := grouper(index, val)
1111 | if _, ok := groups[group]; !ok {
1112 | groups[group] = make([]int16, 0)
1113 | }
1114 | groups[group] = append(groups[group], val)
1115 | return true
1116 | })
1117 |
1118 | return &Value{data: groups}
1119 |
1120 | }
1121 |
1122 | // ReplaceInt16 uses the specified function to replace each int16s
1123 | // by iterating each item. The data in the returned result will be a
1124 | // []int16 containing the replaced items.
1125 | func (v *Value) ReplaceInt16(replacer func(int, int16) int16) *Value {
1126 |
1127 | arr := v.MustInt16Slice()
1128 | replaced := make([]int16, len(arr))
1129 |
1130 | v.EachInt16(func(index int, val int16) bool {
1131 | replaced[index] = replacer(index, val)
1132 | return true
1133 | })
1134 |
1135 | return &Value{data: replaced}
1136 |
1137 | }
1138 |
1139 | // CollectInt16 uses the specified collector function to collect a value
1140 | // for each of the int16s in the slice. The data returned will be a
1141 | // []interface{}.
1142 | func (v *Value) CollectInt16(collector func(int, int16) interface{}) *Value {
1143 |
1144 | arr := v.MustInt16Slice()
1145 | collected := make([]interface{}, len(arr))
1146 |
1147 | v.EachInt16(func(index int, val int16) bool {
1148 | collected[index] = collector(index, val)
1149 | return true
1150 | })
1151 |
1152 | return &Value{data: collected}
1153 | }
1154 |
1155 | /*
1156 | Int32 (int32 and []int32)
1157 | --------------------------------------------------
1158 | */
1159 |
1160 | // Int32 gets the value as a int32, returns the optionalDefault
1161 | // value or a system default object if the value is the wrong type.
1162 | func (v *Value) Int32(optionalDefault ...int32) int32 {
1163 | if s, ok := v.data.(int32); ok {
1164 | return s
1165 | }
1166 | if len(optionalDefault) == 1 {
1167 | return optionalDefault[0]
1168 | }
1169 | return 0
1170 | }
1171 |
1172 | // MustInt32 gets the value as a int32.
1173 | //
1174 | // Panics if the object is not a int32.
1175 | func (v *Value) MustInt32() int32 {
1176 | return v.data.(int32)
1177 | }
1178 |
1179 | // Int32Slice gets the value as a []int32, returns the optionalDefault
1180 | // value or nil if the value is not a []int32.
1181 | func (v *Value) Int32Slice(optionalDefault ...[]int32) []int32 {
1182 | if s, ok := v.data.([]int32); ok {
1183 | return s
1184 | }
1185 | if len(optionalDefault) == 1 {
1186 | return optionalDefault[0]
1187 | }
1188 | return nil
1189 | }
1190 |
1191 | // MustInt32Slice gets the value as a []int32.
1192 | //
1193 | // Panics if the object is not a []int32.
1194 | func (v *Value) MustInt32Slice() []int32 {
1195 | return v.data.([]int32)
1196 | }
1197 |
1198 | // IsInt32 gets whether the object contained is a int32 or not.
1199 | func (v *Value) IsInt32() bool {
1200 | _, ok := v.data.(int32)
1201 | return ok
1202 | }
1203 |
1204 | // IsInt32Slice gets whether the object contained is a []int32 or not.
1205 | func (v *Value) IsInt32Slice() bool {
1206 | _, ok := v.data.([]int32)
1207 | return ok
1208 | }
1209 |
1210 | // EachInt32 calls the specified callback for each object
1211 | // in the []int32.
1212 | //
1213 | // Panics if the object is the wrong type.
1214 | func (v *Value) EachInt32(callback func(int, int32) bool) *Value {
1215 |
1216 | for index, val := range v.MustInt32Slice() {
1217 | carryon := callback(index, val)
1218 | if carryon == false {
1219 | break
1220 | }
1221 | }
1222 |
1223 | return v
1224 |
1225 | }
1226 |
1227 | // WhereInt32 uses the specified decider function to select items
1228 | // from the []int32. The object contained in the result will contain
1229 | // only the selected items.
1230 | func (v *Value) WhereInt32(decider func(int, int32) bool) *Value {
1231 |
1232 | var selected []int32
1233 |
1234 | v.EachInt32(func(index int, val int32) bool {
1235 | shouldSelect := decider(index, val)
1236 | if shouldSelect == false {
1237 | selected = append(selected, val)
1238 | }
1239 | return true
1240 | })
1241 |
1242 | return &Value{data: selected}
1243 |
1244 | }
1245 |
1246 | // GroupInt32 uses the specified grouper function to group the items
1247 | // keyed by the return of the grouper. The object contained in the
1248 | // result will contain a map[string][]int32.
1249 | func (v *Value) GroupInt32(grouper func(int, int32) string) *Value {
1250 |
1251 | groups := make(map[string][]int32)
1252 |
1253 | v.EachInt32(func(index int, val int32) bool {
1254 | group := grouper(index, val)
1255 | if _, ok := groups[group]; !ok {
1256 | groups[group] = make([]int32, 0)
1257 | }
1258 | groups[group] = append(groups[group], val)
1259 | return true
1260 | })
1261 |
1262 | return &Value{data: groups}
1263 |
1264 | }
1265 |
1266 | // ReplaceInt32 uses the specified function to replace each int32s
1267 | // by iterating each item. The data in the returned result will be a
1268 | // []int32 containing the replaced items.
1269 | func (v *Value) ReplaceInt32(replacer func(int, int32) int32) *Value {
1270 |
1271 | arr := v.MustInt32Slice()
1272 | replaced := make([]int32, len(arr))
1273 |
1274 | v.EachInt32(func(index int, val int32) bool {
1275 | replaced[index] = replacer(index, val)
1276 | return true
1277 | })
1278 |
1279 | return &Value{data: replaced}
1280 |
1281 | }
1282 |
1283 | // CollectInt32 uses the specified collector function to collect a value
1284 | // for each of the int32s in the slice. The data returned will be a
1285 | // []interface{}.
1286 | func (v *Value) CollectInt32(collector func(int, int32) interface{}) *Value {
1287 |
1288 | arr := v.MustInt32Slice()
1289 | collected := make([]interface{}, len(arr))
1290 |
1291 | v.EachInt32(func(index int, val int32) bool {
1292 | collected[index] = collector(index, val)
1293 | return true
1294 | })
1295 |
1296 | return &Value{data: collected}
1297 | }
1298 |
1299 | /*
1300 | Int64 (int64 and []int64)
1301 | --------------------------------------------------
1302 | */
1303 |
1304 | // Int64 gets the value as a int64, returns the optionalDefault
1305 | // value or a system default object if the value is the wrong type.
1306 | func (v *Value) Int64(optionalDefault ...int64) int64 {
1307 | if s, ok := v.data.(int64); ok {
1308 | return s
1309 | }
1310 | if len(optionalDefault) == 1 {
1311 | return optionalDefault[0]
1312 | }
1313 | return 0
1314 | }
1315 |
1316 | // MustInt64 gets the value as a int64.
1317 | //
1318 | // Panics if the object is not a int64.
1319 | func (v *Value) MustInt64() int64 {
1320 | return v.data.(int64)
1321 | }
1322 |
1323 | // Int64Slice gets the value as a []int64, returns the optionalDefault
1324 | // value or nil if the value is not a []int64.
1325 | func (v *Value) Int64Slice(optionalDefault ...[]int64) []int64 {
1326 | if s, ok := v.data.([]int64); ok {
1327 | return s
1328 | }
1329 | if len(optionalDefault) == 1 {
1330 | return optionalDefault[0]
1331 | }
1332 | return nil
1333 | }
1334 |
1335 | // MustInt64Slice gets the value as a []int64.
1336 | //
1337 | // Panics if the object is not a []int64.
1338 | func (v *Value) MustInt64Slice() []int64 {
1339 | return v.data.([]int64)
1340 | }
1341 |
1342 | // IsInt64 gets whether the object contained is a int64 or not.
1343 | func (v *Value) IsInt64() bool {
1344 | _, ok := v.data.(int64)
1345 | return ok
1346 | }
1347 |
1348 | // IsInt64Slice gets whether the object contained is a []int64 or not.
1349 | func (v *Value) IsInt64Slice() bool {
1350 | _, ok := v.data.([]int64)
1351 | return ok
1352 | }
1353 |
1354 | // EachInt64 calls the specified callback for each object
1355 | // in the []int64.
1356 | //
1357 | // Panics if the object is the wrong type.
1358 | func (v *Value) EachInt64(callback func(int, int64) bool) *Value {
1359 |
1360 | for index, val := range v.MustInt64Slice() {
1361 | carryon := callback(index, val)
1362 | if carryon == false {
1363 | break
1364 | }
1365 | }
1366 |
1367 | return v
1368 |
1369 | }
1370 |
1371 | // WhereInt64 uses the specified decider function to select items
1372 | // from the []int64. The object contained in the result will contain
1373 | // only the selected items.
1374 | func (v *Value) WhereInt64(decider func(int, int64) bool) *Value {
1375 |
1376 | var selected []int64
1377 |
1378 | v.EachInt64(func(index int, val int64) bool {
1379 | shouldSelect := decider(index, val)
1380 | if shouldSelect == false {
1381 | selected = append(selected, val)
1382 | }
1383 | return true
1384 | })
1385 |
1386 | return &Value{data: selected}
1387 |
1388 | }
1389 |
1390 | // GroupInt64 uses the specified grouper function to group the items
1391 | // keyed by the return of the grouper. The object contained in the
1392 | // result will contain a map[string][]int64.
1393 | func (v *Value) GroupInt64(grouper func(int, int64) string) *Value {
1394 |
1395 | groups := make(map[string][]int64)
1396 |
1397 | v.EachInt64(func(index int, val int64) bool {
1398 | group := grouper(index, val)
1399 | if _, ok := groups[group]; !ok {
1400 | groups[group] = make([]int64, 0)
1401 | }
1402 | groups[group] = append(groups[group], val)
1403 | return true
1404 | })
1405 |
1406 | return &Value{data: groups}
1407 |
1408 | }
1409 |
1410 | // ReplaceInt64 uses the specified function to replace each int64s
1411 | // by iterating each item. The data in the returned result will be a
1412 | // []int64 containing the replaced items.
1413 | func (v *Value) ReplaceInt64(replacer func(int, int64) int64) *Value {
1414 |
1415 | arr := v.MustInt64Slice()
1416 | replaced := make([]int64, len(arr))
1417 |
1418 | v.EachInt64(func(index int, val int64) bool {
1419 | replaced[index] = replacer(index, val)
1420 | return true
1421 | })
1422 |
1423 | return &Value{data: replaced}
1424 |
1425 | }
1426 |
1427 | // CollectInt64 uses the specified collector function to collect a value
1428 | // for each of the int64s in the slice. The data returned will be a
1429 | // []interface{}.
1430 | func (v *Value) CollectInt64(collector func(int, int64) interface{}) *Value {
1431 |
1432 | arr := v.MustInt64Slice()
1433 | collected := make([]interface{}, len(arr))
1434 |
1435 | v.EachInt64(func(index int, val int64) bool {
1436 | collected[index] = collector(index, val)
1437 | return true
1438 | })
1439 |
1440 | return &Value{data: collected}
1441 | }
1442 |
1443 | /*
1444 | Uint (uint and []uint)
1445 | --------------------------------------------------
1446 | */
1447 |
1448 | // Uint gets the value as a uint, returns the optionalDefault
1449 | // value or a system default object if the value is the wrong type.
1450 | func (v *Value) Uint(optionalDefault ...uint) uint {
1451 | if s, ok := v.data.(uint); ok {
1452 | return s
1453 | }
1454 | if len(optionalDefault) == 1 {
1455 | return optionalDefault[0]
1456 | }
1457 | return 0
1458 | }
1459 |
1460 | // MustUint gets the value as a uint.
1461 | //
1462 | // Panics if the object is not a uint.
1463 | func (v *Value) MustUint() uint {
1464 | return v.data.(uint)
1465 | }
1466 |
1467 | // UintSlice gets the value as a []uint, returns the optionalDefault
1468 | // value or nil if the value is not a []uint.
1469 | func (v *Value) UintSlice(optionalDefault ...[]uint) []uint {
1470 | if s, ok := v.data.([]uint); ok {
1471 | return s
1472 | }
1473 | if len(optionalDefault) == 1 {
1474 | return optionalDefault[0]
1475 | }
1476 | return nil
1477 | }
1478 |
1479 | // MustUintSlice gets the value as a []uint.
1480 | //
1481 | // Panics if the object is not a []uint.
1482 | func (v *Value) MustUintSlice() []uint {
1483 | return v.data.([]uint)
1484 | }
1485 |
1486 | // IsUint gets whether the object contained is a uint or not.
1487 | func (v *Value) IsUint() bool {
1488 | _, ok := v.data.(uint)
1489 | return ok
1490 | }
1491 |
1492 | // IsUintSlice gets whether the object contained is a []uint or not.
1493 | func (v *Value) IsUintSlice() bool {
1494 | _, ok := v.data.([]uint)
1495 | return ok
1496 | }
1497 |
1498 | // EachUint calls the specified callback for each object
1499 | // in the []uint.
1500 | //
1501 | // Panics if the object is the wrong type.
1502 | func (v *Value) EachUint(callback func(int, uint) bool) *Value {
1503 |
1504 | for index, val := range v.MustUintSlice() {
1505 | carryon := callback(index, val)
1506 | if carryon == false {
1507 | break
1508 | }
1509 | }
1510 |
1511 | return v
1512 |
1513 | }
1514 |
1515 | // WhereUint uses the specified decider function to select items
1516 | // from the []uint. The object contained in the result will contain
1517 | // only the selected items.
1518 | func (v *Value) WhereUint(decider func(int, uint) bool) *Value {
1519 |
1520 | var selected []uint
1521 |
1522 | v.EachUint(func(index int, val uint) bool {
1523 | shouldSelect := decider(index, val)
1524 | if shouldSelect == false {
1525 | selected = append(selected, val)
1526 | }
1527 | return true
1528 | })
1529 |
1530 | return &Value{data: selected}
1531 |
1532 | }
1533 |
1534 | // GroupUint uses the specified grouper function to group the items
1535 | // keyed by the return of the grouper. The object contained in the
1536 | // result will contain a map[string][]uint.
1537 | func (v *Value) GroupUint(grouper func(int, uint) string) *Value {
1538 |
1539 | groups := make(map[string][]uint)
1540 |
1541 | v.EachUint(func(index int, val uint) bool {
1542 | group := grouper(index, val)
1543 | if _, ok := groups[group]; !ok {
1544 | groups[group] = make([]uint, 0)
1545 | }
1546 | groups[group] = append(groups[group], val)
1547 | return true
1548 | })
1549 |
1550 | return &Value{data: groups}
1551 |
1552 | }
1553 |
1554 | // ReplaceUint uses the specified function to replace each uints
1555 | // by iterating each item. The data in the returned result will be a
1556 | // []uint containing the replaced items.
1557 | func (v *Value) ReplaceUint(replacer func(int, uint) uint) *Value {
1558 |
1559 | arr := v.MustUintSlice()
1560 | replaced := make([]uint, len(arr))
1561 |
1562 | v.EachUint(func(index int, val uint) bool {
1563 | replaced[index] = replacer(index, val)
1564 | return true
1565 | })
1566 |
1567 | return &Value{data: replaced}
1568 |
1569 | }
1570 |
1571 | // CollectUint uses the specified collector function to collect a value
1572 | // for each of the uints in the slice. The data returned will be a
1573 | // []interface{}.
1574 | func (v *Value) CollectUint(collector func(int, uint) interface{}) *Value {
1575 |
1576 | arr := v.MustUintSlice()
1577 | collected := make([]interface{}, len(arr))
1578 |
1579 | v.EachUint(func(index int, val uint) bool {
1580 | collected[index] = collector(index, val)
1581 | return true
1582 | })
1583 |
1584 | return &Value{data: collected}
1585 | }
1586 |
1587 | /*
1588 | Uint8 (uint8 and []uint8)
1589 | --------------------------------------------------
1590 | */
1591 |
1592 | // Uint8 gets the value as a uint8, returns the optionalDefault
1593 | // value or a system default object if the value is the wrong type.
1594 | func (v *Value) Uint8(optionalDefault ...uint8) uint8 {
1595 | if s, ok := v.data.(uint8); ok {
1596 | return s
1597 | }
1598 | if len(optionalDefault) == 1 {
1599 | return optionalDefault[0]
1600 | }
1601 | return 0
1602 | }
1603 |
1604 | // MustUint8 gets the value as a uint8.
1605 | //
1606 | // Panics if the object is not a uint8.
1607 | func (v *Value) MustUint8() uint8 {
1608 | return v.data.(uint8)
1609 | }
1610 |
1611 | // Uint8Slice gets the value as a []uint8, returns the optionalDefault
1612 | // value or nil if the value is not a []uint8.
1613 | func (v *Value) Uint8Slice(optionalDefault ...[]uint8) []uint8 {
1614 | if s, ok := v.data.([]uint8); ok {
1615 | return s
1616 | }
1617 | if len(optionalDefault) == 1 {
1618 | return optionalDefault[0]
1619 | }
1620 | return nil
1621 | }
1622 |
1623 | // MustUint8Slice gets the value as a []uint8.
1624 | //
1625 | // Panics if the object is not a []uint8.
1626 | func (v *Value) MustUint8Slice() []uint8 {
1627 | return v.data.([]uint8)
1628 | }
1629 |
1630 | // IsUint8 gets whether the object contained is a uint8 or not.
1631 | func (v *Value) IsUint8() bool {
1632 | _, ok := v.data.(uint8)
1633 | return ok
1634 | }
1635 |
1636 | // IsUint8Slice gets whether the object contained is a []uint8 or not.
1637 | func (v *Value) IsUint8Slice() bool {
1638 | _, ok := v.data.([]uint8)
1639 | return ok
1640 | }
1641 |
1642 | // EachUint8 calls the specified callback for each object
1643 | // in the []uint8.
1644 | //
1645 | // Panics if the object is the wrong type.
1646 | func (v *Value) EachUint8(callback func(int, uint8) bool) *Value {
1647 |
1648 | for index, val := range v.MustUint8Slice() {
1649 | carryon := callback(index, val)
1650 | if carryon == false {
1651 | break
1652 | }
1653 | }
1654 |
1655 | return v
1656 |
1657 | }
1658 |
1659 | // WhereUint8 uses the specified decider function to select items
1660 | // from the []uint8. The object contained in the result will contain
1661 | // only the selected items.
1662 | func (v *Value) WhereUint8(decider func(int, uint8) bool) *Value {
1663 |
1664 | var selected []uint8
1665 |
1666 | v.EachUint8(func(index int, val uint8) bool {
1667 | shouldSelect := decider(index, val)
1668 | if shouldSelect == false {
1669 | selected = append(selected, val)
1670 | }
1671 | return true
1672 | })
1673 |
1674 | return &Value{data: selected}
1675 |
1676 | }
1677 |
1678 | // GroupUint8 uses the specified grouper function to group the items
1679 | // keyed by the return of the grouper. The object contained in the
1680 | // result will contain a map[string][]uint8.
1681 | func (v *Value) GroupUint8(grouper func(int, uint8) string) *Value {
1682 |
1683 | groups := make(map[string][]uint8)
1684 |
1685 | v.EachUint8(func(index int, val uint8) bool {
1686 | group := grouper(index, val)
1687 | if _, ok := groups[group]; !ok {
1688 | groups[group] = make([]uint8, 0)
1689 | }
1690 | groups[group] = append(groups[group], val)
1691 | return true
1692 | })
1693 |
1694 | return &Value{data: groups}
1695 |
1696 | }
1697 |
1698 | // ReplaceUint8 uses the specified function to replace each uint8s
1699 | // by iterating each item. The data in the returned result will be a
1700 | // []uint8 containing the replaced items.
1701 | func (v *Value) ReplaceUint8(replacer func(int, uint8) uint8) *Value {
1702 |
1703 | arr := v.MustUint8Slice()
1704 | replaced := make([]uint8, len(arr))
1705 |
1706 | v.EachUint8(func(index int, val uint8) bool {
1707 | replaced[index] = replacer(index, val)
1708 | return true
1709 | })
1710 |
1711 | return &Value{data: replaced}
1712 |
1713 | }
1714 |
1715 | // CollectUint8 uses the specified collector function to collect a value
1716 | // for each of the uint8s in the slice. The data returned will be a
1717 | // []interface{}.
1718 | func (v *Value) CollectUint8(collector func(int, uint8) interface{}) *Value {
1719 |
1720 | arr := v.MustUint8Slice()
1721 | collected := make([]interface{}, len(arr))
1722 |
1723 | v.EachUint8(func(index int, val uint8) bool {
1724 | collected[index] = collector(index, val)
1725 | return true
1726 | })
1727 |
1728 | return &Value{data: collected}
1729 | }
1730 |
1731 | /*
1732 | Uint16 (uint16 and []uint16)
1733 | --------------------------------------------------
1734 | */
1735 |
1736 | // Uint16 gets the value as a uint16, returns the optionalDefault
1737 | // value or a system default object if the value is the wrong type.
1738 | func (v *Value) Uint16(optionalDefault ...uint16) uint16 {
1739 | if s, ok := v.data.(uint16); ok {
1740 | return s
1741 | }
1742 | if len(optionalDefault) == 1 {
1743 | return optionalDefault[0]
1744 | }
1745 | return 0
1746 | }
1747 |
1748 | // MustUint16 gets the value as a uint16.
1749 | //
1750 | // Panics if the object is not a uint16.
1751 | func (v *Value) MustUint16() uint16 {
1752 | return v.data.(uint16)
1753 | }
1754 |
1755 | // Uint16Slice gets the value as a []uint16, returns the optionalDefault
1756 | // value or nil if the value is not a []uint16.
1757 | func (v *Value) Uint16Slice(optionalDefault ...[]uint16) []uint16 {
1758 | if s, ok := v.data.([]uint16); ok {
1759 | return s
1760 | }
1761 | if len(optionalDefault) == 1 {
1762 | return optionalDefault[0]
1763 | }
1764 | return nil
1765 | }
1766 |
1767 | // MustUint16Slice gets the value as a []uint16.
1768 | //
1769 | // Panics if the object is not a []uint16.
1770 | func (v *Value) MustUint16Slice() []uint16 {
1771 | return v.data.([]uint16)
1772 | }
1773 |
1774 | // IsUint16 gets whether the object contained is a uint16 or not.
1775 | func (v *Value) IsUint16() bool {
1776 | _, ok := v.data.(uint16)
1777 | return ok
1778 | }
1779 |
1780 | // IsUint16Slice gets whether the object contained is a []uint16 or not.
1781 | func (v *Value) IsUint16Slice() bool {
1782 | _, ok := v.data.([]uint16)
1783 | return ok
1784 | }
1785 |
1786 | // EachUint16 calls the specified callback for each object
1787 | // in the []uint16.
1788 | //
1789 | // Panics if the object is the wrong type.
1790 | func (v *Value) EachUint16(callback func(int, uint16) bool) *Value {
1791 |
1792 | for index, val := range v.MustUint16Slice() {
1793 | carryon := callback(index, val)
1794 | if carryon == false {
1795 | break
1796 | }
1797 | }
1798 |
1799 | return v
1800 |
1801 | }
1802 |
1803 | // WhereUint16 uses the specified decider function to select items
1804 | // from the []uint16. The object contained in the result will contain
1805 | // only the selected items.
1806 | func (v *Value) WhereUint16(decider func(int, uint16) bool) *Value {
1807 |
1808 | var selected []uint16
1809 |
1810 | v.EachUint16(func(index int, val uint16) bool {
1811 | shouldSelect := decider(index, val)
1812 | if shouldSelect == false {
1813 | selected = append(selected, val)
1814 | }
1815 | return true
1816 | })
1817 |
1818 | return &Value{data: selected}
1819 |
1820 | }
1821 |
1822 | // GroupUint16 uses the specified grouper function to group the items
1823 | // keyed by the return of the grouper. The object contained in the
1824 | // result will contain a map[string][]uint16.
1825 | func (v *Value) GroupUint16(grouper func(int, uint16) string) *Value {
1826 |
1827 | groups := make(map[string][]uint16)
1828 |
1829 | v.EachUint16(func(index int, val uint16) bool {
1830 | group := grouper(index, val)
1831 | if _, ok := groups[group]; !ok {
1832 | groups[group] = make([]uint16, 0)
1833 | }
1834 | groups[group] = append(groups[group], val)
1835 | return true
1836 | })
1837 |
1838 | return &Value{data: groups}
1839 |
1840 | }
1841 |
1842 | // ReplaceUint16 uses the specified function to replace each uint16s
1843 | // by iterating each item. The data in the returned result will be a
1844 | // []uint16 containing the replaced items.
1845 | func (v *Value) ReplaceUint16(replacer func(int, uint16) uint16) *Value {
1846 |
1847 | arr := v.MustUint16Slice()
1848 | replaced := make([]uint16, len(arr))
1849 |
1850 | v.EachUint16(func(index int, val uint16) bool {
1851 | replaced[index] = replacer(index, val)
1852 | return true
1853 | })
1854 |
1855 | return &Value{data: replaced}
1856 |
1857 | }
1858 |
1859 | // CollectUint16 uses the specified collector function to collect a value
1860 | // for each of the uint16s in the slice. The data returned will be a
1861 | // []interface{}.
1862 | func (v *Value) CollectUint16(collector func(int, uint16) interface{}) *Value {
1863 |
1864 | arr := v.MustUint16Slice()
1865 | collected := make([]interface{}, len(arr))
1866 |
1867 | v.EachUint16(func(index int, val uint16) bool {
1868 | collected[index] = collector(index, val)
1869 | return true
1870 | })
1871 |
1872 | return &Value{data: collected}
1873 | }
1874 |
1875 | /*
1876 | Uint32 (uint32 and []uint32)
1877 | --------------------------------------------------
1878 | */
1879 |
1880 | // Uint32 gets the value as a uint32, returns the optionalDefault
1881 | // value or a system default object if the value is the wrong type.
1882 | func (v *Value) Uint32(optionalDefault ...uint32) uint32 {
1883 | if s, ok := v.data.(uint32); ok {
1884 | return s
1885 | }
1886 | if len(optionalDefault) == 1 {
1887 | return optionalDefault[0]
1888 | }
1889 | return 0
1890 | }
1891 |
1892 | // MustUint32 gets the value as a uint32.
1893 | //
1894 | // Panics if the object is not a uint32.
1895 | func (v *Value) MustUint32() uint32 {
1896 | return v.data.(uint32)
1897 | }
1898 |
1899 | // Uint32Slice gets the value as a []uint32, returns the optionalDefault
1900 | // value or nil if the value is not a []uint32.
1901 | func (v *Value) Uint32Slice(optionalDefault ...[]uint32) []uint32 {
1902 | if s, ok := v.data.([]uint32); ok {
1903 | return s
1904 | }
1905 | if len(optionalDefault) == 1 {
1906 | return optionalDefault[0]
1907 | }
1908 | return nil
1909 | }
1910 |
1911 | // MustUint32Slice gets the value as a []uint32.
1912 | //
1913 | // Panics if the object is not a []uint32.
1914 | func (v *Value) MustUint32Slice() []uint32 {
1915 | return v.data.([]uint32)
1916 | }
1917 |
1918 | // IsUint32 gets whether the object contained is a uint32 or not.
1919 | func (v *Value) IsUint32() bool {
1920 | _, ok := v.data.(uint32)
1921 | return ok
1922 | }
1923 |
1924 | // IsUint32Slice gets whether the object contained is a []uint32 or not.
1925 | func (v *Value) IsUint32Slice() bool {
1926 | _, ok := v.data.([]uint32)
1927 | return ok
1928 | }
1929 |
1930 | // EachUint32 calls the specified callback for each object
1931 | // in the []uint32.
1932 | //
1933 | // Panics if the object is the wrong type.
1934 | func (v *Value) EachUint32(callback func(int, uint32) bool) *Value {
1935 |
1936 | for index, val := range v.MustUint32Slice() {
1937 | carryon := callback(index, val)
1938 | if carryon == false {
1939 | break
1940 | }
1941 | }
1942 |
1943 | return v
1944 |
1945 | }
1946 |
1947 | // WhereUint32 uses the specified decider function to select items
1948 | // from the []uint32. The object contained in the result will contain
1949 | // only the selected items.
1950 | func (v *Value) WhereUint32(decider func(int, uint32) bool) *Value {
1951 |
1952 | var selected []uint32
1953 |
1954 | v.EachUint32(func(index int, val uint32) bool {
1955 | shouldSelect := decider(index, val)
1956 | if shouldSelect == false {
1957 | selected = append(selected, val)
1958 | }
1959 | return true
1960 | })
1961 |
1962 | return &Value{data: selected}
1963 |
1964 | }
1965 |
1966 | // GroupUint32 uses the specified grouper function to group the items
1967 | // keyed by the return of the grouper. The object contained in the
1968 | // result will contain a map[string][]uint32.
1969 | func (v *Value) GroupUint32(grouper func(int, uint32) string) *Value {
1970 |
1971 | groups := make(map[string][]uint32)
1972 |
1973 | v.EachUint32(func(index int, val uint32) bool {
1974 | group := grouper(index, val)
1975 | if _, ok := groups[group]; !ok {
1976 | groups[group] = make([]uint32, 0)
1977 | }
1978 | groups[group] = append(groups[group], val)
1979 | return true
1980 | })
1981 |
1982 | return &Value{data: groups}
1983 |
1984 | }
1985 |
1986 | // ReplaceUint32 uses the specified function to replace each uint32s
1987 | // by iterating each item. The data in the returned result will be a
1988 | // []uint32 containing the replaced items.
1989 | func (v *Value) ReplaceUint32(replacer func(int, uint32) uint32) *Value {
1990 |
1991 | arr := v.MustUint32Slice()
1992 | replaced := make([]uint32, len(arr))
1993 |
1994 | v.EachUint32(func(index int, val uint32) bool {
1995 | replaced[index] = replacer(index, val)
1996 | return true
1997 | })
1998 |
1999 | return &Value{data: replaced}
2000 |
2001 | }
2002 |
2003 | // CollectUint32 uses the specified collector function to collect a value
2004 | // for each of the uint32s in the slice. The data returned will be a
2005 | // []interface{}.
2006 | func (v *Value) CollectUint32(collector func(int, uint32) interface{}) *Value {
2007 |
2008 | arr := v.MustUint32Slice()
2009 | collected := make([]interface{}, len(arr))
2010 |
2011 | v.EachUint32(func(index int, val uint32) bool {
2012 | collected[index] = collector(index, val)
2013 | return true
2014 | })
2015 |
2016 | return &Value{data: collected}
2017 | }
2018 |
2019 | /*
2020 | Uint64 (uint64 and []uint64)
2021 | --------------------------------------------------
2022 | */
2023 |
2024 | // Uint64 gets the value as a uint64, returns the optionalDefault
2025 | // value or a system default object if the value is the wrong type.
2026 | func (v *Value) Uint64(optionalDefault ...uint64) uint64 {
2027 | if s, ok := v.data.(uint64); ok {
2028 | return s
2029 | }
2030 | if len(optionalDefault) == 1 {
2031 | return optionalDefault[0]
2032 | }
2033 | return 0
2034 | }
2035 |
2036 | // MustUint64 gets the value as a uint64.
2037 | //
2038 | // Panics if the object is not a uint64.
2039 | func (v *Value) MustUint64() uint64 {
2040 | return v.data.(uint64)
2041 | }
2042 |
2043 | // Uint64Slice gets the value as a []uint64, returns the optionalDefault
2044 | // value or nil if the value is not a []uint64.
2045 | func (v *Value) Uint64Slice(optionalDefault ...[]uint64) []uint64 {
2046 | if s, ok := v.data.([]uint64); ok {
2047 | return s
2048 | }
2049 | if len(optionalDefault) == 1 {
2050 | return optionalDefault[0]
2051 | }
2052 | return nil
2053 | }
2054 |
2055 | // MustUint64Slice gets the value as a []uint64.
2056 | //
2057 | // Panics if the object is not a []uint64.
2058 | func (v *Value) MustUint64Slice() []uint64 {
2059 | return v.data.([]uint64)
2060 | }
2061 |
2062 | // IsUint64 gets whether the object contained is a uint64 or not.
2063 | func (v *Value) IsUint64() bool {
2064 | _, ok := v.data.(uint64)
2065 | return ok
2066 | }
2067 |
2068 | // IsUint64Slice gets whether the object contained is a []uint64 or not.
2069 | func (v *Value) IsUint64Slice() bool {
2070 | _, ok := v.data.([]uint64)
2071 | return ok
2072 | }
2073 |
2074 | // EachUint64 calls the specified callback for each object
2075 | // in the []uint64.
2076 | //
2077 | // Panics if the object is the wrong type.
2078 | func (v *Value) EachUint64(callback func(int, uint64) bool) *Value {
2079 |
2080 | for index, val := range v.MustUint64Slice() {
2081 | carryon := callback(index, val)
2082 | if carryon == false {
2083 | break
2084 | }
2085 | }
2086 |
2087 | return v
2088 |
2089 | }
2090 |
2091 | // WhereUint64 uses the specified decider function to select items
2092 | // from the []uint64. The object contained in the result will contain
2093 | // only the selected items.
2094 | func (v *Value) WhereUint64(decider func(int, uint64) bool) *Value {
2095 |
2096 | var selected []uint64
2097 |
2098 | v.EachUint64(func(index int, val uint64) bool {
2099 | shouldSelect := decider(index, val)
2100 | if shouldSelect == false {
2101 | selected = append(selected, val)
2102 | }
2103 | return true
2104 | })
2105 |
2106 | return &Value{data: selected}
2107 |
2108 | }
2109 |
2110 | // GroupUint64 uses the specified grouper function to group the items
2111 | // keyed by the return of the grouper. The object contained in the
2112 | // result will contain a map[string][]uint64.
2113 | func (v *Value) GroupUint64(grouper func(int, uint64) string) *Value {
2114 |
2115 | groups := make(map[string][]uint64)
2116 |
2117 | v.EachUint64(func(index int, val uint64) bool {
2118 | group := grouper(index, val)
2119 | if _, ok := groups[group]; !ok {
2120 | groups[group] = make([]uint64, 0)
2121 | }
2122 | groups[group] = append(groups[group], val)
2123 | return true
2124 | })
2125 |
2126 | return &Value{data: groups}
2127 |
2128 | }
2129 |
2130 | // ReplaceUint64 uses the specified function to replace each uint64s
2131 | // by iterating each item. The data in the returned result will be a
2132 | // []uint64 containing the replaced items.
2133 | func (v *Value) ReplaceUint64(replacer func(int, uint64) uint64) *Value {
2134 |
2135 | arr := v.MustUint64Slice()
2136 | replaced := make([]uint64, len(arr))
2137 |
2138 | v.EachUint64(func(index int, val uint64) bool {
2139 | replaced[index] = replacer(index, val)
2140 | return true
2141 | })
2142 |
2143 | return &Value{data: replaced}
2144 |
2145 | }
2146 |
2147 | // CollectUint64 uses the specified collector function to collect a value
2148 | // for each of the uint64s in the slice. The data returned will be a
2149 | // []interface{}.
2150 | func (v *Value) CollectUint64(collector func(int, uint64) interface{}) *Value {
2151 |
2152 | arr := v.MustUint64Slice()
2153 | collected := make([]interface{}, len(arr))
2154 |
2155 | v.EachUint64(func(index int, val uint64) bool {
2156 | collected[index] = collector(index, val)
2157 | return true
2158 | })
2159 |
2160 | return &Value{data: collected}
2161 | }
2162 |
2163 | /*
2164 | Uintptr (uintptr and []uintptr)
2165 | --------------------------------------------------
2166 | */
2167 |
2168 | // Uintptr gets the value as a uintptr, returns the optionalDefault
2169 | // value or a system default object if the value is the wrong type.
2170 | func (v *Value) Uintptr(optionalDefault ...uintptr) uintptr {
2171 | if s, ok := v.data.(uintptr); ok {
2172 | return s
2173 | }
2174 | if len(optionalDefault) == 1 {
2175 | return optionalDefault[0]
2176 | }
2177 | return 0
2178 | }
2179 |
2180 | // MustUintptr gets the value as a uintptr.
2181 | //
2182 | // Panics if the object is not a uintptr.
2183 | func (v *Value) MustUintptr() uintptr {
2184 | return v.data.(uintptr)
2185 | }
2186 |
2187 | // UintptrSlice gets the value as a []uintptr, returns the optionalDefault
2188 | // value or nil if the value is not a []uintptr.
2189 | func (v *Value) UintptrSlice(optionalDefault ...[]uintptr) []uintptr {
2190 | if s, ok := v.data.([]uintptr); ok {
2191 | return s
2192 | }
2193 | if len(optionalDefault) == 1 {
2194 | return optionalDefault[0]
2195 | }
2196 | return nil
2197 | }
2198 |
2199 | // MustUintptrSlice gets the value as a []uintptr.
2200 | //
2201 | // Panics if the object is not a []uintptr.
2202 | func (v *Value) MustUintptrSlice() []uintptr {
2203 | return v.data.([]uintptr)
2204 | }
2205 |
2206 | // IsUintptr gets whether the object contained is a uintptr or not.
2207 | func (v *Value) IsUintptr() bool {
2208 | _, ok := v.data.(uintptr)
2209 | return ok
2210 | }
2211 |
2212 | // IsUintptrSlice gets whether the object contained is a []uintptr or not.
2213 | func (v *Value) IsUintptrSlice() bool {
2214 | _, ok := v.data.([]uintptr)
2215 | return ok
2216 | }
2217 |
2218 | // EachUintptr calls the specified callback for each object
2219 | // in the []uintptr.
2220 | //
2221 | // Panics if the object is the wrong type.
2222 | func (v *Value) EachUintptr(callback func(int, uintptr) bool) *Value {
2223 |
2224 | for index, val := range v.MustUintptrSlice() {
2225 | carryon := callback(index, val)
2226 | if carryon == false {
2227 | break
2228 | }
2229 | }
2230 |
2231 | return v
2232 |
2233 | }
2234 |
2235 | // WhereUintptr uses the specified decider function to select items
2236 | // from the []uintptr. The object contained in the result will contain
2237 | // only the selected items.
2238 | func (v *Value) WhereUintptr(decider func(int, uintptr) bool) *Value {
2239 |
2240 | var selected []uintptr
2241 |
2242 | v.EachUintptr(func(index int, val uintptr) bool {
2243 | shouldSelect := decider(index, val)
2244 | if shouldSelect == false {
2245 | selected = append(selected, val)
2246 | }
2247 | return true
2248 | })
2249 |
2250 | return &Value{data: selected}
2251 |
2252 | }
2253 |
2254 | // GroupUintptr uses the specified grouper function to group the items
2255 | // keyed by the return of the grouper. The object contained in the
2256 | // result will contain a map[string][]uintptr.
2257 | func (v *Value) GroupUintptr(grouper func(int, uintptr) string) *Value {
2258 |
2259 | groups := make(map[string][]uintptr)
2260 |
2261 | v.EachUintptr(func(index int, val uintptr) bool {
2262 | group := grouper(index, val)
2263 | if _, ok := groups[group]; !ok {
2264 | groups[group] = make([]uintptr, 0)
2265 | }
2266 | groups[group] = append(groups[group], val)
2267 | return true
2268 | })
2269 |
2270 | return &Value{data: groups}
2271 |
2272 | }
2273 |
2274 | // ReplaceUintptr uses the specified function to replace each uintptrs
2275 | // by iterating each item. The data in the returned result will be a
2276 | // []uintptr containing the replaced items.
2277 | func (v *Value) ReplaceUintptr(replacer func(int, uintptr) uintptr) *Value {
2278 |
2279 | arr := v.MustUintptrSlice()
2280 | replaced := make([]uintptr, len(arr))
2281 |
2282 | v.EachUintptr(func(index int, val uintptr) bool {
2283 | replaced[index] = replacer(index, val)
2284 | return true
2285 | })
2286 |
2287 | return &Value{data: replaced}
2288 |
2289 | }
2290 |
2291 | // CollectUintptr uses the specified collector function to collect a value
2292 | // for each of the uintptrs in the slice. The data returned will be a
2293 | // []interface{}.
2294 | func (v *Value) CollectUintptr(collector func(int, uintptr) interface{}) *Value {
2295 |
2296 | arr := v.MustUintptrSlice()
2297 | collected := make([]interface{}, len(arr))
2298 |
2299 | v.EachUintptr(func(index int, val uintptr) bool {
2300 | collected[index] = collector(index, val)
2301 | return true
2302 | })
2303 |
2304 | return &Value{data: collected}
2305 | }
2306 |
2307 | /*
2308 | Float32 (float32 and []float32)
2309 | --------------------------------------------------
2310 | */
2311 |
2312 | // Float32 gets the value as a float32, returns the optionalDefault
2313 | // value or a system default object if the value is the wrong type.
2314 | func (v *Value) Float32(optionalDefault ...float32) float32 {
2315 | if s, ok := v.data.(float32); ok {
2316 | return s
2317 | }
2318 | if len(optionalDefault) == 1 {
2319 | return optionalDefault[0]
2320 | }
2321 | return 0
2322 | }
2323 |
2324 | // MustFloat32 gets the value as a float32.
2325 | //
2326 | // Panics if the object is not a float32.
2327 | func (v *Value) MustFloat32() float32 {
2328 | return v.data.(float32)
2329 | }
2330 |
2331 | // Float32Slice gets the value as a []float32, returns the optionalDefault
2332 | // value or nil if the value is not a []float32.
2333 | func (v *Value) Float32Slice(optionalDefault ...[]float32) []float32 {
2334 | if s, ok := v.data.([]float32); ok {
2335 | return s
2336 | }
2337 | if len(optionalDefault) == 1 {
2338 | return optionalDefault[0]
2339 | }
2340 | return nil
2341 | }
2342 |
2343 | // MustFloat32Slice gets the value as a []float32.
2344 | //
2345 | // Panics if the object is not a []float32.
2346 | func (v *Value) MustFloat32Slice() []float32 {
2347 | return v.data.([]float32)
2348 | }
2349 |
2350 | // IsFloat32 gets whether the object contained is a float32 or not.
2351 | func (v *Value) IsFloat32() bool {
2352 | _, ok := v.data.(float32)
2353 | return ok
2354 | }
2355 |
2356 | // IsFloat32Slice gets whether the object contained is a []float32 or not.
2357 | func (v *Value) IsFloat32Slice() bool {
2358 | _, ok := v.data.([]float32)
2359 | return ok
2360 | }
2361 |
2362 | // EachFloat32 calls the specified callback for each object
2363 | // in the []float32.
2364 | //
2365 | // Panics if the object is the wrong type.
2366 | func (v *Value) EachFloat32(callback func(int, float32) bool) *Value {
2367 |
2368 | for index, val := range v.MustFloat32Slice() {
2369 | carryon := callback(index, val)
2370 | if carryon == false {
2371 | break
2372 | }
2373 | }
2374 |
2375 | return v
2376 |
2377 | }
2378 |
2379 | // WhereFloat32 uses the specified decider function to select items
2380 | // from the []float32. The object contained in the result will contain
2381 | // only the selected items.
2382 | func (v *Value) WhereFloat32(decider func(int, float32) bool) *Value {
2383 |
2384 | var selected []float32
2385 |
2386 | v.EachFloat32(func(index int, val float32) bool {
2387 | shouldSelect := decider(index, val)
2388 | if shouldSelect == false {
2389 | selected = append(selected, val)
2390 | }
2391 | return true
2392 | })
2393 |
2394 | return &Value{data: selected}
2395 |
2396 | }
2397 |
2398 | // GroupFloat32 uses the specified grouper function to group the items
2399 | // keyed by the return of the grouper. The object contained in the
2400 | // result will contain a map[string][]float32.
2401 | func (v *Value) GroupFloat32(grouper func(int, float32) string) *Value {
2402 |
2403 | groups := make(map[string][]float32)
2404 |
2405 | v.EachFloat32(func(index int, val float32) bool {
2406 | group := grouper(index, val)
2407 | if _, ok := groups[group]; !ok {
2408 | groups[group] = make([]float32, 0)
2409 | }
2410 | groups[group] = append(groups[group], val)
2411 | return true
2412 | })
2413 |
2414 | return &Value{data: groups}
2415 |
2416 | }
2417 |
2418 | // ReplaceFloat32 uses the specified function to replace each float32s
2419 | // by iterating each item. The data in the returned result will be a
2420 | // []float32 containing the replaced items.
2421 | func (v *Value) ReplaceFloat32(replacer func(int, float32) float32) *Value {
2422 |
2423 | arr := v.MustFloat32Slice()
2424 | replaced := make([]float32, len(arr))
2425 |
2426 | v.EachFloat32(func(index int, val float32) bool {
2427 | replaced[index] = replacer(index, val)
2428 | return true
2429 | })
2430 |
2431 | return &Value{data: replaced}
2432 |
2433 | }
2434 |
2435 | // CollectFloat32 uses the specified collector function to collect a value
2436 | // for each of the float32s in the slice. The data returned will be a
2437 | // []interface{}.
2438 | func (v *Value) CollectFloat32(collector func(int, float32) interface{}) *Value {
2439 |
2440 | arr := v.MustFloat32Slice()
2441 | collected := make([]interface{}, len(arr))
2442 |
2443 | v.EachFloat32(func(index int, val float32) bool {
2444 | collected[index] = collector(index, val)
2445 | return true
2446 | })
2447 |
2448 | return &Value{data: collected}
2449 | }
2450 |
2451 | /*
2452 | Float64 (float64 and []float64)
2453 | --------------------------------------------------
2454 | */
2455 |
2456 | // Float64 gets the value as a float64, returns the optionalDefault
2457 | // value or a system default object if the value is the wrong type.
2458 | func (v *Value) Float64(optionalDefault ...float64) float64 {
2459 | if s, ok := v.data.(float64); ok {
2460 | return s
2461 | }
2462 | if len(optionalDefault) == 1 {
2463 | return optionalDefault[0]
2464 | }
2465 | return 0
2466 | }
2467 |
2468 | // MustFloat64 gets the value as a float64.
2469 | //
2470 | // Panics if the object is not a float64.
2471 | func (v *Value) MustFloat64() float64 {
2472 | return v.data.(float64)
2473 | }
2474 |
2475 | // Float64Slice gets the value as a []float64, returns the optionalDefault
2476 | // value or nil if the value is not a []float64.
2477 | func (v *Value) Float64Slice(optionalDefault ...[]float64) []float64 {
2478 | if s, ok := v.data.([]float64); ok {
2479 | return s
2480 | }
2481 | if len(optionalDefault) == 1 {
2482 | return optionalDefault[0]
2483 | }
2484 | return nil
2485 | }
2486 |
2487 | // MustFloat64Slice gets the value as a []float64.
2488 | //
2489 | // Panics if the object is not a []float64.
2490 | func (v *Value) MustFloat64Slice() []float64 {
2491 | return v.data.([]float64)
2492 | }
2493 |
2494 | // IsFloat64 gets whether the object contained is a float64 or not.
2495 | func (v *Value) IsFloat64() bool {
2496 | _, ok := v.data.(float64)
2497 | return ok
2498 | }
2499 |
2500 | // IsFloat64Slice gets whether the object contained is a []float64 or not.
2501 | func (v *Value) IsFloat64Slice() bool {
2502 | _, ok := v.data.([]float64)
2503 | return ok
2504 | }
2505 |
2506 | // EachFloat64 calls the specified callback for each object
2507 | // in the []float64.
2508 | //
2509 | // Panics if the object is the wrong type.
2510 | func (v *Value) EachFloat64(callback func(int, float64) bool) *Value {
2511 |
2512 | for index, val := range v.MustFloat64Slice() {
2513 | carryon := callback(index, val)
2514 | if carryon == false {
2515 | break
2516 | }
2517 | }
2518 |
2519 | return v
2520 |
2521 | }
2522 |
2523 | // WhereFloat64 uses the specified decider function to select items
2524 | // from the []float64. The object contained in the result will contain
2525 | // only the selected items.
2526 | func (v *Value) WhereFloat64(decider func(int, float64) bool) *Value {
2527 |
2528 | var selected []float64
2529 |
2530 | v.EachFloat64(func(index int, val float64) bool {
2531 | shouldSelect := decider(index, val)
2532 | if shouldSelect == false {
2533 | selected = append(selected, val)
2534 | }
2535 | return true
2536 | })
2537 |
2538 | return &Value{data: selected}
2539 |
2540 | }
2541 |
2542 | // GroupFloat64 uses the specified grouper function to group the items
2543 | // keyed by the return of the grouper. The object contained in the
2544 | // result will contain a map[string][]float64.
2545 | func (v *Value) GroupFloat64(grouper func(int, float64) string) *Value {
2546 |
2547 | groups := make(map[string][]float64)
2548 |
2549 | v.EachFloat64(func(index int, val float64) bool {
2550 | group := grouper(index, val)
2551 | if _, ok := groups[group]; !ok {
2552 | groups[group] = make([]float64, 0)
2553 | }
2554 | groups[group] = append(groups[group], val)
2555 | return true
2556 | })
2557 |
2558 | return &Value{data: groups}
2559 |
2560 | }
2561 |
2562 | // ReplaceFloat64 uses the specified function to replace each float64s
2563 | // by iterating each item. The data in the returned result will be a
2564 | // []float64 containing the replaced items.
2565 | func (v *Value) ReplaceFloat64(replacer func(int, float64) float64) *Value {
2566 |
2567 | arr := v.MustFloat64Slice()
2568 | replaced := make([]float64, len(arr))
2569 |
2570 | v.EachFloat64(func(index int, val float64) bool {
2571 | replaced[index] = replacer(index, val)
2572 | return true
2573 | })
2574 |
2575 | return &Value{data: replaced}
2576 |
2577 | }
2578 |
2579 | // CollectFloat64 uses the specified collector function to collect a value
2580 | // for each of the float64s in the slice. The data returned will be a
2581 | // []interface{}.
2582 | func (v *Value) CollectFloat64(collector func(int, float64) interface{}) *Value {
2583 |
2584 | arr := v.MustFloat64Slice()
2585 | collected := make([]interface{}, len(arr))
2586 |
2587 | v.EachFloat64(func(index int, val float64) bool {
2588 | collected[index] = collector(index, val)
2589 | return true
2590 | })
2591 |
2592 | return &Value{data: collected}
2593 | }
2594 |
2595 | /*
2596 | Complex64 (complex64 and []complex64)
2597 | --------------------------------------------------
2598 | */
2599 |
2600 | // Complex64 gets the value as a complex64, returns the optionalDefault
2601 | // value or a system default object if the value is the wrong type.
2602 | func (v *Value) Complex64(optionalDefault ...complex64) complex64 {
2603 | if s, ok := v.data.(complex64); ok {
2604 | return s
2605 | }
2606 | if len(optionalDefault) == 1 {
2607 | return optionalDefault[0]
2608 | }
2609 | return 0
2610 | }
2611 |
2612 | // MustComplex64 gets the value as a complex64.
2613 | //
2614 | // Panics if the object is not a complex64.
2615 | func (v *Value) MustComplex64() complex64 {
2616 | return v.data.(complex64)
2617 | }
2618 |
2619 | // Complex64Slice gets the value as a []complex64, returns the optionalDefault
2620 | // value or nil if the value is not a []complex64.
2621 | func (v *Value) Complex64Slice(optionalDefault ...[]complex64) []complex64 {
2622 | if s, ok := v.data.([]complex64); ok {
2623 | return s
2624 | }
2625 | if len(optionalDefault) == 1 {
2626 | return optionalDefault[0]
2627 | }
2628 | return nil
2629 | }
2630 |
2631 | // MustComplex64Slice gets the value as a []complex64.
2632 | //
2633 | // Panics if the object is not a []complex64.
2634 | func (v *Value) MustComplex64Slice() []complex64 {
2635 | return v.data.([]complex64)
2636 | }
2637 |
2638 | // IsComplex64 gets whether the object contained is a complex64 or not.
2639 | func (v *Value) IsComplex64() bool {
2640 | _, ok := v.data.(complex64)
2641 | return ok
2642 | }
2643 |
2644 | // IsComplex64Slice gets whether the object contained is a []complex64 or not.
2645 | func (v *Value) IsComplex64Slice() bool {
2646 | _, ok := v.data.([]complex64)
2647 | return ok
2648 | }
2649 |
2650 | // EachComplex64 calls the specified callback for each object
2651 | // in the []complex64.
2652 | //
2653 | // Panics if the object is the wrong type.
2654 | func (v *Value) EachComplex64(callback func(int, complex64) bool) *Value {
2655 |
2656 | for index, val := range v.MustComplex64Slice() {
2657 | carryon := callback(index, val)
2658 | if carryon == false {
2659 | break
2660 | }
2661 | }
2662 |
2663 | return v
2664 |
2665 | }
2666 |
2667 | // WhereComplex64 uses the specified decider function to select items
2668 | // from the []complex64. The object contained in the result will contain
2669 | // only the selected items.
2670 | func (v *Value) WhereComplex64(decider func(int, complex64) bool) *Value {
2671 |
2672 | var selected []complex64
2673 |
2674 | v.EachComplex64(func(index int, val complex64) bool {
2675 | shouldSelect := decider(index, val)
2676 | if shouldSelect == false {
2677 | selected = append(selected, val)
2678 | }
2679 | return true
2680 | })
2681 |
2682 | return &Value{data: selected}
2683 |
2684 | }
2685 |
2686 | // GroupComplex64 uses the specified grouper function to group the items
2687 | // keyed by the return of the grouper. The object contained in the
2688 | // result will contain a map[string][]complex64.
2689 | func (v *Value) GroupComplex64(grouper func(int, complex64) string) *Value {
2690 |
2691 | groups := make(map[string][]complex64)
2692 |
2693 | v.EachComplex64(func(index int, val complex64) bool {
2694 | group := grouper(index, val)
2695 | if _, ok := groups[group]; !ok {
2696 | groups[group] = make([]complex64, 0)
2697 | }
2698 | groups[group] = append(groups[group], val)
2699 | return true
2700 | })
2701 |
2702 | return &Value{data: groups}
2703 |
2704 | }
2705 |
2706 | // ReplaceComplex64 uses the specified function to replace each complex64s
2707 | // by iterating each item. The data in the returned result will be a
2708 | // []complex64 containing the replaced items.
2709 | func (v *Value) ReplaceComplex64(replacer func(int, complex64) complex64) *Value {
2710 |
2711 | arr := v.MustComplex64Slice()
2712 | replaced := make([]complex64, len(arr))
2713 |
2714 | v.EachComplex64(func(index int, val complex64) bool {
2715 | replaced[index] = replacer(index, val)
2716 | return true
2717 | })
2718 |
2719 | return &Value{data: replaced}
2720 |
2721 | }
2722 |
2723 | // CollectComplex64 uses the specified collector function to collect a value
2724 | // for each of the complex64s in the slice. The data returned will be a
2725 | // []interface{}.
2726 | func (v *Value) CollectComplex64(collector func(int, complex64) interface{}) *Value {
2727 |
2728 | arr := v.MustComplex64Slice()
2729 | collected := make([]interface{}, len(arr))
2730 |
2731 | v.EachComplex64(func(index int, val complex64) bool {
2732 | collected[index] = collector(index, val)
2733 | return true
2734 | })
2735 |
2736 | return &Value{data: collected}
2737 | }
2738 |
2739 | /*
2740 | Complex128 (complex128 and []complex128)
2741 | --------------------------------------------------
2742 | */
2743 |
2744 | // Complex128 gets the value as a complex128, returns the optionalDefault
2745 | // value or a system default object if the value is the wrong type.
2746 | func (v *Value) Complex128(optionalDefault ...complex128) complex128 {
2747 | if s, ok := v.data.(complex128); ok {
2748 | return s
2749 | }
2750 | if len(optionalDefault) == 1 {
2751 | return optionalDefault[0]
2752 | }
2753 | return 0
2754 | }
2755 |
2756 | // MustComplex128 gets the value as a complex128.
2757 | //
2758 | // Panics if the object is not a complex128.
2759 | func (v *Value) MustComplex128() complex128 {
2760 | return v.data.(complex128)
2761 | }
2762 |
2763 | // Complex128Slice gets the value as a []complex128, returns the optionalDefault
2764 | // value or nil if the value is not a []complex128.
2765 | func (v *Value) Complex128Slice(optionalDefault ...[]complex128) []complex128 {
2766 | if s, ok := v.data.([]complex128); ok {
2767 | return s
2768 | }
2769 | if len(optionalDefault) == 1 {
2770 | return optionalDefault[0]
2771 | }
2772 | return nil
2773 | }
2774 |
2775 | // MustComplex128Slice gets the value as a []complex128.
2776 | //
2777 | // Panics if the object is not a []complex128.
2778 | func (v *Value) MustComplex128Slice() []complex128 {
2779 | return v.data.([]complex128)
2780 | }
2781 |
2782 | // IsComplex128 gets whether the object contained is a complex128 or not.
2783 | func (v *Value) IsComplex128() bool {
2784 | _, ok := v.data.(complex128)
2785 | return ok
2786 | }
2787 |
2788 | // IsComplex128Slice gets whether the object contained is a []complex128 or not.
2789 | func (v *Value) IsComplex128Slice() bool {
2790 | _, ok := v.data.([]complex128)
2791 | return ok
2792 | }
2793 |
2794 | // EachComplex128 calls the specified callback for each object
2795 | // in the []complex128.
2796 | //
2797 | // Panics if the object is the wrong type.
2798 | func (v *Value) EachComplex128(callback func(int, complex128) bool) *Value {
2799 |
2800 | for index, val := range v.MustComplex128Slice() {
2801 | carryon := callback(index, val)
2802 | if carryon == false {
2803 | break
2804 | }
2805 | }
2806 |
2807 | return v
2808 |
2809 | }
2810 |
2811 | // WhereComplex128 uses the specified decider function to select items
2812 | // from the []complex128. The object contained in the result will contain
2813 | // only the selected items.
2814 | func (v *Value) WhereComplex128(decider func(int, complex128) bool) *Value {
2815 |
2816 | var selected []complex128
2817 |
2818 | v.EachComplex128(func(index int, val complex128) bool {
2819 | shouldSelect := decider(index, val)
2820 | if shouldSelect == false {
2821 | selected = append(selected, val)
2822 | }
2823 | return true
2824 | })
2825 |
2826 | return &Value{data: selected}
2827 |
2828 | }
2829 |
2830 | // GroupComplex128 uses the specified grouper function to group the items
2831 | // keyed by the return of the grouper. The object contained in the
2832 | // result will contain a map[string][]complex128.
2833 | func (v *Value) GroupComplex128(grouper func(int, complex128) string) *Value {
2834 |
2835 | groups := make(map[string][]complex128)
2836 |
2837 | v.EachComplex128(func(index int, val complex128) bool {
2838 | group := grouper(index, val)
2839 | if _, ok := groups[group]; !ok {
2840 | groups[group] = make([]complex128, 0)
2841 | }
2842 | groups[group] = append(groups[group], val)
2843 | return true
2844 | })
2845 |
2846 | return &Value{data: groups}
2847 |
2848 | }
2849 |
2850 | // ReplaceComplex128 uses the specified function to replace each complex128s
2851 | // by iterating each item. The data in the returned result will be a
2852 | // []complex128 containing the replaced items.
2853 | func (v *Value) ReplaceComplex128(replacer func(int, complex128) complex128) *Value {
2854 |
2855 | arr := v.MustComplex128Slice()
2856 | replaced := make([]complex128, len(arr))
2857 |
2858 | v.EachComplex128(func(index int, val complex128) bool {
2859 | replaced[index] = replacer(index, val)
2860 | return true
2861 | })
2862 |
2863 | return &Value{data: replaced}
2864 |
2865 | }
2866 |
2867 | // CollectComplex128 uses the specified collector function to collect a value
2868 | // for each of the complex128s in the slice. The data returned will be a
2869 | // []interface{}.
2870 | func (v *Value) CollectComplex128(collector func(int, complex128) interface{}) *Value {
2871 |
2872 | arr := v.MustComplex128Slice()
2873 | collected := make([]interface{}, len(arr))
2874 |
2875 | v.EachComplex128(func(index int, val complex128) bool {
2876 | collected[index] = collector(index, val)
2877 | return true
2878 | })
2879 |
2880 | return &Value{data: collected}
2881 | }
2882 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/objx/value.go:
--------------------------------------------------------------------------------
1 | package objx
2 |
3 | import (
4 | "fmt"
5 | "strconv"
6 | )
7 |
8 | // Value provides methods for extracting interface{} data in various
9 | // types.
10 | type Value struct {
11 | // data contains the raw data being managed by this Value
12 | data interface{}
13 | }
14 |
15 | // Data returns the raw data contained by this Value
16 | func (v *Value) Data() interface{} {
17 | return v.data
18 | }
19 |
20 | // String returns the value always as a string
21 | func (v *Value) String() string {
22 | switch {
23 | case v.IsStr():
24 | return v.Str()
25 | case v.IsBool():
26 | return strconv.FormatBool(v.Bool())
27 | case v.IsFloat32():
28 | return strconv.FormatFloat(float64(v.Float32()), 'f', -1, 32)
29 | case v.IsFloat64():
30 | return strconv.FormatFloat(v.Float64(), 'f', -1, 64)
31 | case v.IsInt():
32 | return strconv.FormatInt(int64(v.Int()), 10)
33 | case v.IsInt():
34 | return strconv.FormatInt(int64(v.Int()), 10)
35 | case v.IsInt8():
36 | return strconv.FormatInt(int64(v.Int8()), 10)
37 | case v.IsInt16():
38 | return strconv.FormatInt(int64(v.Int16()), 10)
39 | case v.IsInt32():
40 | return strconv.FormatInt(int64(v.Int32()), 10)
41 | case v.IsInt64():
42 | return strconv.FormatInt(v.Int64(), 10)
43 | case v.IsUint():
44 | return strconv.FormatUint(uint64(v.Uint()), 10)
45 | case v.IsUint8():
46 | return strconv.FormatUint(uint64(v.Uint8()), 10)
47 | case v.IsUint16():
48 | return strconv.FormatUint(uint64(v.Uint16()), 10)
49 | case v.IsUint32():
50 | return strconv.FormatUint(uint64(v.Uint32()), 10)
51 | case v.IsUint64():
52 | return strconv.FormatUint(v.Uint64(), 10)
53 | }
54 |
55 | return fmt.Sprintf("%#v", v.Data())
56 | }
57 |
--------------------------------------------------------------------------------
/Godeps/_workspace/src/github.com/stretchr/objx/value_test.go:
--------------------------------------------------------------------------------
1 | package objx
2 |
3 | import (
4 | "github.com/stretchr/testify/assert"
5 | "testing"
6 | )
7 |
8 | func TestStringTypeString(t *testing.T) {
9 | m := New(map[string]interface{}{"string": "foo"})
10 | assert.Equal(t, "foo", m.Get("string").String())
11 | }
12 |
13 | func TestStringTypeBool(t *testing.T) {
14 | m := New(map[string]interface{}{"bool": true})
15 | assert.Equal(t, "true", m.Get("bool").String())
16 | }
17 |
18 | func TestStringTypeInt(t *testing.T) {
19 | m := New(map[string]interface{}{
20 | "int": int(1),
21 | "int8": int8(8),
22 | "int16": int16(16),
23 | "int32": int32(32),
24 | "int64": int64(64),
25 | })
26 |
27 | assert.Equal(t, "1", m.Get("int").String())
28 | assert.Equal(t, "8", m.Get("int8").String())
29 | assert.Equal(t, "16", m.Get("int16").String())
30 | assert.Equal(t, "32", m.Get("int32").String())
31 | assert.Equal(t, "64", m.Get("int64").String())
32 | }
33 |
34 | func TestStringTypeUint(t *testing.T) {
35 | m := New(map[string]interface{}{
36 | "uint": uint(1),
37 | "uint8": uint8(8),
38 | "uint16": uint16(16),
39 | "uint32": uint32(32),
40 | "uint64": uint64(64),
41 | })
42 |
43 | assert.Equal(t, "1", m.Get("uint").String())
44 | assert.Equal(t, "8", m.Get("uint8").String())
45 | assert.Equal(t, "16", m.Get("uint16").String())
46 | assert.Equal(t, "32", m.Get("uint32").String())
47 | assert.Equal(t, "64", m.Get("uint64").String())
48 | }
49 |
50 | func TestStringTypeFloat(t *testing.T) {
51 | m := New(map[string]interface{}{
52 | "float32": float32(32.32),
53 | "float64": float64(64.64),
54 | })
55 |
56 | assert.Equal(t, "32.32", m.Get("float32").String())
57 | assert.Equal(t, "64.64", m.Get("float64").String())
58 | }
59 |
60 | func TestStringTypeOther(t *testing.T) {
61 | m := New(map[string]interface{}{
62 | "other": []string{"foo", "bar"},
63 | })
64 |
65 | assert.Equal(t, "[]string{\"foo\", \"bar\"}", m.Get("other").String())
66 | }
67 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Taylor Blau
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # minecraft [](https://travis-ci.org/ttaylorr/minecraft)
2 |
3 | 
4 |
5 | ```
6 | go get github.com/ttaylorr/minecraft
7 | ```
8 |
9 | ## License
10 |
11 | MIT
12 |
--------------------------------------------------------------------------------
/chat/color.go:
--------------------------------------------------------------------------------
1 | package chat
2 |
3 | type Color string
4 |
5 | var (
6 | Colors []Color = []Color{
7 | ColorBlack, ColorDarkBlue, ColorDarkGreen, ColorDarkAqua,
8 | ColorDarkRed, ColorPurple, ColorGold, ColorGray, ColorDarkGray,
9 | ColorBlue, ColorGreen, ColorAqua, ColorRed, ColorLightPurple,
10 | ColorYellow, ColorWhite,
11 | }
12 | )
13 |
14 | const (
15 | ColorBlack Color = "black"
16 | ColorDarkBlue = "dark_blue"
17 | ColorDarkGreen = "dark_green"
18 | ColorDarkAqua = "dark_aqua"
19 | ColorDarkRed = "dark_red"
20 | ColorPurple = "dark_purple"
21 | ColorGold = "gold"
22 | ColorGray = "gray"
23 | ColorDarkGray = "dark_Gray"
24 | ColorBlue = "blue"
25 | ColorGreen = "green"
26 | ColorAqua = "aqua"
27 | ColorRed = "red"
28 | ColorLightPurple = "light_purple"
29 | ColorYellow = "yellow"
30 | ColorWhite = "white"
31 | )
32 |
--------------------------------------------------------------------------------
/chat/component.go:
--------------------------------------------------------------------------------
1 | package chat
2 |
3 | type (
4 | TextComponent struct {
5 | Text string `json:"text"`
6 |
7 | Component
8 | }
9 |
10 | TranslateComponent struct {
11 | Translate string `json:"translate"`
12 | With []string `json:"with"`
13 |
14 | Component
15 | }
16 |
17 | ScoreComponent struct {
18 | Name string `json:"name"`
19 | Objective string `json:"objective"`
20 |
21 | Component
22 | }
23 |
24 | SelectorComponent struct {
25 | Selector string `json:"selector"`
26 | Args []string `json:"extra"`
27 |
28 | Component
29 | }
30 |
31 | Component struct {
32 | Bold bool `json:"bold"`
33 | Italic bool `json:"italic"`
34 | Underlined bool `json:"underlined"`
35 | Strikethrough bool `json:"strikethrough"`
36 | Obfuscated bool `json:"obfuscated"`
37 |
38 | Color Color `json:"color"`
39 |
40 | ClickEvent ClickEvent `json:"clickEvent"`
41 | HoverEvent HoverEvent `json:"hoverEvent"`
42 |
43 | Insertion string `json:"insertion"`
44 | }
45 | )
46 |
--------------------------------------------------------------------------------
/chat/event.go:
--------------------------------------------------------------------------------
1 | package chat
2 |
3 | type (
4 | ClickAction string
5 | HoverAction string
6 |
7 | ClickEvent struct {
8 | Action ClickAction
9 | Value string
10 | }
11 |
12 | HoverEvent struct {
13 | Action HoverAction
14 | Value interface{}
15 | }
16 | )
17 |
18 | const (
19 | OpenUrlClickAction ClickAction = "open_url"
20 | OpenFileClickAction = "open_file"
21 | RunCommandClickAction = "run_command"
22 | SuggestCommandClickAction = "suggest_command"
23 |
24 | ShowTextHoverAction HoverAction = "show_text"
25 | ShowAchievement = "show_achievement"
26 | ShowItem = "show_item"
27 | )
28 |
--------------------------------------------------------------------------------
/protocol/connection.go:
--------------------------------------------------------------------------------
1 | package protocol
2 |
3 | import (
4 | "bufio"
5 | "encoding/binary"
6 | "errors"
7 | "io"
8 |
9 | "github.com/ttaylorr/minecraft/protocol/packet"
10 | )
11 |
12 | var (
13 | ErrTooFewBytes = errors.New("too few bytes read")
14 | )
15 |
16 | // Connection represents a uni-directional connection from client to server.
17 | type Connection struct {
18 | d *Dealer
19 | rw io.ReadWriter
20 | }
21 |
22 | // NewConnection serves as the builder function for type Connection. It takes in
23 | // a reader which, when read from, yeilds data sent by the "client".
24 | func NewConnection(rw io.ReadWriter) *Connection {
25 | return &Connection{d: NewDealer(), rw: rw}
26 | }
27 |
28 | func (c *Connection) SetState(state State) {
29 | c.d.SetState(state)
30 | }
31 |
32 | func (c *Connection) Next() (interface{}, error) {
33 | p, err := c.packet()
34 | if err != nil {
35 | return nil, err
36 | }
37 |
38 | return c.d.Decode(p)
39 | }
40 |
41 | func (c *Connection) Write(h packet.Holder) (int, error) {
42 | data, err := c.d.Encode(h)
43 | if err != nil {
44 | return -1, nil
45 | }
46 |
47 | return c.rw.Write(data)
48 | }
49 |
50 | // Next reads and decodes the next Packet on the stream. Packets are expected to
51 | // be in the following format (as described on
52 | // http://wiki.vg/Protocol#Without_compression:
53 | //
54 | // Without compression:
55 | // | Field Name | Field Type | Field Notes |
56 | // | ---------- | ---------- | ---------------------------------- |
57 | // | Length | Uvarint | Represents length of + |
58 | // | ID | Uvarint | |
59 | // | Data | []byte | |
60 | //
61 | // With compression:
62 | // ...
63 | //
64 | // If an error is experienced in reading the packet from the io.Reader `r`, then
65 | // a nil pointer will be returned and the error will be propogated up.
66 | func (c *Connection) packet() (*packet.Packet, error) {
67 | r := bufio.NewReader(c.rw)
68 |
69 | size, err := binary.ReadUvarint(r)
70 | if err != nil {
71 | return nil, err
72 | }
73 |
74 | // TODO(ttaylorr): extract this to a package `util`
75 | buffer := make([]byte, size)
76 | read, err := io.ReadAtLeast(r, buffer, int(size))
77 | if err != nil {
78 | return nil, err
79 | } else if read < int(size) {
80 | return nil, ErrTooFewBytes
81 | }
82 |
83 | id, offset := binary.Uvarint(buffer)
84 |
85 | return &packet.Packet{
86 | ID: int(id),
87 | Direction: packet.DirectionServerbound,
88 | Data: buffer[offset:],
89 | }, nil
90 | }
91 |
--------------------------------------------------------------------------------
/protocol/connection_test.go:
--------------------------------------------------------------------------------
1 | package protocol
2 |
3 | import (
4 | "bytes"
5 | "testing"
6 |
7 | "github.com/stretchr/testify/assert"
8 | "github.com/ttaylorr/minecraft/protocol/packet"
9 | )
10 |
11 | func TestConnectionConstruction(t *testing.T) {
12 | b := new(bytes.Buffer)
13 | conn := NewConnection(b)
14 |
15 | assert.NotNil(t, conn, "expected a *Connection object, got nil")
16 | }
17 |
18 | func TestPacketReading(t *testing.T) {
19 | p := []byte{
20 | 0x0f, 0x00, 0x2f, 0x09, 0x6c, 0x6f, 0x63, 0x61,
21 | 0x6c, 0x68, 0x64, 0x73, 0x74, 0x63, 0xdd, 0x01,
22 | }
23 |
24 | r := bytes.NewBuffer(p)
25 | c := NewConnection(r)
26 |
27 | next, err := c.packet()
28 |
29 | assert.Nil(t, err)
30 | assert.Equal(t, next.ID, 0)
31 | assert.Equal(t, next.Direction, packet.DirectionServerbound)
32 | assert.Equal(t, next.Data, p[2:])
33 | }
34 |
--------------------------------------------------------------------------------
/protocol/dealer.go:
--------------------------------------------------------------------------------
1 | package protocol
2 |
3 | import (
4 | "bytes"
5 | "reflect"
6 | "sync"
7 |
8 | "github.com/ttaylorr/minecraft/protocol/packet"
9 | "github.com/ttaylorr/minecraft/protocol/types"
10 | "github.com/ttaylorr/minecraft/util"
11 | )
12 |
13 | // A Dealer manages a set of `Rule`s and is able to decode and encode arbitrary
14 | // data by finding and using applicable rules.
15 | type Dealer struct {
16 | State State
17 | smu sync.RWMutex
18 | }
19 |
20 | // NewDealer creates and returns a pointer to a new Dealer
21 | func NewDealer() *Dealer {
22 | return &Dealer{}
23 | }
24 |
25 | func (d *Dealer) SetState(s State) {
26 | d.smu.Lock()
27 | defer d.smu.Unlock()
28 |
29 | d.State = s
30 | }
31 |
32 | // Decode decodes a packet coming from the client (sent to the server) into a
33 | // packet "holder" type. (An example holder type is packet.Handshake). The
34 | // types of the struct's fields are picked one by one (in order) and a field of
35 | // data is decoded off of the stream and initialized into the corresponding
36 | // field. If no matching decoder is found, an error is returned.
37 | func (d *Dealer) Decode(p *packet.Packet) (v interface{}, err error) {
38 | inst := reflect.New(d.GetHolderType(p)).Elem()
39 |
40 | data := bytes.NewBuffer(p.Data)
41 |
42 | for i := 0; i < inst.NumField(); i++ {
43 | f := inst.Field(i)
44 |
45 | typ, ok := f.Interface().(types.Type)
46 | if !ok {
47 | continue
48 | }
49 |
50 | v, err := typ.Decode(data)
51 | if err != nil {
52 | return nil, err
53 | }
54 |
55 | f.Set(reflect.ValueOf(v))
56 | }
57 |
58 | return inst.Interface(), nil
59 | }
60 |
61 | // Encode encodes a packet to be sent from the server to client into an array of
62 | // bytes. The values of each field are encoded into the byte array according to
63 | // their type.
64 | //
65 | // Once all of the data is serialized, the length and ID will be written in
66 | // front of it, according to the specification given in `connection.go` from
67 | // L41-L46.
68 | //
69 | // If an error occurs during encoding, an empty byte array and that
70 | // error will be returned.
71 | func (d *Dealer) Encode(h packet.Holder) ([]byte, error) {
72 | out := new(bytes.Buffer)
73 | out.Write(util.Uvarint(uint32(h.ID())))
74 |
75 | v := reflect.ValueOf(h)
76 |
77 | for i := 0; i < v.NumField(); i++ {
78 | ftype, ok := v.Field(i).Interface().(types.Type)
79 | if !ok {
80 | // XXX(taylor): special-casing
81 | ftype = types.JSON{V: v.Field(i).Interface()}
82 | }
83 |
84 | if _, err := ftype.Encode(out); err != nil {
85 | return nil, err
86 | }
87 | }
88 |
89 | return append(
90 | util.Uvarint(uint32(out.Len())),
91 | out.Bytes()...,
92 | ), nil
93 | }
94 |
95 | // GetHolderType returns the `reflect.Type` associated with a particular packet
96 | // sent to the server (from the client).
97 | func (d *Dealer) GetHolderType(p *packet.Packet) reflect.Type {
98 | d.smu.RLock()
99 | defer d.smu.RUnlock()
100 |
101 | return GetPacket(p.Direction, d.State, p.ID)
102 | }
103 |
--------------------------------------------------------------------------------
/protocol/dealer_test.go:
--------------------------------------------------------------------------------
1 | package protocol_test
2 |
3 | import (
4 | "reflect"
5 | "testing"
6 |
7 | "github.com/stretchr/testify/assert"
8 | "github.com/ttaylorr/minecraft/protocol"
9 | "github.com/ttaylorr/minecraft/protocol/packet"
10 | "github.com/ttaylorr/minecraft/protocol/types"
11 | )
12 |
13 | func TestDecoderInitialization(t *testing.T) {
14 | d := protocol.NewDealer()
15 | assert.IsType(t, d, &protocol.Dealer{})
16 | }
17 |
18 | func TestPacketDecoding(t *testing.T) {
19 | d := protocol.NewDealer()
20 | p := &packet.Packet{
21 | ID: 0x00,
22 | Data: []byte{
23 | 0x2f, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68,
24 | 0x64, 0x73, 0x74, 0x63, 0xdd, 0x01,
25 | },
26 | }
27 |
28 | v, err := d.Decode(p)
29 |
30 | assert.Nil(t, err)
31 | hsk, _ := v.(packet.Handshake)
32 |
33 | assert.IsType(t, hsk, packet.Handshake{})
34 |
35 | assert.Equal(t, types.UVarint(47), hsk.ProtocolVersion)
36 | assert.Equal(t, types.String("localhdst"), hsk.ServerAddress)
37 | assert.Equal(t, types.UShort(25565), hsk.ServerPort)
38 | assert.Equal(t, types.UVarint(1), hsk.NextState)
39 | }
40 |
41 | func TestPacketEncoding(t *testing.T) {
42 | handshake := packet.Handshake{
43 | ProtocolVersion: 47,
44 | ServerAddress: "localhdst",
45 | ServerPort: 25565,
46 | NextState: 1,
47 | }
48 |
49 | d := protocol.NewDealer()
50 | e, err := d.Encode(handshake)
51 |
52 | assert.Nil(t, err)
53 | assert.Equal(t, []byte{
54 | 0x0f, 0x00, 0x2f, 0x09, 0x6c, 0x6f, 0x63, 0x61,
55 | 0x6c, 0x68, 0x64, 0x73, 0x74, 0x63, 0xdd, 0x01,
56 | }, e)
57 | }
58 |
59 | func TestFindingHolderWithValidID(t *testing.T) {
60 | d := protocol.NewDealer()
61 | pack := &packet.Packet{ID: 0x00}
62 |
63 | holder := d.GetHolderType(pack)
64 | assert.Equal(t, holder, reflect.TypeOf(packet.Handshake{}))
65 | }
66 |
67 | func TestFindingHolderWithInvalidID(t *testing.T) {
68 | d := protocol.NewDealer()
69 | pack := &packet.Packet{ID: -1}
70 |
71 | assert.Nil(t, d.GetHolderType(pack))
72 | }
73 |
--------------------------------------------------------------------------------
/protocol/packet/holder.go:
--------------------------------------------------------------------------------
1 | package packet
2 |
3 | type Holder interface {
4 | ID() int
5 | }
6 |
--------------------------------------------------------------------------------
/protocol/packet/packet.go:
--------------------------------------------------------------------------------
1 | package packet
2 |
3 | // Type Packet encapsulates a raw packet sent between the Minecraft server and
4 | // the Minecraft client.
5 | type Packet struct {
6 | // ID is the ID of the packet according to the latest version of the
7 | // Minecraft protocol as implemented by Mojang AB.
8 | ID int
9 |
10 | // Direction gives information regarding who sent the packet. Packets
11 | // sent from server to client will always be tagged DirectionClientbound
12 | // whereas messages passed from client ot server will be
13 | // DirectionServerbound.
14 | Direction Direction
15 |
16 | // Data contains the uncompressed array of bytes encoding the body of
17 | // the packet itself.
18 | Data []byte
19 | }
20 |
21 | type Direction int
22 |
23 | const (
24 | DirectionServerbound Direction = iota
25 | DirectionClientbound
26 | )
27 |
--------------------------------------------------------------------------------
/protocol/packet/packets_handshake.go:
--------------------------------------------------------------------------------
1 | package packet
2 |
3 | import "github.com/ttaylorr/minecraft/protocol/types"
4 |
5 | type Handshake struct {
6 | ProtocolVersion types.UVarint
7 | ServerAddress types.String
8 | ServerPort types.UShort
9 | NextState types.UVarint
10 | }
11 |
12 | func (h Handshake) ID() int {
13 | return 0x00
14 | }
15 |
--------------------------------------------------------------------------------
/protocol/packet/packets_status.go:
--------------------------------------------------------------------------------
1 | package packet
2 |
3 | import (
4 | "github.com/ttaylorr/minecraft/chat"
5 | "github.com/ttaylorr/minecraft/protocol/types"
6 | )
7 |
8 | type StatusRequest struct{}
9 |
10 | func (r *StatusRequest) ID() int { return 0x00 }
11 |
12 | type StatusResponse struct {
13 | Status struct {
14 | Version struct {
15 | Name string `json:"name"`
16 | Protocol int `json:"protocol"`
17 | } `json:"version"`
18 |
19 | Players struct {
20 | Max int `json:"max"`
21 | Online int `json:"online"`
22 | } `json:"players"`
23 |
24 | Description chat.TextComponent `json:"description"`
25 | }
26 | }
27 |
28 | func (r StatusResponse) ID() int { return 0x00 }
29 |
30 | type StatusPing struct {
31 | Payload types.Long
32 | }
33 |
34 | func (p StatusPing) ID() int { return 0x01 }
35 |
36 | type StatusPong struct {
37 | Payload types.Long
38 | }
39 |
40 | func (p StatusPong) ID() int { return 0x01 }
41 |
--------------------------------------------------------------------------------
/protocol/packets.go:
--------------------------------------------------------------------------------
1 | package protocol
2 |
3 | import (
4 | "reflect"
5 |
6 | "github.com/ttaylorr/minecraft/protocol/packet"
7 | )
8 |
9 | var (
10 | Packets = map[packet.Direction]map[State]map[int]reflect.Type{
11 | packet.DirectionServerbound: map[State]map[int]reflect.Type{
12 | HandshakeState: map[int]reflect.Type{
13 | 0x00: reflect.TypeOf(packet.Handshake{}),
14 | },
15 | StatusState: map[int]reflect.Type{
16 | 0x00: reflect.TypeOf(packet.StatusRequest{}),
17 | 0x01: reflect.TypeOf(packet.StatusPing{}),
18 | },
19 | },
20 | packet.DirectionClientbound: map[State]map[int]reflect.Type{
21 | StatusState: map[int]reflect.Type{
22 | 0x00: reflect.TypeOf(packet.StatusResponse{}),
23 | 0x01: reflect.TypeOf(packet.StatusPong{}),
24 | },
25 | },
26 | }
27 | )
28 |
29 | func GetPacket(d packet.Direction, s State, id int) reflect.Type {
30 | return Packets[d][s][id]
31 | }
32 |
--------------------------------------------------------------------------------
/protocol/state.go:
--------------------------------------------------------------------------------
1 | package protocol
2 |
3 | type State uint8
4 |
5 | const (
6 | HandshakeState State = iota
7 | StatusState
8 | )
9 |
--------------------------------------------------------------------------------
/protocol/types/json.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | "encoding/json"
5 | "errors"
6 | "io"
7 | )
8 |
9 | type JSON struct {
10 | V interface{}
11 | }
12 |
13 | func (_ JSON) Decode(r io.Reader) (interface{}, error) {
14 | return nil, errors.New("not yet implemented")
15 | }
16 |
17 | func (j JSON) Encode(w io.Writer) (int, error) {
18 | data, err := json.Marshal(j.V)
19 | if err != nil {
20 | return 0, err
21 | }
22 |
23 | str := String(string(data))
24 | return str.Encode(w)
25 | }
26 |
--------------------------------------------------------------------------------
/protocol/types/long.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | "encoding/binary"
5 | "io"
6 | )
7 |
8 | type Long int64
9 |
10 | func (_ Long) Decode(r io.Reader) (interface{}, error) {
11 | var l Long
12 | err := binary.Read(r, ByteOrder, &l)
13 |
14 | return l, err
15 | }
16 |
17 | func (l Long) Encode(w io.Writer) (int, error) {
18 | return 8, binary.Write(w, ByteOrder, l)
19 | }
20 |
--------------------------------------------------------------------------------
/protocol/types/string.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | "encoding/binary"
5 | "errors"
6 | "io"
7 |
8 | "github.com/ttaylorr/minecraft/util"
9 | )
10 |
11 | var (
12 | ErrorMismatchedStringLength = errors.New("fewer bytes available than string length")
13 | )
14 |
15 | type String string
16 |
17 | func (_ String) Decode(r io.Reader) (interface{}, error) {
18 | size, err := binary.ReadUvarint(util.ByteReader{r})
19 | if err != nil {
20 | return nil, err
21 | }
22 |
23 | str := make([]byte, int(size))
24 | if read, err := r.Read(str); err != nil {
25 | return nil, err
26 | } else if read != int(size) {
27 | return nil, ErrorMismatchedStringLength
28 | }
29 |
30 | return String(string(str)), nil
31 | }
32 |
33 | func (s String) Encode(w io.Writer) (int, error) {
34 | var n int
35 | var err error
36 |
37 | length := util.Uvarint(uint32(len(s)))
38 |
39 | written, err := w.Write(length)
40 | n += written
41 | if err != nil {
42 | return written, err
43 | }
44 |
45 | written, err = w.Write([]byte(s))
46 | n += written
47 | if err != nil {
48 | return written, err
49 | }
50 |
51 | return written, nil
52 | }
53 |
--------------------------------------------------------------------------------
/protocol/types/type.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | "encoding/binary"
5 | "fmt"
6 | "io"
7 | "reflect"
8 | )
9 |
10 | var (
11 | ByteOrder = binary.BigEndian
12 | )
13 |
14 | // A Rule represents a particular decoding method, usually bound to a type. It
15 | // gives information regarding how to decode and encode a particular piece
16 | // of data to and from a `*bytes.Buffer`.
17 | //
18 | // Only after a call to the `AppliesTo` method returns true can it be said that
19 | // the Rule is allowed to work on a given value.
20 | type Type interface {
21 | // Decode reads from the given *bytes.Buffer and returns the decoded
22 | // contents of a single field of data. If an error is encountered during
23 | // read-time, or if the data is invalid post read-time, an error will be
24 | // thrown.
25 | Decode(r io.Reader) (interface{}, error)
26 |
27 | // Encode turns a Go type instance into some bytes packed together in
28 | // a []byte. If the data is the wrong type, an error will be thrown. If
29 | // the data is un-encodable, or an error occurs while encoding, the
30 | // error will be thrown.
31 | Encode(w io.Writer) (int, error)
32 | }
33 |
34 | func ErrorMismatchedType(expected string, actual interface{}) error {
35 | return fmt.Errorf(
36 | "cannot encode mismatched type (expected: %s, got: %s)",
37 | expected, reflect.TypeOf(actual),
38 | )
39 | }
40 |
--------------------------------------------------------------------------------
/protocol/types/ushort.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import "io"
4 |
5 | type UShort uint16
6 |
7 | func (u UShort) Decode(r io.Reader) (interface{}, error) {
8 | buf := u.Buffer()
9 | if _, err := r.Read(buf); err != nil {
10 | return nil, err
11 | }
12 |
13 | return UShort(ByteOrder.Uint16(buf)), nil
14 | }
15 |
16 | func (u UShort) Encode(w io.Writer) (int, error) {
17 | buf := u.Buffer()
18 | ByteOrder.PutUint16(buf, uint16(u))
19 |
20 | return w.Write(buf)
21 | }
22 |
23 | func (u UShort) Buffer() []byte {
24 | return make([]byte, 2)
25 | }
26 |
--------------------------------------------------------------------------------
/protocol/types/uvarint.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | "encoding/binary"
5 | "io"
6 |
7 | "github.com/ttaylorr/minecraft/util"
8 | )
9 |
10 | type UVarint uint32
11 |
12 | func (_ UVarint) Decode(r io.Reader) (interface{}, error) {
13 | br := util.ByteReader{r}
14 |
15 | i, err := binary.ReadUvarint(br)
16 | if err != nil {
17 | return nil, err
18 | }
19 |
20 | return UVarint(uint32(i)), nil
21 | }
22 |
23 | func (u UVarint) Encode(w io.Writer) (int, error) {
24 | return w.Write(util.Uvarint(uint32(u)))
25 | }
26 |
--------------------------------------------------------------------------------
/protocol/types/varint.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | "encoding/binary"
5 | "io"
6 |
7 | "github.com/ttaylorr/minecraft/util"
8 | )
9 |
10 | type Varint int32
11 |
12 | func (_ Varint) Decode(r io.Reader) (interface{}, error) {
13 | br := util.ByteReader{r}
14 |
15 | i, err := binary.ReadVarint(br)
16 | if err != nil {
17 | return nil, err
18 | }
19 |
20 | return Varint(int32(i)), nil
21 | }
22 |
23 | func (v Varint) Encode(w io.Writer) (int, error) {
24 | return w.Write(util.Varint(int32(v)))
25 | }
26 |
--------------------------------------------------------------------------------
/server.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "io"
5 | "math/rand"
6 | "net"
7 |
8 | "github.com/ttaylorr/minecraft/chat"
9 | "github.com/ttaylorr/minecraft/protocol"
10 | "github.com/ttaylorr/minecraft/protocol/packet"
11 | )
12 |
13 | func main() {
14 | conn, _ := net.Listen("tcp", "0.0.0.0:25565")
15 | for {
16 | client, _ := conn.Accept()
17 | go handleConnection(protocol.NewConnection(client))
18 | }
19 | }
20 |
21 | func handleConnection(c *protocol.Connection) {
22 | for {
23 | p, err := c.Next()
24 | if err == io.EOF {
25 | return
26 | }
27 |
28 | switch t := p.(type) {
29 | case packet.Handshake:
30 | state := protocol.State(uint8(t.NextState))
31 | c.SetState(state)
32 | case packet.StatusRequest:
33 | resp := packet.StatusResponse{}
34 | resp.Status.Version.Name = "1.8.8"
35 | resp.Status.Version.Protocol = 47
36 | resp.Status.Players.Max = rand.Intn(100)
37 | resp.Status.Players.Online = rand.Intn(101)
38 | resp.Status.Description = chat.TextComponent{
39 | "Hello from Golang!",
40 |
41 | chat.Component{
42 | Bold: true,
43 | Color: chat.ColorRed,
44 | },
45 | }
46 |
47 | c.Write(resp)
48 | case packet.StatusPing:
49 | pong := packet.StatusPong{}
50 | pong.Payload = t.Payload
51 |
52 | c.Write(pong)
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/util/encoding.go:
--------------------------------------------------------------------------------
1 | package util
2 |
3 | import "encoding/binary"
4 |
5 | var (
6 | maxVarintLength = 5
7 | )
8 |
9 | func Varint(n int32) []byte {
10 | buf := make([]byte, maxVarintLength)
11 | l := binary.PutVarint(buf, int64(n))
12 |
13 | return buf[:l]
14 | }
15 |
16 | func Uvarint(n uint32) []byte {
17 | buf := make([]byte, maxVarintLength)
18 | l := binary.PutUvarint(buf, uint64(n))
19 |
20 | return buf[:l]
21 | }
22 |
--------------------------------------------------------------------------------
/util/reader.go:
--------------------------------------------------------------------------------
1 | package util
2 |
3 | import "io"
4 |
5 | type ByteReader struct {
6 | io.Reader
7 | }
8 |
9 | func (br ByteReader) ReadByte() (byte, error) {
10 | buf := make([]byte, 1)
11 | if _, err := br.Read(buf); err != nil {
12 | return 0, err
13 | }
14 |
15 | return buf[0], nil
16 | }
17 |
--------------------------------------------------------------------------------
/util/reader_test.go:
--------------------------------------------------------------------------------
1 | package util_test
2 |
3 | import (
4 | "bytes"
5 | "io"
6 | "testing"
7 |
8 | "github.com/stretchr/testify/assert"
9 | "github.com/ttaylorr/minecraft/util"
10 | )
11 |
12 | func TestByteReaderReadsOneByte(t *testing.T) {
13 | source := bytes.NewReader([]byte{1, 2, 3})
14 | br := util.ByteReader{source}
15 |
16 | first, err := br.ReadByte()
17 | assert.Nil(t, err)
18 | assert.Equal(t, first, byte(1))
19 |
20 | second, err := br.ReadByte()
21 | assert.Nil(t, err)
22 | assert.Equal(t, second, byte(2))
23 |
24 | third, err := br.ReadByte()
25 | assert.Nil(t, err)
26 | assert.Equal(t, third, byte(3))
27 | }
28 |
29 | func TestEmptyByteReaderEOFs(t *testing.T) {
30 | source := bytes.NewReader([]byte{})
31 | br := util.ByteReader{source}
32 |
33 | _, err := br.ReadByte()
34 | assert.Equal(t, io.EOF, err)
35 | }
36 |
--------------------------------------------------------------------------------