├── .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 [![Build Status](https://travis-ci.org/ttaylorr/minecraft.svg)](https://travis-ci.org/ttaylorr/minecraft) 2 | 3 | ![](http://i.imgur.com/MqTtJ93.png) 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 | --------------------------------------------------------------------------------