├── .gitignore ├── Gopkg.lock ├── Gopkg.toml ├── LICENSE ├── README.md ├── hades └── hades.go ├── init.sh ├── lib └── server │ ├── pusher.go │ ├── response_buffer.go │ └── server.go └── vendor └── github.com ├── gabesullice └── jq │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── doc.go │ ├── op.go │ ├── op_chain_test.go │ ├── op_dot_test.go │ ├── parse.go │ ├── parse_regexp_test.go │ ├── parse_test.go │ └── scanner │ ├── any.go │ ├── any_test.go │ ├── array.go │ ├── array_test.go │ ├── as.go │ ├── as_array_test.go │ ├── bool.go │ ├── doc.go │ ├── err.go │ ├── find_from.go │ ├── find_from_test.go │ ├── find_index.go │ ├── find_index_test.go │ ├── find_key.go │ ├── find_key_test.go │ ├── find_range.go │ ├── find_range_test.go │ ├── find_to.go │ ├── find_to_test.go │ ├── null.go │ ├── null_test.go │ ├── number.go │ ├── number_test.go │ ├── object.go │ ├── object_test.go │ ├── string.go │ ├── string_test.go │ ├── util.go │ └── util_test.go └── satori └── go.uuid ├── .travis.yml ├── LICENSE ├── README.md ├── codec.go ├── codec_test.go ├── generator.go ├── generator_test.go ├── sql.go ├── sql_test.go ├── uuid.go └── uuid_test.go /.gitignore: -------------------------------------------------------------------------------- 1 | /hades/hades 2 | /server.crt 3 | /server.key 4 | -------------------------------------------------------------------------------- /Gopkg.lock: -------------------------------------------------------------------------------- 1 | # This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. 2 | 3 | 4 | [[projects]] 5 | branch = "rename-imports" 6 | name = "github.com/gabesullice/jq" 7 | packages = [ 8 | ".", 9 | "scanner" 10 | ] 11 | revision = "2f1db31d92127040bab202f0f0a4ee6977eb7c7c" 12 | 13 | [[projects]] 14 | name = "github.com/satori/go.uuid" 15 | packages = ["."] 16 | revision = "f58768cc1a7a7e77a3bd49e98cdd21419399b6a3" 17 | version = "v1.2.0" 18 | 19 | [solve-meta] 20 | analyzer-name = "dep" 21 | analyzer-version = 1 22 | inputs-digest = "67483caa2bd23a0aaa96c343b9a76fdb467749d280a4d2933a1ff48e58b96a5b" 23 | solver-name = "gps-cdcl" 24 | solver-version = 1 25 | -------------------------------------------------------------------------------- /Gopkg.toml: -------------------------------------------------------------------------------- 1 | 2 | # Gopkg.toml example 3 | # 4 | # Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md 5 | # for detailed Gopkg.toml documentation. 6 | # 7 | # required = ["github.com/user/thing/cmd/thing"] 8 | # ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] 9 | # 10 | # [[constraint]] 11 | # name = "github.com/user/project" 12 | # version = "1.0.0" 13 | # 14 | # [[constraint]] 15 | # name = "github.com/user/project2" 16 | # branch = "dev" 17 | # source = "github.com/myfork/project2" 18 | # 19 | # [[override]] 20 | # name = "github.com/x/y" 21 | # version = "2.4.0" 22 | 23 | 24 | [[constraint]] 25 | branch = "rename-imports" 26 | name = "github.com/gabesullice/jq" 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Gabriel Sullice 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 | Hades 2 | === 3 | 4 | Hades is an **experimental** HATEOAS-based HTTP/2 reverse proxy for JSON API backends. 5 | 6 | ## Why? 7 | The JSON API specification makes ample use of `links` objects in its 8 | specification. These links objects contain URLs which enable a client to easily 9 | and automatically traverse documents to fetch subsequent pages, relationship 10 | data and related resources. 11 | 12 | With the ever increasing deployment of HTTP/2, these HATEOAS links become much 13 | more relevant, especially when they can be pushed to the client _before the 14 | client even requests them_. 15 | 16 | Hades is an intelligent reverse proxy that can be deployed in front of any 17 | JSON API server. 18 | 19 | Clients that are HTTP/2 capable can then send an `X-Push-Please` request header 20 | to your application. The values of this header should be comprised of [JSONPath selectors](http://goessner.net/articles/JsonPath/index.html#e2) 21 | which target links in the expected response document. Hades will identify these 22 | links and proactively push the linked resources to the client. 23 | 24 | Clients that are not HTTP/2 capable can also send these headers, Hades will 25 | simply not push the responses. Future versions of Hades might make further 26 | optimizations (like using the request to warm a server-side application cache). 27 | 28 | ## Example 29 | Take a JSON API server with `issue`, `comment` and `user` resource types as an 30 | example. 31 | 32 | A client would like to list the 10 most recent issues and embed user 33 | avatars for every participant in the issue. 34 | 35 | In JSON API terms, the data model is structured such that: 36 | 37 | 1. Issues have a relationship to comments 38 | 1. Comments have an author relationship to users 39 | 1. User resources have an attribute that specifies a URL for the user's avatar 40 | 41 | `issue -> comment -> user -> avatar` 42 | 43 | Traditionally, one might use the `include` query parameter to receive a compound 44 | document response. The compound document would embed the chain of resources in a 45 | single response. However, in this scenario, issues do not support includes on 46 | comments. They would be far too numerous—if 10 issues each have 100 comments, 47 | the compound document would have 1000 resources! 48 | 49 | This means that a client will first need to: 50 | 51 | 1. Fetch the first 10 issues 52 | 1. Fetch from the `related` or `relationship` routes for _each_ issue 53 | 1. Fetch the user resource for each unique author 54 | 1. Finally, download the user's avatar file using a download URL on the user resource 55 | 56 | This chain of requests is often called the "waterfall." Each step needs to be 57 | completed before the next step can proceed because the client can't know which 58 | resources to fetch in advance. 59 | 60 | In other words, the client can't know which users to fetch if it doesn't know 61 | which comments are on an issue... and the client can't know which comments to 62 | fetch without first fetching the issues. 63 | 64 | Hades solves this problem. By specifying the following request, a client can 65 | inform the Hades proxy which resources _it's going to fetch_ and Hades can then 66 | proactively push those resources to the client. 67 | 68 | ``` 69 | GET /api/issues?sort=-created&page[limit]=10 70 | 71 | X-Push-Please: $.data[*].relationships.comments.links.related 72 | X-Push-Please: $.data[*].relationships.author.links.related 73 | X-Push-Please: $.data.attributes.avatar.url 74 | ``` 75 | Multiple headers are permitted by HTTP/2. Alternatively, values may be 76 | concatenated with `;` 77 | 78 | Hades can use this information to identify the links in the response document 79 | that the client will eventually require. Future versions will permit response 80 | IDs in the `X-Push-Please` header so that link paths can target only specific 81 | responses. 82 | 83 | Apart from the client-sent header, _client applications need not be adapted in 84 | any way_. When the client recieves the initial response document, it should 85 | still request the subsequent documents just as it would under HTTP/1.1. 86 | 87 | However, because those request responses will have already been pushed, they 88 | will already be in a local cache or on the way! That means all responses will 89 | appear to have been received as if the client sent all the requests at the same 90 | time. 91 | 92 | Hades eliminates the waterfall. 93 | 94 | 🔥 95 | -------------------------------------------------------------------------------- /hades/hades.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "net/http" 6 | "net/http/httputil" 7 | "net/url" 8 | "os" 9 | 10 | hades "github.com/gabesullice/hades/lib/server" 11 | ) 12 | 13 | func main() { 14 | url, err := url.Parse(os.Args[1]) 15 | if err != nil { 16 | log.Fatalln("Could not parse backend URL") 17 | } 18 | log.Printf("Started proxy for %v", url) 19 | backend := httputil.NewSingleHostReverseProxy(url) 20 | d := backend.Director 21 | backend.Director = func(r *http.Request) { 22 | r.Header.Set("X-Forwarded-Proto", "https") 23 | d(r) 24 | } 25 | http.Handle("/", hades.NewProxy(backend)) 26 | log.Fatalln(http.ListenAndServeTLS(":443", "./server.crt", "./server.key", nil)) 27 | } 28 | -------------------------------------------------------------------------------- /init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | main () { 6 | openssl genrsa -out server.key 2048 7 | openssl req -new -x509 -sha256 -key server.key -out server.crt -days 3650 8 | } 9 | 10 | main $@ 11 | -------------------------------------------------------------------------------- /lib/server/pusher.go: -------------------------------------------------------------------------------- 1 | package server 2 | 3 | import ( 4 | "log" 5 | "net/http" 6 | "sync" 7 | ) 8 | 9 | var () 10 | 11 | type pusher struct { 12 | sync.WaitGroup 13 | p http.Pusher 14 | } 15 | 16 | func (r *pusher) push(target string, opts *http.PushOptions) { 17 | log.Printf("Pushing: %s", target) 18 | r.Add(1) 19 | if err := r.p.Push(target, opts); err != nil { 20 | r.Done() 21 | log.Printf("Push Error: %s", err) 22 | } 23 | log.Printf("Pushed: %s", target) 24 | } 25 | 26 | type pusherMap struct { 27 | sync.RWMutex 28 | pushers map[string]*pusher 29 | } 30 | 31 | func (r *pusherMap) add(id string, p *pusher) { 32 | r.Lock() 33 | r.pushers[id] = p 34 | r.Unlock() 35 | } 36 | 37 | func (r *pusherMap) get(id string) (*pusher, bool) { 38 | r.RLock() 39 | p, ok := r.pushers[id] 40 | r.RUnlock() 41 | return p, ok 42 | } 43 | 44 | func (r *pusherMap) remove(id string) { 45 | r.Lock() 46 | delete(r.pushers, id) 47 | r.Unlock() 48 | } 49 | -------------------------------------------------------------------------------- /lib/server/response_buffer.go: -------------------------------------------------------------------------------- 1 | package server 2 | 3 | import ( 4 | "bytes" 5 | "io" 6 | "net/http" 7 | ) 8 | 9 | type responseBuffer struct { 10 | body *bytes.Buffer 11 | w http.ResponseWriter 12 | } 13 | 14 | func newResponseBuffer(w http.ResponseWriter) responseBuffer { 15 | var buf bytes.Buffer 16 | return responseBuffer{ 17 | body: &buf, 18 | w: w, 19 | } 20 | } 21 | 22 | func (b responseBuffer) Header() http.Header { 23 | return b.w.Header() 24 | } 25 | 26 | func (b responseBuffer) WriteHeader(h int) { 27 | b.w.WriteHeader(h) 28 | } 29 | 30 | func (b responseBuffer) Write(bs []byte) (int, error) { 31 | return b.body.Write(bs) 32 | } 33 | 34 | func (b *responseBuffer) Bytes() []byte { 35 | return b.body.Bytes() 36 | } 37 | 38 | func (b *responseBuffer) Flush() { 39 | io.Copy(b.w, bytes.NewReader(b.body.Bytes())) 40 | b.body.Reset() 41 | } 42 | -------------------------------------------------------------------------------- /lib/server/server.go: -------------------------------------------------------------------------------- 1 | package server 2 | 3 | import ( 4 | "encoding/json" 5 | "log" 6 | "net/http" 7 | "net/http/httputil" 8 | "net/url" 9 | "strings" 10 | 11 | "github.com/gabesullice/jq" 12 | "github.com/satori/go.uuid" 13 | ) 14 | 15 | func NewProxy(backend *httputil.ReverseProxy) http.Handler { 16 | return &handler{ 17 | backend: backend, 18 | pushers: pusherMap{pushers: make(map[string]*pusher)}, 19 | } 20 | } 21 | 22 | type handler struct { 23 | pushers pusherMap 24 | backend *httputil.ReverseProxy 25 | } 26 | 27 | func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 28 | isPush := r.Header.Get("X-Push") == "ON" 29 | 30 | if r.Header.Get("Accept") != "application/vnd.api+json" { 31 | h.backend.ServeHTTP(w, r) 32 | return 33 | } 34 | 35 | rb := newResponseBuffer(w) 36 | h.backend.ServeHTTP(rb, r) 37 | defer rb.Flush() 38 | 39 | requestID := r.Header.Get("X-Push-Request-ID") 40 | if requestID == "" { 41 | p, ok := w.(http.Pusher) 42 | if !ok { 43 | log.Println("HTTP/2 is not supported") 44 | } else { 45 | requestID = uuid.NewV4().String() 46 | h.pushers.add(requestID, &pusher{p: p}) 47 | defer h.pushers.remove(requestID) 48 | } 49 | } 50 | 51 | if requestID != "" { 52 | if pusher, ok := h.pushers.get(requestID); ok { 53 | ops := parsePushPlease(r.Header.Get("X-Push-Please")) 54 | if len(ops) > 0 { 55 | bs := rb.Bytes() 56 | if pushes := getPushLinks(ops, bs); len(pushes) > 0 { 57 | headers := r.Header 58 | headers.Set("X-Push", "ON") 59 | headers.Set("X-Push-Request-ID", requestID) 60 | opts := &http.PushOptions{Header: headers} 61 | for _, target := range pushes { 62 | pusher.push(target, opts) 63 | } 64 | } 65 | } 66 | 67 | if isPush { 68 | pusher.Done() 69 | } else { 70 | pusher.Wait() 71 | } 72 | } 73 | } 74 | } 75 | 76 | func getPushLinks(ops map[string]jq.Op, b []byte) []string { 77 | var pushes []string 78 | for part, op := range ops { 79 | data, err := op.Apply(b) 80 | if err != nil { 81 | continue 82 | } 83 | 84 | trimmed := strings.TrimSpace(part) 85 | var query string 86 | if strings.Contains(trimmed, "?") { 87 | query = "?" + strings.Split(trimmed, "?")[1] 88 | } else { 89 | query = "" 90 | } 91 | 92 | var links []string 93 | if err := json.Unmarshal(data, &links); err != nil { 94 | var link string 95 | if err := json.Unmarshal(data, &link); err != nil { 96 | continue 97 | } 98 | links = append(links, link) 99 | } 100 | 101 | for _, link := range links { 102 | if url, err := url.Parse(link); err == nil { 103 | pushes = append(pushes, url.RequestURI()+query) 104 | } 105 | } 106 | } 107 | return pushes 108 | } 109 | 110 | func parsePushPlease(please string) map[string]jq.Op { 111 | ops := make(map[string]jq.Op) 112 | for _, part := range strings.Split(please, ";") { 113 | // Invalid paths are simply ignored. 114 | trimmed := strings.TrimSpace(part) 115 | var path string 116 | if strings.Contains(trimmed, "?") { 117 | path = strings.Split(trimmed, "?")[0] 118 | } else { 119 | path = trimmed 120 | } 121 | if op, err := jq.Parse(path); err == nil { 122 | ops[trimmed] = op 123 | } 124 | } 125 | return ops 126 | } 127 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/.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 | *.test 24 | *.prof 25 | 26 | # ignore intellij files 27 | .idea 28 | *.iml 29 | *.ipr 30 | *.iws 31 | 32 | # ignore scratch files 33 | sample.json 34 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/README.md: -------------------------------------------------------------------------------- 1 | # jq 2 | 3 | [![GoDoc](https://godoc.org/github.com/savaki/jq?status.svg)](https://godoc.org/github.com/savaki/jq) 4 | [![Build Status](https://snap-ci.com/savaki/jq/branch/master/build_image)](https://snap-ci.com/savaki/jq/branch/master) 5 | 6 | A high performance Golang implementation of the incredibly useful jq command line tool. 7 | 8 | Rather than marshalling json elements into go instances, jq opts to manipulate the json elements as raw []byte. This 9 | is especially useful for apps that need to handle dynamic json data. 10 | 11 | Using jq consists of creation an ```Op``` and then calling ```Apply``` on the ```Op``` to transform one []byte into the 12 | desired []byte. Ops may be chained together to form a transformation chain similar to how the command line jq works. 13 | 14 | ## Installation 15 | 16 | ``` 17 | go get github.com/savaki/jq 18 | ``` 19 | 20 | ## Example 21 | 22 | ```go 23 | package main 24 | 25 | import ( 26 | "fmt" 27 | 28 | "github.com/savaki/jq" 29 | ) 30 | 31 | func main() { 32 | op, _ := jq.Parse(".hello") // create an Op 33 | data := []byte(`{"hello":"world"}`) // sample input 34 | value, _ := op.Apply(data) // value == '"world"' 35 | fmt.Println(string(value)) 36 | } 37 | ``` 38 | 39 | ## Syntax 40 | 41 | The initial goal is to support all the selectors the original jq command line supports. 42 | 43 | | syntax | meaning| 44 | | :--- | :--- | 45 | | . | unchanged input | 46 | | .foo | value at key | 47 | | .foo.bar | value at nested key | 48 | | .[0] | value at specified element of array | 49 | | .[0:1] | array of specified elements of array, inclusive | 50 | | .foo.[0] | nested value | 51 | 52 | ## Examples 53 | 54 | ### Data 55 | ```json 56 | { 57 | "string": "a", 58 | "number": 1.23, 59 | "simple": ["a", "b", "c"], 60 | "mixed": [ 61 | "a", 62 | 1, 63 | {"hello":"world"} 64 | ], 65 | "object": { 66 | "first": "joe", 67 | "array": [1,2,3] 68 | } 69 | } 70 | ``` 71 | 72 | | syntax | value | 73 | | :--- | :--- | 74 | | .string | "a" | 75 | | .number| 1.23 | 76 | | .simple | ["a", "b", "c"] | 77 | | .simple.[0] | "a" | 78 | | .simple.[0:1] | ["a","b"] | 79 | | .mixed.[1] | 1 80 | | .object.first | "joe" | 81 | | .object.array.[2] | 3 | 82 | 83 | ## Performance 84 | 85 | ``` 86 | BenchmarkAny-8 20000000 80.8 ns/op 0 B/op 0 allocs/op 87 | BenchmarkArray-8 20000000 108 ns/op 0 B/op 0 allocs/op 88 | BenchmarkFindIndex-8 10000000 125 ns/op 0 B/op 0 allocs/op 89 | BenchmarkFindKey-8 10000000 125 ns/op 0 B/op 0 allocs/op 90 | BenchmarkFindRange-8 10000000 186 ns/op 16 B/op 1 allocs/op 91 | BenchmarkNumber-8 50000000 28.9 ns/op 0 B/op 0 allocs/op 92 | BenchmarkObject-8 20000000 98.5 ns/op 0 B/op 0 allocs/op 93 | BenchmarkString-8 30000000 40.4 ns/op 0 B/op 0 allocs/op 94 | ``` 95 | 96 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/doc.go: -------------------------------------------------------------------------------- 1 | // Package jp offers a highly performant json selector in the style of the jq command line 2 | // 3 | // Usage of this package involves the concept of an Op. An Op is a transformation that converts a []byte into a []byte. 4 | // To get started, use the Parse function to obtain an Op. 5 | // 6 | // op, err := jq.Parse(".key") 7 | // 8 | // This will create an Op that will accept a JSON object in []byte format and return the value associated with "key." 9 | // For example: 10 | // 11 | // in := []byte(`{"key":"value"}`) 12 | // data, _ := op.Apply(in)) 13 | // fmt.Println(string(data)) 14 | // 15 | // Will print the string "value". The goal is to support all the select operations supported by jq's command line 16 | // namesake. 17 | // 18 | package jq 19 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/op.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Matt Ho 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package jq 16 | 17 | import ( 18 | "bytes" 19 | "strings" 20 | 21 | "github.com/gabesullice/jq/scanner" 22 | ) 23 | 24 | // Op defines a single transformation to be applied to a []byte 25 | type Op interface { 26 | Apply([]byte) ([]byte, error) 27 | Iterate([][]byte) ([]byte, error) 28 | } 29 | 30 | // OpFunc provides a convenient func type wrapper on Op 31 | type OpFunc func([]byte) ([]byte, error) 32 | 33 | // Apply executes the transformation defined by OpFunc 34 | func (fn OpFunc) Apply(in []byte) ([]byte, error) { 35 | return fn(in) 36 | } 37 | 38 | func (fn OpFunc) Iterate(in [][]byte) ([]byte, error) { 39 | iterated := make([][]byte, len(in)) 40 | var err error 41 | for i, _ := range in { 42 | iterated[i], err = fn(in[i]) 43 | if err != nil { 44 | return nil, err 45 | } 46 | } 47 | return bytes.Join( 48 | [][]byte{ 49 | []byte("["), 50 | bytes.Join(iterated, []byte(",")), 51 | []byte("]"), 52 | }, 53 | []byte(""), 54 | ), nil 55 | } 56 | 57 | func Iterator(fn Op) OpFunc { 58 | return func(in []byte) ([]byte, error) { 59 | split, err := scanner.AsArray(in, 0) 60 | if err != nil { 61 | return nil, err 62 | } 63 | return fn.Iterate(split) 64 | } 65 | } 66 | 67 | // Dot extract the specific key from the map provided; to extract a nested value, use the Dot Op in conjunction with the 68 | // Chain Op 69 | func Dot(key string) OpFunc { 70 | key = strings.TrimSpace(key) 71 | if key == "" { 72 | return func(in []byte) ([]byte, error) { return in, nil } 73 | } 74 | 75 | k := []byte(key) 76 | 77 | return func(in []byte) ([]byte, error) { 78 | return scanner.FindKey(in, 0, k) 79 | } 80 | } 81 | 82 | // Chain executes a series of operations in the order provided 83 | func Chain(filters ...Op) OpFunc { 84 | return func(in []byte) ([]byte, error) { 85 | if filters == nil { 86 | return in, nil 87 | } 88 | 89 | var err error 90 | data := in 91 | for _, filter := range filters { 92 | data, err = filter.Apply(data) 93 | if err != nil { 94 | return nil, err 95 | } 96 | } 97 | 98 | return data, nil 99 | } 100 | } 101 | 102 | // Index extracts a specific element from the array provided 103 | func Index(index int) OpFunc { 104 | return func(in []byte) ([]byte, error) { 105 | return scanner.FindIndex(in, 0, index) 106 | } 107 | } 108 | 109 | // Range extracts a selection of elements from the array provided, inclusive 110 | func Range(from, to int) OpFunc { 111 | return func(in []byte) ([]byte, error) { 112 | return scanner.FindRange(in, 0, from, to) 113 | } 114 | } 115 | 116 | // From extracts all elements from the array provided from the given index onward, inclusive 117 | func From(from int) OpFunc { 118 | return func(in []byte) ([]byte, error) { 119 | return scanner.FindFrom(in, 0, from) 120 | } 121 | } 122 | 123 | // To extracts all elements from the array provided up to the given index, inclusive 124 | func To(to int) OpFunc { 125 | return func(in []byte) ([]byte, error) { 126 | return scanner.FindTo(in, 0, to) 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/op_chain_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Matt Ho 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package jq_test 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/gabesullice/jq" 21 | ) 22 | 23 | func BenchmarkChain(t *testing.B) { 24 | op := jq.Chain(jq.Dot("a"), jq.Dot("b")) 25 | data := []byte(`{"a":{"b":"value"}}`) 26 | 27 | for i := 0; i < t.N; i++ { 28 | _, err := op.Apply(data) 29 | if err != nil { 30 | t.FailNow() 31 | return 32 | } 33 | } 34 | } 35 | 36 | func TestChain(t *testing.T) { 37 | testCases := map[string]struct { 38 | In string 39 | Op jq.Op 40 | Expected string 41 | HasError bool 42 | }{ 43 | "simple": { 44 | In: `{"hello":"world"}`, 45 | Op: jq.Chain(jq.Dot("hello")), 46 | Expected: `"world"`, 47 | }, 48 | "nested": { 49 | In: `{"a":{"b":"world"}}`, 50 | Op: jq.Chain(jq.Dot("a"), jq.Dot("b")), 51 | Expected: `"world"`, 52 | }, 53 | } 54 | 55 | for label, tc := range testCases { 56 | t.Run(label, func(t *testing.T) { 57 | data, err := tc.Op.Apply([]byte(tc.In)) 58 | if tc.HasError { 59 | if err == nil { 60 | t.FailNow() 61 | } 62 | } else { 63 | if string(data) != tc.Expected { 64 | t.FailNow() 65 | } 66 | if err != nil { 67 | t.FailNow() 68 | } 69 | } 70 | }) 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/op_dot_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Matt Ho 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package jq_test 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/gabesullice/jq" 21 | ) 22 | 23 | func BenchmarkDot(t *testing.B) { 24 | op := jq.Dot("hello") 25 | data := []byte(`{"hello":"world"}`) 26 | 27 | for i := 0; i < t.N; i++ { 28 | _, err := op.Apply(data) 29 | if err != nil { 30 | t.FailNow() 31 | return 32 | } 33 | } 34 | } 35 | 36 | func TestDot(t *testing.T) { 37 | testCases := map[string]struct { 38 | In string 39 | Key string 40 | Expected string 41 | HasError bool 42 | }{ 43 | "simple": { 44 | In: `{"hello":"world"}`, 45 | Key: "hello", 46 | Expected: `"world"`, 47 | }, 48 | "key not found": { 49 | In: `{"hello":"world"}`, 50 | Key: "junk", 51 | HasError: true, 52 | }, 53 | "unclosed value": { 54 | In: `{"hello":"world`, 55 | Key: "hello", 56 | HasError: true, 57 | }, 58 | } 59 | 60 | for label, tc := range testCases { 61 | t.Run(label, func(t *testing.T) { 62 | op := jq.Dot(tc.Key) 63 | data, err := op.Apply([]byte(tc.In)) 64 | if tc.HasError { 65 | if err == nil { 66 | t.FailNow() 67 | } 68 | } else { 69 | if string(data) != tc.Expected { 70 | t.FailNow() 71 | } 72 | if err != nil { 73 | t.FailNow() 74 | } 75 | } 76 | }) 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/parse.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Matt Ho 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package jq 16 | 17 | import ( 18 | "fmt" 19 | "regexp" 20 | "strconv" 21 | "strings" 22 | ) 23 | 24 | var ( 25 | reArray = regexp.MustCompile(`^\s*\[\s*(?:(\d+))?\s*(?:(:))?\s*(?:(\d+))?\s*\]\s*$`) 26 | ) 27 | 28 | // Must is a convenience method similar to template.Must 29 | func Must(op Op, err error) Op { 30 | if err != nil { 31 | panic(fmt.Errorf("unable to parse selector; %v", err.Error())) 32 | } 33 | 34 | return op 35 | } 36 | 37 | // Parse takes a string representation of a selector and returns the corresponding Op definition 38 | func Parse(selector string) (Op, error) { 39 | return transform(strings.Split(selector, ".")), nil 40 | } 41 | 42 | func transform(segments []string) Op { 43 | ops := make([]Op, 0, len(segments)) 44 | 45 | for k, _ := range segments { 46 | key := strings.TrimSpace(segments[k]) 47 | if key == "" { 48 | continue 49 | } 50 | 51 | if op, ok := parseArray(key); ok { 52 | if k < len(segments)-1 { 53 | ops = append(ops, Chain(op, Iterator(transform(segments[k+1:])))) 54 | } else { 55 | ops = append(ops, op) 56 | } 57 | break 58 | } 59 | 60 | ops = append(ops, Dot(key)) 61 | } 62 | 63 | return Chain(ops...) 64 | } 65 | 66 | func parseArray(key string) (Op, bool) { 67 | match := FindIndices(key) 68 | 69 | if len(match) == 0 { 70 | return nil, false 71 | } 72 | 73 | matches := match[0] 74 | 75 | if matches[1]+matches[2]+matches[3] == "" { 76 | return From(0), true 77 | } 78 | 79 | if matches[2] == "" { 80 | idx, err := strconv.Atoi(matches[1]) 81 | if err != nil { 82 | return nil, false 83 | } 84 | return Index(idx), true 85 | } 86 | 87 | if matches[1] == "" { 88 | to, err := strconv.Atoi(matches[3]) 89 | if err != nil { 90 | return nil, false 91 | } 92 | return To(to), true 93 | } 94 | 95 | if matches[3] == "" { 96 | from, err := strconv.Atoi(matches[1]) 97 | if err != nil { 98 | return nil, false 99 | } 100 | return From(from), true 101 | } 102 | 103 | from, err := strconv.Atoi(matches[1]) 104 | if err != nil { 105 | return nil, false 106 | } 107 | 108 | to, err := strconv.Atoi(matches[3]) 109 | if err != nil { 110 | return nil, false 111 | } 112 | 113 | return Range(from, to), true 114 | } 115 | 116 | func FindIndices(key string) [][]string { 117 | return reArray.FindAllStringSubmatch(key, -1) 118 | } 119 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/parse_regexp_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Matt Ho 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package jq 16 | 17 | import ( 18 | "testing" 19 | ) 20 | 21 | func TestRegexp(t *testing.T) { 22 | testCases := map[string]struct { 23 | In string 24 | From string 25 | To string 26 | }{ 27 | "simple": { 28 | In: `[0]`, 29 | From: "0", 30 | }, 31 | "range": { 32 | In: `[0:1]`, 33 | From: "0", 34 | To: "1", 35 | }, 36 | "space before": { 37 | In: ` [0:1]`, 38 | From: "0", 39 | To: "1", 40 | }, 41 | "space after": { 42 | In: `[0:1] `, 43 | From: "0", 44 | To: "1", 45 | }, 46 | "space from": { 47 | In: `[ 0 :1] `, 48 | From: "0", 49 | To: "1", 50 | }, 51 | "space to": { 52 | In: `[0: 1 ] `, 53 | From: "0", 54 | To: "1", 55 | }, 56 | } 57 | 58 | for label, tc := range testCases { 59 | t.Run(label, func(t *testing.T) { 60 | matches := reArray.FindAllStringSubmatch(tc.In, -1) 61 | if len(matches) != 1 { 62 | t.FailNow() 63 | } 64 | if len(matches[0]) != 4 { 65 | t.FailNow() 66 | } 67 | if matches[0][1] != tc.From { 68 | t.FailNow() 69 | } 70 | if matches[0][3] != tc.To { 71 | t.FailNow() 72 | } 73 | }) 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/parse_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Matt Ho 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package jq_test 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/gabesullice/jq" 21 | ) 22 | 23 | func TestParse(t *testing.T) { 24 | testCases := map[string]struct { 25 | In string 26 | Op string 27 | Expected string 28 | HasError bool 29 | }{ 30 | "simple": { 31 | In: `{"hello":"world"}`, 32 | Op: ".hello", 33 | Expected: `"world"`, 34 | }, 35 | "nested": { 36 | In: `{"a":{"b":"world"}}`, 37 | Op: ".a.b", 38 | Expected: `"world"`, 39 | }, 40 | "index": { 41 | In: `["a","b","c"]`, 42 | Op: ".[1]", 43 | Expected: `"b"`, 44 | }, 45 | "range": { 46 | In: `["a","b","c"]`, 47 | Op: ".[1:2]", 48 | Expected: `["b","c"]`, 49 | }, 50 | "from": { 51 | In: `["a","b","c","d"]`, 52 | Op: ".[1:]", 53 | Expected: `["b","c","d"]`, 54 | }, 55 | "to": { 56 | In: `["a","b","c","d"]`, 57 | Op: ".[:2]", 58 | Expected: `["a","b","c"]`, 59 | }, 60 | "all": { 61 | In: `["a","b","c","d"]`, 62 | Op: ".[]", 63 | Expected: `["a","b","c","d"]`, 64 | }, 65 | "nested index": { 66 | In: `{"abc":"-","def":["a","b","c"]}`, 67 | Op: ".def.[1]", 68 | Expected: `"b"`, 69 | }, 70 | "interated index": { 71 | In: `[{"foo":"bar"},{"foo":"baz"}]`, 72 | Op: ".[].foo", 73 | Expected: `["bar","baz"]`, 74 | }, 75 | "nested range": { 76 | In: `{"abc":"-","def":["a","b","c"]}`, 77 | Op: ".def.[1:2]", 78 | Expected: `["b","c"]`, 79 | }, 80 | } 81 | 82 | for label, tc := range testCases { 83 | t.Run(label, func(t *testing.T) { 84 | op, err := jq.Parse(tc.Op) 85 | if err != nil { 86 | t.FailNow() 87 | } 88 | 89 | data, err := op.Apply([]byte(tc.In)) 90 | if tc.HasError { 91 | if err == nil { 92 | t.FailNow() 93 | } 94 | } else { 95 | if string(data) != tc.Expected { 96 | t.Logf("op: %q", data) 97 | t.FailNow() 98 | } 99 | if err != nil { 100 | t.FailNow() 101 | } 102 | } 103 | }) 104 | } 105 | } 106 | 107 | //func TestFindIndices(t *testing.T) { 108 | // testCases := map[string]struct { 109 | // In string 110 | // Expect []string 111 | // }{ 112 | // "simple": { 113 | // In: "[0]", 114 | // Expect: []string{"0"}, 115 | // }, 116 | // "range": { 117 | // In: "[0:1]", 118 | // Expect: []string{"0"}, 119 | // }, 120 | // "from": { 121 | // In: "[1:]", 122 | // Expect: []string{"0"}, 123 | // }, 124 | // "to": { 125 | // In: "[:1]", 126 | // Expect: []string{"0"}, 127 | // }, 128 | // } 129 | // for label, tc := range testCases { 130 | // t.Run(label, func(t *testing.T) { 131 | // matches := jq.FindIndices(tc.In) 132 | // t.Logf("%#v", matches[0]) 133 | // if len(matches) == 0 { 134 | // t.Log("no matches") 135 | // t.FailNow() 136 | // } 137 | // if len(matches[0]) != len(tc.Expect) { 138 | // t.Log("count mismatch") 139 | // t.FailNow() 140 | // } 141 | // for k, v := range tc.Expect { 142 | // if v != matches[0][k] { 143 | // t.Log("expected mismatch") 144 | // t.FailNow() 145 | // } 146 | // } 147 | // }) 148 | // } 149 | //} 150 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/scanner/any.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Matt Ho 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package scanner 16 | 17 | // Any returns the position of the end of the current element that begins at pos; handles any valid json element 18 | func Any(in []byte, pos int) (int, error) { 19 | pos, err := skipSpace(in, pos) 20 | if err != nil { 21 | return 0, err 22 | } 23 | 24 | switch in[pos] { 25 | case '"': 26 | return String(in, pos) 27 | case '{': 28 | return Object(in, pos) 29 | case '.', '-', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0': 30 | return Number(in, pos) 31 | case '[': 32 | return Array(in, pos) 33 | case 't', 'f': 34 | return Boolean(in, pos) 35 | case 'n': 36 | return Null(in, pos) 37 | default: 38 | max := len(in) - pos 39 | if max > 20 { 40 | max = 20 41 | } 42 | 43 | return 0, opErr{ 44 | pos: pos, 45 | msg: "invalid object", 46 | content: string(in[pos : pos+max]), 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/scanner/any_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Matt Ho 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package scanner_test 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/gabesullice/jq/scanner" 21 | ) 22 | 23 | func BenchmarkAny(t *testing.B) { 24 | data := []byte(`"Hello, 世界 - 生日快乐"`) 25 | 26 | for i := 0; i < t.N; i++ { 27 | end, err := scanner.Any(data, 0) 28 | if err != nil { 29 | t.FailNow() 30 | return 31 | } 32 | 33 | if end == 0 { 34 | t.FailNow() 35 | return 36 | } 37 | } 38 | } 39 | 40 | func TestAny(t *testing.T) { 41 | testCases := map[string]struct { 42 | In string 43 | Out string 44 | }{ 45 | "string": { 46 | In: `"hello"`, 47 | Out: `"hello"`, 48 | }, 49 | "array": { 50 | In: `["a","b","c"]`, 51 | Out: `["a","b","c"]`, 52 | }, 53 | "object": { 54 | In: `{"a":"b"}`, 55 | Out: `{"a":"b"}`, 56 | }, 57 | "number": { 58 | In: `1.234e+10`, 59 | Out: `1.234e+10`, 60 | }, 61 | } 62 | 63 | for label, tc := range testCases { 64 | t.Run(label, func(t *testing.T) { 65 | end, err := scanner.Any([]byte(tc.In), 0) 66 | if err != nil { 67 | t.FailNow() 68 | } 69 | data := tc.In[0:end] 70 | if string(data) != tc.Out { 71 | t.FailNow() 72 | } 73 | }) 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/scanner/array.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Matt Ho 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package scanner 16 | 17 | // Array returns the position of the end of the array that begins at the position specified 18 | func Array(in []byte, pos int) (int, error) { 19 | pos, err := skipSpace(in, pos) 20 | if err != nil { 21 | return 0, err 22 | } 23 | 24 | if v := in[pos]; v != '[' { 25 | return 0, newError(pos, v) 26 | } 27 | pos++ 28 | 29 | // clean initial spaces 30 | pos, err = skipSpace(in, pos) 31 | if err != nil { 32 | return 0, err 33 | } 34 | 35 | if in[pos] == ']' { 36 | return pos + 1, nil 37 | } 38 | 39 | for { 40 | // data 41 | pos, err = Any(in, pos) 42 | if err != nil { 43 | return 0, err 44 | } 45 | 46 | pos, err = skipSpace(in, pos) 47 | if err != nil { 48 | return 0, err 49 | } 50 | 51 | switch in[pos] { 52 | case ',': 53 | pos++ 54 | case ']': 55 | return pos + 1, nil 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/scanner/array_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Matt Ho 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package scanner_test 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/gabesullice/jq/scanner" 21 | ) 22 | 23 | func BenchmarkArray(t *testing.B) { 24 | data := []byte(`["hello","world"]`) 25 | 26 | for i := 0; i < t.N; i++ { 27 | end, err := scanner.Array(data, 0) 28 | if err != nil { 29 | t.FailNow() 30 | return 31 | } 32 | 33 | if end == 0 { 34 | t.FailNow() 35 | return 36 | } 37 | } 38 | } 39 | 40 | func TestArray(t *testing.T) { 41 | testCases := map[string]struct { 42 | In string 43 | Out string 44 | HasErr bool 45 | }{ 46 | "simple": { 47 | In: `["hello","world"]`, 48 | Out: `["hello","world"]`, 49 | }, 50 | "empty": { 51 | In: `[]`, 52 | Out: `[]`, 53 | }, 54 | "spaced": { 55 | In: ` [ "hello" , "world" ] `, 56 | Out: ` [ "hello" , "world" ]`, 57 | }, 58 | "all types": { 59 | In: ` [ "hello" , 123, {"hello":"world"} ] `, 60 | Out: ` [ "hello" , 123, {"hello":"world"} ]`, 61 | }, 62 | } 63 | 64 | for label, tc := range testCases { 65 | t.Run(label, func(t *testing.T) { 66 | end, err := scanner.Array([]byte(tc.In), 0) 67 | if tc.HasErr { 68 | if err == nil { 69 | t.FailNow() 70 | } 71 | 72 | } else { 73 | data := tc.In[0:end] 74 | if string(data) != tc.Out { 75 | t.FailNow() 76 | } 77 | if err != nil { 78 | t.FailNow() 79 | } 80 | } 81 | }) 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/scanner/as.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Matt Ho 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package scanner 16 | 17 | // AsArray accepts an []byte encoded json array as an input and returns the array's elements 18 | func AsArray(in []byte, pos int) ([][]byte, error) { 19 | pos, err := skipSpace(in, pos) 20 | if err != nil { 21 | return nil, err 22 | } 23 | 24 | if v := in[pos]; v != '[' { 25 | return nil, newError(pos, v) 26 | } 27 | pos++ 28 | 29 | // clean initial spaces 30 | pos, err = skipSpace(in, pos) 31 | if err != nil { 32 | return nil, err 33 | } 34 | 35 | if in[pos] == ']' { 36 | return [][]byte{}, nil 37 | } 38 | 39 | // 1. Count the number of elements in the array 40 | 41 | start := pos 42 | 43 | elements := make([][]byte, 0, 256) 44 | for { 45 | pos, err = skipSpace(in, pos) 46 | if err != nil { 47 | return nil, err 48 | } 49 | 50 | start = pos 51 | 52 | // data 53 | pos, err = Any(in, pos) 54 | if err != nil { 55 | return nil, err 56 | } 57 | elements = append(elements, in[start:pos]) 58 | 59 | pos, err = skipSpace(in, pos) 60 | if err != nil { 61 | return nil, err 62 | } 63 | 64 | switch in[pos] { 65 | case ',': 66 | pos++ 67 | case ']': 68 | return elements, nil 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/scanner/as_array_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Matt Ho 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package scanner_test 16 | 17 | import ( 18 | "bytes" 19 | "testing" 20 | 21 | "github.com/gabesullice/jq/scanner" 22 | ) 23 | 24 | func BenchmarkAsArray(t *testing.B) { 25 | data := []byte(`["hello","world"]`) 26 | 27 | for i := 0; i < t.N; i++ { 28 | out, err := scanner.AsArray(data, 0) 29 | if err != nil { 30 | t.Errorf("expected nil err; got %v", err) 31 | return 32 | } 33 | if v := len(out); v != 2 { 34 | t.Errorf("want %v, got %v", 2, v) 35 | return 36 | } 37 | } 38 | } 39 | 40 | func TestAsArray(t *testing.T) { 41 | testCases := map[string]struct { 42 | In string 43 | Out []string 44 | HasErr bool 45 | }{ 46 | "simple": { 47 | In: `["hello","world"]`, 48 | Out: []string{`"hello"`, `"world"`}, 49 | }, 50 | "empty": { 51 | In: `[]`, 52 | Out: []string{}, 53 | }, 54 | "spaced": { 55 | In: ` [ "hello" , "world" ] `, 56 | Out: []string{`"hello"`, `"world"`}, 57 | }, 58 | "all types": { 59 | In: ` [ "hello" , 123, {"hello":"world"} ] `, 60 | Out: []string{`"hello"`, `123`, `{"hello":"world"}`}, 61 | }, 62 | } 63 | 64 | for label, tc := range testCases { 65 | t.Run(label, func(t *testing.T) { 66 | out, err := scanner.AsArray([]byte(tc.In), 0) 67 | if tc.HasErr { 68 | if err == nil { 69 | t.FailNow() 70 | } 71 | 72 | } else { 73 | if err != nil { 74 | t.Errorf("expected nil err; got %v", err) 75 | return 76 | } 77 | if len(out) != len(tc.Out) { 78 | t.Errorf("expected output lengths to match; want %v, got %v", len(tc.Out), len(out)) 79 | return 80 | } 81 | for index, item := range tc.Out { 82 | if v := out[index]; bytes.Compare(v, []byte(item)) != 0 { 83 | t.Errorf("expected content at index %v to match; want %v, got %v", index, item, string(v)) 84 | return 85 | } 86 | } 87 | } 88 | }) 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/scanner/bool.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Matt Ho 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package scanner 16 | 17 | var ( 18 | t = []byte("true") 19 | f = []byte("false") 20 | ) 21 | 22 | // Boolean matches a boolean at the specified position 23 | func Boolean(in []byte, pos int) (int, error) { 24 | switch in[pos] { 25 | case 't': 26 | return expect(in, pos, t...) 27 | case 'f': 28 | return expect(in, pos, f...) 29 | default: 30 | return 0, errUnexpectedValue 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/scanner/doc.go: -------------------------------------------------------------------------------- 1 | // Package scanner provides various utilities for parsing and extracting json data from []byte 2 | 3 | package scanner 4 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/scanner/err.go: -------------------------------------------------------------------------------- 1 | package scanner 2 | 3 | type opErr struct { 4 | pos int 5 | msg string 6 | content string 7 | } 8 | 9 | func (o opErr) Error() string { 10 | return o.msg + "; ..." + o.content 11 | } 12 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/scanner/find_from.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Matt Ho 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package scanner 16 | 17 | // FindTo finds the elements of an array between the specified indexes; inclusive 18 | func FindFrom(in []byte, pos, from int) ([]byte, error) { 19 | pos, err := skipSpace(in, pos) 20 | if err != nil { 21 | return nil, err 22 | } 23 | 24 | if v := in[pos]; v != '[' { 25 | return nil, newError(pos, v) 26 | } 27 | pos++ 28 | 29 | idx := 0 30 | itemStart := pos 31 | 32 | for { 33 | pos, err = skipSpace(in, pos) 34 | if err != nil { 35 | return nil, err 36 | } 37 | 38 | if idx == from { 39 | itemStart = pos 40 | } 41 | 42 | // data 43 | pos, err = Any(in, pos) 44 | if err != nil { 45 | return nil, err 46 | } 47 | 48 | pos, err = skipSpace(in, pos) 49 | if err != nil { 50 | return nil, err 51 | } 52 | 53 | switch in[pos] { 54 | case ',': 55 | pos++ 56 | case ']': 57 | if idx < from { 58 | return nil, errFromOutOfBounds 59 | } 60 | 61 | data := in[itemStart:pos] 62 | result := make([]byte, 0, len(data)+2) 63 | result = append(result, '[') 64 | result = append(result, data...) 65 | result = append(result, ']') 66 | return result, nil 67 | } 68 | 69 | idx++ 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/scanner/find_from_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Matt Ho 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package scanner_test 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/gabesullice/jq/scanner" 21 | ) 22 | 23 | func TestFindFrom(t *testing.T) { 24 | testCases := map[string]struct { 25 | In string 26 | From int 27 | Expected string 28 | HasErr bool 29 | }{ 30 | "all": { 31 | In: `["a","b","c","d","e"]`, 32 | From: 0, 33 | Expected: `["a","b","c","d","e"]`, 34 | }, 35 | "last": { 36 | In: `["a","b","c","d","e"]`, 37 | From: 4, 38 | Expected: `["e"]`, 39 | }, 40 | "middle": { 41 | In: `["a","b","c","d","e"]`, 42 | From: 2, 43 | Expected: `["c","d","e"]`, 44 | }, 45 | "mixed": { 46 | In: `["a",{"hello":"world"},"c","d","e"]`, 47 | From: 0, 48 | Expected: `["a",{"hello":"world"},"c","d","e"]`, 49 | }, 50 | "out of bounds": { 51 | In: `["a",{"hello":"world"},"c","d","e"]`, 52 | From: 20, 53 | HasErr: true, 54 | }, 55 | } 56 | 57 | for label, tc := range testCases { 58 | t.Run(label, func(t *testing.T) { 59 | data, err := scanner.FindFrom([]byte(tc.In), 0, tc.From) 60 | if tc.HasErr { 61 | if err == nil { 62 | t.FailNow() 63 | } 64 | } else { 65 | if string(data) != tc.Expected { 66 | t.FailNow() 67 | } 68 | if err != nil { 69 | t.FailNow() 70 | } 71 | } 72 | }) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/scanner/find_index.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Matt Ho 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package scanner 16 | 17 | // FindIndex accepts a JSON array and return the value of the element at the specified index 18 | func FindIndex(in []byte, pos, index int) ([]byte, error) { 19 | pos, err := skipSpace(in, pos) 20 | if err != nil { 21 | return nil, err 22 | } 23 | 24 | if v := in[pos]; v != '[' { 25 | return nil, newError(pos, v) 26 | } 27 | pos++ 28 | 29 | idx := 0 30 | for { 31 | pos, err = skipSpace(in, pos) 32 | if err != nil { 33 | return nil, err 34 | } 35 | 36 | itemStart := pos 37 | // data 38 | pos, err = Any(in, pos) 39 | if err != nil { 40 | return nil, err 41 | } 42 | if index == idx { 43 | return in[itemStart:pos], nil 44 | } 45 | 46 | pos, err = skipSpace(in, pos) 47 | if err != nil { 48 | return nil, err 49 | } 50 | 51 | switch in[pos] { 52 | case ',': 53 | pos++ 54 | case ']': 55 | return nil, errIndexOutOfBounds 56 | } 57 | 58 | idx++ 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/scanner/find_index_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Matt Ho 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package scanner_test 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/gabesullice/jq/scanner" 21 | ) 22 | 23 | func BenchmarkFindIndex(t *testing.B) { 24 | data := []byte(`["hello","world"]`) 25 | 26 | for i := 0; i < t.N; i++ { 27 | data, err := scanner.FindIndex(data, 0, 1) 28 | if err != nil { 29 | t.FailNow() 30 | return 31 | } 32 | 33 | if string(data) != `"world"` { 34 | t.FailNow() 35 | return 36 | } 37 | } 38 | } 39 | 40 | func TestFindIndex(t *testing.T) { 41 | testCases := map[string]struct { 42 | In string 43 | Index int 44 | Expected string 45 | HasErr bool 46 | }{ 47 | "simple": { 48 | In: `["hello","world"]`, 49 | Index: 1, 50 | Expected: `"world"`, 51 | }, 52 | "spaced": { 53 | In: ` [ "hello" , "world" ] `, 54 | Index: 1, 55 | Expected: `"world"`, 56 | }, 57 | "all types": { 58 | In: ` [ "hello" , 123, {"hello":"world"} ] `, 59 | Index: 2, 60 | Expected: `{"hello":"world"}`, 61 | }, 62 | } 63 | 64 | for label, tc := range testCases { 65 | t.Run(label, func(t *testing.T) { 66 | data, err := scanner.FindIndex([]byte(tc.In), 0, tc.Index) 67 | if tc.HasErr { 68 | if err == nil { 69 | t.FailNow() 70 | } 71 | } else { 72 | if string(data) != tc.Expected { 73 | t.FailNow() 74 | } 75 | if err != nil { 76 | t.FailNow() 77 | } 78 | } 79 | }) 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/scanner/find_key.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Matt Ho 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package scanner 16 | 17 | import "bytes" 18 | 19 | // FindKey accepts a JSON object and returns the value associated with the key specified 20 | func FindKey(in []byte, pos int, k []byte) ([]byte, error) { 21 | pos, err := skipSpace(in, pos) 22 | if err != nil { 23 | return nil, err 24 | } 25 | 26 | if v := in[pos]; v != '{' { 27 | return nil, newError(pos, v) 28 | } 29 | pos++ 30 | 31 | for { 32 | pos, err = skipSpace(in, pos) 33 | if err != nil { 34 | return nil, err 35 | } 36 | 37 | keyStart := pos 38 | // key 39 | pos, err = String(in, pos) 40 | if err != nil { 41 | return nil, err 42 | } 43 | key := in[keyStart+1 : pos-1] 44 | match := bytes.Equal(k, key) 45 | 46 | // leading spaces 47 | pos, err = skipSpace(in, pos) 48 | if err != nil { 49 | return nil, err 50 | } 51 | 52 | // colon 53 | pos, err = expect(in, pos, ':') 54 | if err != nil { 55 | return nil, err 56 | } 57 | 58 | pos, err = skipSpace(in, pos) 59 | if err != nil { 60 | return nil, err 61 | } 62 | 63 | valueStart := pos 64 | // data 65 | pos, err = Any(in, pos) 66 | if err != nil { 67 | return nil, err 68 | } 69 | 70 | if match { 71 | return in[valueStart:pos], nil 72 | } 73 | 74 | pos, err = skipSpace(in, pos) 75 | if err != nil { 76 | return nil, err 77 | } 78 | 79 | switch in[pos] { 80 | case ',': 81 | pos++ 82 | case '}': 83 | return nil, errKeyNotFound 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/scanner/find_key_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Matt Ho 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package scanner_test 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/gabesullice/jq/scanner" 21 | ) 22 | 23 | func BenchmarkFindKey(t *testing.B) { 24 | data := []byte(`{"hello":"world"}`) 25 | 26 | for i := 0; i < t.N; i++ { 27 | out, err := scanner.FindKey(data, 0, []byte("hello")) 28 | if err != nil { 29 | t.FailNow() 30 | return 31 | } 32 | 33 | if string(out) != `"world"` { 34 | t.FailNow() 35 | return 36 | } 37 | } 38 | } 39 | 40 | func TestFindKey(t *testing.T) { 41 | testCases := map[string]struct { 42 | In string 43 | Key string 44 | Expected string 45 | HasErr bool 46 | }{ 47 | "simple": { 48 | In: `{"hello":"world"}`, 49 | Key: "hello", 50 | Expected: `"world"`, 51 | }, 52 | "spaced": { 53 | In: ` { "hello" : "world" } `, 54 | Key: "hello", 55 | Expected: `"world"`, 56 | }, 57 | } 58 | 59 | for label, tc := range testCases { 60 | t.Run(label, func(t *testing.T) { 61 | data, err := scanner.FindKey([]byte(tc.In), 0, []byte(tc.Key)) 62 | if tc.HasErr { 63 | if err == nil { 64 | t.FailNow() 65 | } 66 | } else { 67 | if string(data) != tc.Expected { 68 | t.FailNow() 69 | } 70 | if err != nil { 71 | t.FailNow() 72 | } 73 | } 74 | }) 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/scanner/find_range.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Matt Ho 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package scanner 16 | 17 | // FindRange finds the elements of an array between the specified indexes; inclusive 18 | func FindRange(in []byte, pos, from, to int) ([]byte, error) { 19 | if to < from { 20 | return nil, errToLessThanFrom 21 | } 22 | 23 | pos, err := skipSpace(in, pos) 24 | if err != nil { 25 | return nil, err 26 | } 27 | 28 | if v := in[pos]; v != '[' { 29 | return nil, newError(pos, v) 30 | } 31 | pos++ 32 | 33 | idx := 0 34 | itemStart := pos 35 | 36 | for { 37 | pos, err = skipSpace(in, pos) 38 | if err != nil { 39 | return nil, err 40 | } 41 | 42 | if idx == from { 43 | itemStart = pos 44 | } 45 | 46 | // data 47 | pos, err = Any(in, pos) 48 | if err != nil { 49 | return nil, err 50 | } 51 | 52 | if idx == to { 53 | data := in[itemStart:pos] 54 | result := make([]byte, 0, len(data)+2) 55 | result = append(result, '[') 56 | result = append(result, data...) 57 | result = append(result, ']') 58 | return result, nil 59 | } 60 | 61 | pos, err = skipSpace(in, pos) 62 | if err != nil { 63 | return nil, err 64 | } 65 | 66 | switch in[pos] { 67 | case ',': 68 | pos++ 69 | case ']': 70 | return nil, errIndexOutOfBounds 71 | } 72 | 73 | idx++ 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/scanner/find_range_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Matt Ho 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package scanner_test 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/gabesullice/jq/scanner" 21 | ) 22 | 23 | func BenchmarkFindRange(t *testing.B) { 24 | data := []byte(`["a","b","c","d","e"]`) 25 | 26 | for i := 0; i < t.N; i++ { 27 | out, err := scanner.FindRange(data, 0, 1, 2) 28 | if err != nil { 29 | t.FailNow() 30 | return 31 | } 32 | 33 | if string(out) != `["b","c"]` { 34 | t.FailNow() 35 | return 36 | } 37 | } 38 | } 39 | 40 | func TestFindRange(t *testing.T) { 41 | testCases := map[string]struct { 42 | In string 43 | From int 44 | To int 45 | Expected string 46 | HasErr bool 47 | }{ 48 | "simple": { 49 | In: `["a","b","c","d","e"]`, 50 | From: 1, 51 | To: 2, 52 | Expected: `["b","c"]`, 53 | }, 54 | "single": { 55 | In: `["a","b","c","d","e"]`, 56 | From: 1, 57 | To: 1, 58 | Expected: `["b"]`, 59 | }, 60 | "mixed": { 61 | In: `["a",{"hello":"world"},"c","d","e"]`, 62 | From: 1, 63 | To: 1, 64 | Expected: `[{"hello":"world"}]`, 65 | }, 66 | "ordering": { 67 | In: `["a",{"hello":"world"},"c","d","e"]`, 68 | From: 1, 69 | To: 0, 70 | HasErr: true, 71 | }, 72 | "out of bounds": { 73 | In: `["a",{"hello":"world"},"c","d","e"]`, 74 | From: 1, 75 | To: 20, 76 | HasErr: true, 77 | }, 78 | } 79 | 80 | for label, tc := range testCases { 81 | t.Run(label, func(t *testing.T) { 82 | data, err := scanner.FindRange([]byte(tc.In), 0, tc.From, tc.To) 83 | if tc.HasErr { 84 | if err == nil { 85 | t.FailNow() 86 | } 87 | } else { 88 | if string(data) != tc.Expected { 89 | t.FailNow() 90 | } 91 | if err != nil { 92 | t.FailNow() 93 | } 94 | } 95 | }) 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/scanner/find_to.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Matt Ho 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package scanner 16 | 17 | // FindTo finds the elements of an array between the specified indexes; inclusive 18 | func FindTo(in []byte, pos, to int) ([]byte, error) { 19 | pos, err := skipSpace(in, pos) 20 | if err != nil { 21 | return nil, err 22 | } 23 | 24 | if v := in[pos]; v != '[' { 25 | return nil, newError(pos, v) 26 | } 27 | pos++ 28 | 29 | idx := 0 30 | itemStart := pos 31 | 32 | for { 33 | pos, err = skipSpace(in, pos) 34 | if err != nil { 35 | return nil, err 36 | } 37 | 38 | // data 39 | pos, err = Any(in, pos) 40 | if err != nil { 41 | return nil, err 42 | } 43 | 44 | if idx == to { 45 | data := in[itemStart:pos] 46 | result := make([]byte, 0, len(data)+2) 47 | result = append(result, '[') 48 | result = append(result, data...) 49 | result = append(result, ']') 50 | return result, nil 51 | } 52 | 53 | pos, err = skipSpace(in, pos) 54 | if err != nil { 55 | return nil, err 56 | } 57 | 58 | switch in[pos] { 59 | case ',': 60 | pos++ 61 | case ']': 62 | return nil, errIndexOutOfBounds 63 | } 64 | 65 | idx++ 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/scanner/find_to_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Matt Ho 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package scanner_test 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/gabesullice/jq/scanner" 21 | ) 22 | 23 | func TestFindTo(t *testing.T) { 24 | testCases := map[string]struct { 25 | In string 26 | To int 27 | Expected string 28 | HasErr bool 29 | }{ 30 | "first": { 31 | In: `["a","b","c","d","e"]`, 32 | To: 0, 33 | Expected: `["a"]`, 34 | }, 35 | "second": { 36 | In: `["a","b","c","d","e"]`, 37 | To: 1, 38 | Expected: `["a","b"]`, 39 | }, 40 | "mixed": { 41 | In: `["a",{"hello":"world"},"c","d","e"]`, 42 | To: 1, 43 | Expected: `["a",{"hello":"world"}]`, 44 | }, 45 | "negative": { 46 | In: `["a",{"hello":"world"},"c","d","e"]`, 47 | To: -1, 48 | HasErr: true, 49 | }, 50 | "out of bounds": { 51 | In: `["a",{"hello":"world"},"c","d","e"]`, 52 | To: 20, 53 | HasErr: true, 54 | }, 55 | } 56 | 57 | for label, tc := range testCases { 58 | t.Run(label, func(t *testing.T) { 59 | data, err := scanner.FindTo([]byte(tc.In), 0, tc.To) 60 | if tc.HasErr { 61 | if err == nil { 62 | t.FailNow() 63 | } 64 | } else { 65 | if string(data) != tc.Expected { 66 | t.FailNow() 67 | } 68 | if err != nil { 69 | t.FailNow() 70 | } 71 | } 72 | }) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/scanner/null.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Matt Ho 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package scanner 16 | 17 | var ( 18 | n = []byte("null") 19 | ) 20 | 21 | // Null verifies the contents of bytes provided is a null starting as pos 22 | func Null(in []byte, pos int) (int, error) { 23 | switch in[pos] { 24 | case 'n': 25 | return expect(in, pos, n...) 26 | return pos + 4, nil 27 | default: 28 | return 0, errUnexpectedValue 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/scanner/null_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Matt Ho 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package scanner_test 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/gabesullice/jq/scanner" 21 | ) 22 | 23 | func BenchmarkNull(t *testing.B) { 24 | data := []byte("null") 25 | for i := 0; i < t.N; i++ { 26 | pos, err := scanner.Null(data, 0) 27 | if err != nil { 28 | t.FailNow() 29 | } 30 | if pos != 4 { 31 | t.FailNow() 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/scanner/number.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Matt Ho 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package scanner 16 | 17 | // Number returns the end position of the number that begins at the specified pos 18 | func Number(in []byte, pos int) (int, error) { 19 | pos, err := skipSpace(in, pos) 20 | if err != nil { 21 | return 0, err 22 | } 23 | 24 | max := len(in) 25 | for { 26 | v := in[pos] 27 | switch v { 28 | case '-', '+', '.', 'e', 'E', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0': 29 | pos++ 30 | default: 31 | return pos, nil 32 | } 33 | 34 | if pos >= max { 35 | return pos, nil 36 | } 37 | } 38 | 39 | return pos, nil 40 | } 41 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/scanner/number_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Matt Ho 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package scanner_test 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/gabesullice/jq/scanner" 21 | ) 22 | 23 | func BenchmarkNumber(t *testing.B) { 24 | data := []byte(`12.34e+9`) 25 | 26 | for i := 0; i < t.N; i++ { 27 | end, err := scanner.Number(data, 0) 28 | if err != nil { 29 | t.FailNow() 30 | return 31 | } 32 | 33 | if end == 0 { 34 | t.FailNow() 35 | return 36 | } 37 | } 38 | } 39 | 40 | func TestNumber(t *testing.T) { 41 | testCases := map[string]struct { 42 | In string 43 | Out string 44 | HasErr bool 45 | }{ 46 | "simple": { 47 | In: `1234`, 48 | Out: `1234`, 49 | }, 50 | "decimal": { 51 | In: `1.234`, 52 | Out: `1.234`, 53 | }, 54 | "spaced": { 55 | In: ` 1.234 `, 56 | Out: ` 1.234`, 57 | }, 58 | "kitchen-sink": { 59 | In: ` +-123.25eE10 `, 60 | Out: ` +-123.25eE10`, 61 | }, 62 | } 63 | 64 | for label, tc := range testCases { 65 | t.Run(label, func(t *testing.T) { 66 | end, err := scanner.Number([]byte(tc.In), 0) 67 | if tc.HasErr { 68 | if err == nil { 69 | t.FailNow() 70 | } 71 | } else { 72 | data := tc.In[0:end] 73 | if string(data) != tc.Out { 74 | t.FailNow() 75 | } 76 | if err != nil { 77 | t.FailNow() 78 | } 79 | } 80 | }) 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/scanner/object.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Matt Ho 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package scanner 16 | 17 | // Object returns the position of the end of the object that begins at the specified pos 18 | func Object(in []byte, pos int) (int, error) { 19 | pos, err := skipSpace(in, pos) 20 | if err != nil { 21 | return 0, err 22 | } 23 | 24 | if v := in[pos]; v != '{' { 25 | return 0, newError(pos, v) 26 | } 27 | pos++ 28 | 29 | // clean initial spaces 30 | pos, err = skipSpace(in, pos) 31 | if err != nil { 32 | return 0, err 33 | } 34 | 35 | if in[pos] == '}' { 36 | return pos + 1, nil 37 | } 38 | 39 | for { 40 | // key 41 | pos, err = String(in, pos) 42 | if err != nil { 43 | return 0, err 44 | } 45 | 46 | // leading spaces 47 | pos, err = skipSpace(in, pos) 48 | if err != nil { 49 | return 0, err 50 | } 51 | 52 | // colon 53 | pos, err = expect(in, pos, ':') 54 | if err != nil { 55 | return 0, err 56 | } 57 | 58 | // data 59 | pos, err = Any(in, pos) 60 | if err != nil { 61 | return 0, err 62 | } 63 | 64 | pos, err = skipSpace(in, pos) 65 | if err != nil { 66 | return 0, err 67 | } 68 | 69 | switch in[pos] { 70 | case ',': 71 | pos++ 72 | case '}': 73 | return pos + 1, nil 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/scanner/object_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Matt Ho 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package scanner_test 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/gabesullice/jq/scanner" 21 | ) 22 | 23 | func BenchmarkObject(t *testing.B) { 24 | data := []byte(`{"hello":"world"}`) 25 | 26 | for i := 0; i < t.N; i++ { 27 | end, err := scanner.Object(data, 0) 28 | if err != nil { 29 | t.FailNow() 30 | return 31 | } 32 | 33 | if end == 0 { 34 | t.FailNow() 35 | return 36 | } 37 | } 38 | } 39 | 40 | func TestObject(t *testing.T) { 41 | testCases := map[string]struct { 42 | In string 43 | Out string 44 | HasErr bool 45 | }{ 46 | "simple": { 47 | In: `{"hello":"world"}`, 48 | Out: `{"hello":"world"}`, 49 | }, 50 | "empty": { 51 | In: `{}`, 52 | Out: `{}`, 53 | }, 54 | "spaced": { 55 | In: ` { "hello" : "world" } `, 56 | Out: ` { "hello" : "world" }`, 57 | }, 58 | } 59 | 60 | for label, tc := range testCases { 61 | t.Run(label, func(t *testing.T) { 62 | end, err := scanner.Object([]byte(tc.In), 0) 63 | if tc.HasErr { 64 | if err == nil { 65 | t.FailNow() 66 | } 67 | } else { 68 | data := tc.In[0:end] 69 | if string(data) != tc.Out { 70 | t.FailNow() 71 | } 72 | if err != nil { 73 | t.FailNow() 74 | } 75 | } 76 | }) 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/scanner/string.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Matt Ho 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package scanner 16 | 17 | import "errors" 18 | 19 | // String returns the position of the string that begins at the specified pos 20 | func String(in []byte, pos int) (int, error) { 21 | pos, err := skipSpace(in, pos) 22 | if err != nil { 23 | return 0, err 24 | } 25 | 26 | max := len(in) 27 | 28 | if v := in[pos]; v != '"' { 29 | return 0, newError(pos, v) 30 | } 31 | pos++ 32 | 33 | for { 34 | switch in[pos] { 35 | case '\\': 36 | if in[pos+1] == '"' { 37 | pos++ 38 | } 39 | case '"': 40 | return pos + 1, nil 41 | } 42 | pos++ 43 | 44 | if pos >= max { 45 | break 46 | } 47 | } 48 | 49 | return 0, errors.New("unclosed string") 50 | } 51 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/scanner/string_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Matt Ho 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package scanner_test 16 | 17 | import ( 18 | "testing" 19 | "unicode/utf8" 20 | 21 | "github.com/gabesullice/jq/scanner" 22 | ) 23 | 24 | func BenchmarkString(t *testing.B) { 25 | data := []byte(`"hello world"`) 26 | 27 | for i := 0; i < t.N; i++ { 28 | end, err := scanner.String(data, 0) 29 | if err != nil { 30 | t.FailNow() 31 | return 32 | } 33 | 34 | if end == 0 { 35 | t.FailNow() 36 | return 37 | } 38 | } 39 | } 40 | 41 | func TestString(t *testing.T) { 42 | testCases := map[string]struct { 43 | In string 44 | Out string 45 | HasErr bool 46 | }{ 47 | "simple": { 48 | In: `"hello"`, 49 | Out: `"hello"`, 50 | }, 51 | "array": { 52 | In: `"hello", "world"`, 53 | Out: `"hello"`, 54 | }, 55 | "escaped": { 56 | In: `"hello\"\"world"`, 57 | Out: `"hello\"\"world"`, 58 | }, 59 | "unclosed": { 60 | In: `"hello`, 61 | HasErr: true, 62 | }, 63 | "unclosed escape": { 64 | In: `"hello\"`, 65 | HasErr: true, 66 | }, 67 | "utf8": { 68 | In: `"生日快乐"`, 69 | Out: `"生日快乐"`, 70 | }, 71 | } 72 | 73 | for label, tc := range testCases { 74 | t.Run(label, func(t *testing.T) { 75 | end, err := scanner.String([]byte(tc.In), 0) 76 | if tc.HasErr { 77 | if err == nil { 78 | t.FailNow() 79 | } 80 | } else { 81 | data := tc.In[0:end] 82 | if string(data) != tc.Out { 83 | t.FailNow() 84 | } 85 | if err != nil { 86 | t.FailNow() 87 | } 88 | } 89 | }) 90 | } 91 | } 92 | 93 | func TestDecode(t *testing.T) { 94 | v := "" 95 | _, size := utf8.DecodeRune([]byte(v)) 96 | if size != 0 { 97 | t.FailNow() 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/scanner/util.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Matt Ho 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package scanner 16 | 17 | import ( 18 | "errors" 19 | "fmt" 20 | "unicode" 21 | "unicode/utf8" 22 | ) 23 | 24 | var ( 25 | errUnexpectedEOF = errors.New("unexpected EOF") 26 | errKeyNotFound = errors.New("key not found") 27 | errIndexOutOfBounds = errors.New("index out of bounds") 28 | errToLessThanFrom = errors.New("to index less than from index") 29 | errFromOutOfBounds = errors.New("from index out of bounds") 30 | errUnexpectedValue = errors.New("unexpected value") 31 | ) 32 | 33 | func skipSpace(in []byte, pos int) (int, error) { 34 | for { 35 | r, size := utf8.DecodeRune(in[pos:]) 36 | if size == 0 { 37 | return 0, errUnexpectedEOF 38 | } 39 | if !unicode.IsSpace(r) { 40 | break 41 | } 42 | pos += size 43 | } 44 | 45 | return pos, nil 46 | } 47 | 48 | func expect(in []byte, pos int, content ...byte) (int, error) { 49 | if pos+len(content) > len(in) { 50 | return 0, errUnexpectedEOF 51 | } 52 | 53 | for _, b := range content { 54 | if v := in[pos]; v != b { 55 | return 0, errUnexpectedValue 56 | } 57 | pos++ 58 | } 59 | 60 | return pos, nil 61 | } 62 | 63 | func newError(pos int, b byte) error { 64 | return fmt.Errorf("invalid character at position, %v; %v", pos, string([]byte{b})) 65 | } 66 | -------------------------------------------------------------------------------- /vendor/github.com/gabesullice/jq/scanner/util_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Matt Ho 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package scanner 16 | 17 | import ( 18 | "fmt" 19 | "testing" 20 | ) 21 | 22 | func TestSkipSpace(t *testing.T) { 23 | content := []byte(" \t\n\r!") 24 | end, err := skipSpace(content, 0) 25 | if err != nil { 26 | t.FailNow() 27 | } 28 | if end+1 != len(content) { 29 | t.FailNow() 30 | } 31 | } 32 | 33 | func TestExpect(t *testing.T) { 34 | testCases := map[string]struct { 35 | In string 36 | Expected string 37 | HasError bool 38 | }{ 39 | "simple": { 40 | In: "abc", 41 | Expected: "abc", 42 | }, 43 | "extra": { 44 | In: "abcdef", 45 | Expected: "abc", 46 | }, 47 | "no match": { 48 | In: "abc", 49 | Expected: "def", 50 | HasError: true, 51 | }, 52 | "unexpected EOF": { 53 | In: "ab", 54 | Expected: "abc", 55 | HasError: true, 56 | }, 57 | } 58 | 59 | for label, tc := range testCases { 60 | t.Run(label, func(t *testing.T) { 61 | pos, err := expect([]byte(tc.In), 0, []byte(tc.Expected)...) 62 | if tc.HasError { 63 | if err == nil { 64 | t.FailNow() 65 | } 66 | 67 | } else { 68 | if err != nil { 69 | fmt.Println(err) 70 | t.FailNow() 71 | } 72 | if pos != len([]byte(tc.Expected)) { 73 | t.FailNow() 74 | } 75 | 76 | } 77 | }) 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /vendor/github.com/satori/go.uuid/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | sudo: false 3 | go: 4 | - 1.2 5 | - 1.3 6 | - 1.4 7 | - 1.5 8 | - 1.6 9 | - 1.7 10 | - 1.8 11 | - 1.9 12 | - tip 13 | matrix: 14 | allow_failures: 15 | - go: tip 16 | fast_finish: true 17 | before_install: 18 | - go get github.com/mattn/goveralls 19 | - go get golang.org/x/tools/cmd/cover 20 | script: 21 | - $HOME/gopath/bin/goveralls -service=travis-ci 22 | notifications: 23 | email: false 24 | -------------------------------------------------------------------------------- /vendor/github.com/satori/go.uuid/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2013-2018 by Maxim Bublis 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /vendor/github.com/satori/go.uuid/README.md: -------------------------------------------------------------------------------- 1 | # UUID package for Go language 2 | 3 | [![Build Status](https://travis-ci.org/satori/go.uuid.png?branch=master)](https://travis-ci.org/satori/go.uuid) 4 | [![Coverage Status](https://coveralls.io/repos/github/satori/go.uuid/badge.svg?branch=master)](https://coveralls.io/github/satori/go.uuid) 5 | [![GoDoc](http://godoc.org/github.com/satori/go.uuid?status.png)](http://godoc.org/github.com/satori/go.uuid) 6 | 7 | This package provides pure Go implementation of Universally Unique Identifier (UUID). Supported both creation and parsing of UUIDs. 8 | 9 | With 100% test coverage and benchmarks out of box. 10 | 11 | Supported versions: 12 | * Version 1, based on timestamp and MAC address (RFC 4122) 13 | * Version 2, based on timestamp, MAC address and POSIX UID/GID (DCE 1.1) 14 | * Version 3, based on MD5 hashing (RFC 4122) 15 | * Version 4, based on random numbers (RFC 4122) 16 | * Version 5, based on SHA-1 hashing (RFC 4122) 17 | 18 | ## Installation 19 | 20 | Use the `go` command: 21 | 22 | $ go get github.com/satori/go.uuid 23 | 24 | ## Requirements 25 | 26 | UUID package requires Go >= 1.2. 27 | 28 | ## Example 29 | 30 | ```go 31 | package main 32 | 33 | import ( 34 | "fmt" 35 | "github.com/satori/go.uuid" 36 | ) 37 | 38 | func main() { 39 | // Creating UUID Version 4 40 | u1 := uuid.NewV4() 41 | fmt.Printf("UUIDv4: %s\n", u1) 42 | 43 | // Parsing UUID from string input 44 | u2, err := uuid.FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8") 45 | if err != nil { 46 | fmt.Printf("Something gone wrong: %s", err) 47 | } 48 | fmt.Printf("Successfully parsed: %s", u2) 49 | } 50 | ``` 51 | 52 | ## Documentation 53 | 54 | [Documentation](http://godoc.org/github.com/satori/go.uuid) is hosted at GoDoc project. 55 | 56 | ## Links 57 | * [RFC 4122](http://tools.ietf.org/html/rfc4122) 58 | * [DCE 1.1: Authentication and Security Services](http://pubs.opengroup.org/onlinepubs/9696989899/chap5.htm#tagcjh_08_02_01_01) 59 | 60 | ## Copyright 61 | 62 | Copyright (C) 2013-2018 by Maxim Bublis . 63 | 64 | UUID package released under MIT License. 65 | See [LICENSE](https://github.com/satori/go.uuid/blob/master/LICENSE) for details. 66 | -------------------------------------------------------------------------------- /vendor/github.com/satori/go.uuid/codec.go: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013-2018 by Maxim Bublis 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining 4 | // a copy of this software and associated documentation files (the 5 | // "Software"), to deal in the Software without restriction, including 6 | // without limitation the rights to use, copy, modify, merge, publish, 7 | // distribute, sublicense, and/or sell copies of the Software, and to 8 | // permit persons to whom the Software is furnished to do so, subject to 9 | // the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be 12 | // included in all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | package uuid 23 | 24 | import ( 25 | "bytes" 26 | "encoding/hex" 27 | "fmt" 28 | ) 29 | 30 | // FromBytes returns UUID converted from raw byte slice input. 31 | // It will return error if the slice isn't 16 bytes long. 32 | func FromBytes(input []byte) (u UUID, err error) { 33 | err = u.UnmarshalBinary(input) 34 | return 35 | } 36 | 37 | // FromBytesOrNil returns UUID converted from raw byte slice input. 38 | // Same behavior as FromBytes, but returns a Nil UUID on error. 39 | func FromBytesOrNil(input []byte) UUID { 40 | uuid, err := FromBytes(input) 41 | if err != nil { 42 | return Nil 43 | } 44 | return uuid 45 | } 46 | 47 | // FromString returns UUID parsed from string input. 48 | // Input is expected in a form accepted by UnmarshalText. 49 | func FromString(input string) (u UUID, err error) { 50 | err = u.UnmarshalText([]byte(input)) 51 | return 52 | } 53 | 54 | // FromStringOrNil returns UUID parsed from string input. 55 | // Same behavior as FromString, but returns a Nil UUID on error. 56 | func FromStringOrNil(input string) UUID { 57 | uuid, err := FromString(input) 58 | if err != nil { 59 | return Nil 60 | } 61 | return uuid 62 | } 63 | 64 | // MarshalText implements the encoding.TextMarshaler interface. 65 | // The encoding is the same as returned by String. 66 | func (u UUID) MarshalText() (text []byte, err error) { 67 | text = []byte(u.String()) 68 | return 69 | } 70 | 71 | // UnmarshalText implements the encoding.TextUnmarshaler interface. 72 | // Following formats are supported: 73 | // "6ba7b810-9dad-11d1-80b4-00c04fd430c8", 74 | // "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}", 75 | // "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8" 76 | // "6ba7b8109dad11d180b400c04fd430c8" 77 | // ABNF for supported UUID text representation follows: 78 | // uuid := canonical | hashlike | braced | urn 79 | // plain := canonical | hashlike 80 | // canonical := 4hexoct '-' 2hexoct '-' 2hexoct '-' 6hexoct 81 | // hashlike := 12hexoct 82 | // braced := '{' plain '}' 83 | // urn := URN ':' UUID-NID ':' plain 84 | // URN := 'urn' 85 | // UUID-NID := 'uuid' 86 | // 12hexoct := 6hexoct 6hexoct 87 | // 6hexoct := 4hexoct 2hexoct 88 | // 4hexoct := 2hexoct 2hexoct 89 | // 2hexoct := hexoct hexoct 90 | // hexoct := hexdig hexdig 91 | // hexdig := '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | 92 | // 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 93 | // 'A' | 'B' | 'C' | 'D' | 'E' | 'F' 94 | func (u *UUID) UnmarshalText(text []byte) (err error) { 95 | switch len(text) { 96 | case 32: 97 | return u.decodeHashLike(text) 98 | case 36: 99 | return u.decodeCanonical(text) 100 | case 38: 101 | return u.decodeBraced(text) 102 | case 41: 103 | fallthrough 104 | case 45: 105 | return u.decodeURN(text) 106 | default: 107 | return fmt.Errorf("uuid: incorrect UUID length: %s", text) 108 | } 109 | } 110 | 111 | // decodeCanonical decodes UUID string in format 112 | // "6ba7b810-9dad-11d1-80b4-00c04fd430c8". 113 | func (u *UUID) decodeCanonical(t []byte) (err error) { 114 | if t[8] != '-' || t[13] != '-' || t[18] != '-' || t[23] != '-' { 115 | return fmt.Errorf("uuid: incorrect UUID format %s", t) 116 | } 117 | 118 | src := t[:] 119 | dst := u[:] 120 | 121 | for i, byteGroup := range byteGroups { 122 | if i > 0 { 123 | src = src[1:] // skip dash 124 | } 125 | _, err = hex.Decode(dst[:byteGroup/2], src[:byteGroup]) 126 | if err != nil { 127 | return 128 | } 129 | src = src[byteGroup:] 130 | dst = dst[byteGroup/2:] 131 | } 132 | 133 | return 134 | } 135 | 136 | // decodeHashLike decodes UUID string in format 137 | // "6ba7b8109dad11d180b400c04fd430c8". 138 | func (u *UUID) decodeHashLike(t []byte) (err error) { 139 | src := t[:] 140 | dst := u[:] 141 | 142 | if _, err = hex.Decode(dst, src); err != nil { 143 | return err 144 | } 145 | return 146 | } 147 | 148 | // decodeBraced decodes UUID string in format 149 | // "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}" or in format 150 | // "{6ba7b8109dad11d180b400c04fd430c8}". 151 | func (u *UUID) decodeBraced(t []byte) (err error) { 152 | l := len(t) 153 | 154 | if t[0] != '{' || t[l-1] != '}' { 155 | return fmt.Errorf("uuid: incorrect UUID format %s", t) 156 | } 157 | 158 | return u.decodePlain(t[1 : l-1]) 159 | } 160 | 161 | // decodeURN decodes UUID string in format 162 | // "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8" or in format 163 | // "urn:uuid:6ba7b8109dad11d180b400c04fd430c8". 164 | func (u *UUID) decodeURN(t []byte) (err error) { 165 | total := len(t) 166 | 167 | urn_uuid_prefix := t[:9] 168 | 169 | if !bytes.Equal(urn_uuid_prefix, urnPrefix) { 170 | return fmt.Errorf("uuid: incorrect UUID format: %s", t) 171 | } 172 | 173 | return u.decodePlain(t[9:total]) 174 | } 175 | 176 | // decodePlain decodes UUID string in canonical format 177 | // "6ba7b810-9dad-11d1-80b4-00c04fd430c8" or in hash-like format 178 | // "6ba7b8109dad11d180b400c04fd430c8". 179 | func (u *UUID) decodePlain(t []byte) (err error) { 180 | switch len(t) { 181 | case 32: 182 | return u.decodeHashLike(t) 183 | case 36: 184 | return u.decodeCanonical(t) 185 | default: 186 | return fmt.Errorf("uuid: incorrrect UUID length: %s", t) 187 | } 188 | } 189 | 190 | // MarshalBinary implements the encoding.BinaryMarshaler interface. 191 | func (u UUID) MarshalBinary() (data []byte, err error) { 192 | data = u.Bytes() 193 | return 194 | } 195 | 196 | // UnmarshalBinary implements the encoding.BinaryUnmarshaler interface. 197 | // It will return error if the slice isn't 16 bytes long. 198 | func (u *UUID) UnmarshalBinary(data []byte) (err error) { 199 | if len(data) != Size { 200 | err = fmt.Errorf("uuid: UUID must be exactly 16 bytes long, got %d bytes", len(data)) 201 | return 202 | } 203 | copy(u[:], data) 204 | 205 | return 206 | } 207 | -------------------------------------------------------------------------------- /vendor/github.com/satori/go.uuid/codec_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013-2018 by Maxim Bublis 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining 4 | // a copy of this software and associated documentation files (the 5 | // "Software"), to deal in the Software without restriction, including 6 | // without limitation the rights to use, copy, modify, merge, publish, 7 | // distribute, sublicense, and/or sell copies of the Software, and to 8 | // permit persons to whom the Software is furnished to do so, subject to 9 | // the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be 12 | // included in all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | package uuid 23 | 24 | import ( 25 | "bytes" 26 | 27 | . "gopkg.in/check.v1" 28 | ) 29 | 30 | type codecTestSuite struct{} 31 | 32 | var _ = Suite(&codecTestSuite{}) 33 | 34 | func (s *codecTestSuite) TestFromBytes(c *C) { 35 | u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 36 | b1 := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 37 | 38 | u1, err := FromBytes(b1) 39 | c.Assert(err, IsNil) 40 | c.Assert(u1, Equals, u) 41 | 42 | b2 := []byte{} 43 | _, err = FromBytes(b2) 44 | c.Assert(err, NotNil) 45 | } 46 | 47 | func (s *codecTestSuite) BenchmarkFromBytes(c *C) { 48 | bytes := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 49 | for i := 0; i < c.N; i++ { 50 | FromBytes(bytes) 51 | } 52 | } 53 | 54 | func (s *codecTestSuite) TestMarshalBinary(c *C) { 55 | u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 56 | b1 := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 57 | 58 | b2, err := u.MarshalBinary() 59 | c.Assert(err, IsNil) 60 | c.Assert(bytes.Equal(b1, b2), Equals, true) 61 | } 62 | 63 | func (s *codecTestSuite) BenchmarkMarshalBinary(c *C) { 64 | u := NewV4() 65 | for i := 0; i < c.N; i++ { 66 | u.MarshalBinary() 67 | } 68 | } 69 | 70 | func (s *codecTestSuite) TestUnmarshalBinary(c *C) { 71 | u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 72 | b1 := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 73 | 74 | u1 := UUID{} 75 | err := u1.UnmarshalBinary(b1) 76 | c.Assert(err, IsNil) 77 | c.Assert(u1, Equals, u) 78 | 79 | b2 := []byte{} 80 | u2 := UUID{} 81 | err = u2.UnmarshalBinary(b2) 82 | c.Assert(err, NotNil) 83 | } 84 | 85 | func (s *codecTestSuite) TestFromString(c *C) { 86 | u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 87 | 88 | s1 := "6ba7b810-9dad-11d1-80b4-00c04fd430c8" 89 | s2 := "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}" 90 | s3 := "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8" 91 | s4 := "6ba7b8109dad11d180b400c04fd430c8" 92 | s5 := "urn:uuid:6ba7b8109dad11d180b400c04fd430c8" 93 | 94 | _, err := FromString("") 95 | c.Assert(err, NotNil) 96 | 97 | u1, err := FromString(s1) 98 | c.Assert(err, IsNil) 99 | c.Assert(u1, Equals, u) 100 | 101 | u2, err := FromString(s2) 102 | c.Assert(err, IsNil) 103 | c.Assert(u2, Equals, u) 104 | 105 | u3, err := FromString(s3) 106 | c.Assert(err, IsNil) 107 | c.Assert(u3, Equals, u) 108 | 109 | u4, err := FromString(s4) 110 | c.Assert(err, IsNil) 111 | c.Assert(u4, Equals, u) 112 | 113 | u5, err := FromString(s5) 114 | c.Assert(err, IsNil) 115 | c.Assert(u5, Equals, u) 116 | } 117 | 118 | func (s *codecTestSuite) BenchmarkFromString(c *C) { 119 | str := "6ba7b810-9dad-11d1-80b4-00c04fd430c8" 120 | for i := 0; i < c.N; i++ { 121 | FromString(str) 122 | } 123 | } 124 | 125 | func (s *codecTestSuite) BenchmarkFromStringUrn(c *C) { 126 | str := "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8" 127 | for i := 0; i < c.N; i++ { 128 | FromString(str) 129 | } 130 | } 131 | 132 | func (s *codecTestSuite) BenchmarkFromStringWithBrackets(c *C) { 133 | str := "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}" 134 | for i := 0; i < c.N; i++ { 135 | FromString(str) 136 | } 137 | } 138 | 139 | func (s *codecTestSuite) TestFromStringShort(c *C) { 140 | // Invalid 35-character UUID string 141 | s1 := "6ba7b810-9dad-11d1-80b4-00c04fd430c" 142 | 143 | for i := len(s1); i >= 0; i-- { 144 | _, err := FromString(s1[:i]) 145 | c.Assert(err, NotNil) 146 | } 147 | } 148 | 149 | func (s *codecTestSuite) TestFromStringLong(c *C) { 150 | // Invalid 37+ character UUID string 151 | strings := []string{ 152 | "6ba7b810-9dad-11d1-80b4-00c04fd430c8=", 153 | "6ba7b810-9dad-11d1-80b4-00c04fd430c8}", 154 | "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}f", 155 | "6ba7b810-9dad-11d1-80b4-00c04fd430c800c04fd430c8", 156 | } 157 | 158 | for _, str := range strings { 159 | _, err := FromString(str) 160 | c.Assert(err, NotNil) 161 | } 162 | } 163 | 164 | func (s *codecTestSuite) TestFromStringInvalid(c *C) { 165 | // Invalid UUID string formats 166 | strings := []string{ 167 | "6ba7b8109dad11d180b400c04fd430c86ba7b8109dad11d180b400c04fd430c8", 168 | "urn:uuid:{6ba7b810-9dad-11d1-80b4-00c04fd430c8}", 169 | "uuid:urn:6ba7b810-9dad-11d1-80b4-00c04fd430c8", 170 | "uuid:urn:6ba7b8109dad11d180b400c04fd430c8", 171 | "6ba7b8109-dad-11d1-80b4-00c04fd430c8", 172 | "6ba7b810-9dad1-1d1-80b4-00c04fd430c8", 173 | "6ba7b810-9dad-11d18-0b4-00c04fd430c8", 174 | "6ba7b810-9dad-11d1-80b40-0c04fd430c8", 175 | "6ba7b810+9dad+11d1+80b4+00c04fd430c8", 176 | "(6ba7b810-9dad-11d1-80b4-00c04fd430c8}", 177 | "{6ba7b810-9dad-11d1-80b4-00c04fd430c8>", 178 | "zba7b810-9dad-11d1-80b4-00c04fd430c8", 179 | "6ba7b810-9dad11d180b400c04fd430c8", 180 | "6ba7b8109dad-11d180b400c04fd430c8", 181 | "6ba7b8109dad11d1-80b400c04fd430c8", 182 | "6ba7b8109dad11d180b4-00c04fd430c8", 183 | } 184 | 185 | for _, str := range strings { 186 | _, err := FromString(str) 187 | c.Assert(err, NotNil) 188 | } 189 | } 190 | 191 | func (s *codecTestSuite) TestFromStringOrNil(c *C) { 192 | u := FromStringOrNil("") 193 | c.Assert(u, Equals, Nil) 194 | } 195 | 196 | func (s *codecTestSuite) TestFromBytesOrNil(c *C) { 197 | b := []byte{} 198 | u := FromBytesOrNil(b) 199 | c.Assert(u, Equals, Nil) 200 | } 201 | 202 | func (s *codecTestSuite) TestMarshalText(c *C) { 203 | u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 204 | b1 := []byte("6ba7b810-9dad-11d1-80b4-00c04fd430c8") 205 | 206 | b2, err := u.MarshalText() 207 | c.Assert(err, IsNil) 208 | c.Assert(bytes.Equal(b1, b2), Equals, true) 209 | } 210 | 211 | func (s *codecTestSuite) BenchmarkMarshalText(c *C) { 212 | u := NewV4() 213 | for i := 0; i < c.N; i++ { 214 | u.MarshalText() 215 | } 216 | } 217 | 218 | func (s *codecTestSuite) TestUnmarshalText(c *C) { 219 | u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 220 | b1 := []byte("6ba7b810-9dad-11d1-80b4-00c04fd430c8") 221 | 222 | u1 := UUID{} 223 | err := u1.UnmarshalText(b1) 224 | c.Assert(err, IsNil) 225 | c.Assert(u1, Equals, u) 226 | 227 | b2 := []byte("") 228 | u2 := UUID{} 229 | err = u2.UnmarshalText(b2) 230 | c.Assert(err, NotNil) 231 | } 232 | 233 | func (s *codecTestSuite) BenchmarkUnmarshalText(c *C) { 234 | bytes := []byte("6ba7b810-9dad-11d1-80b4-00c04fd430c8") 235 | u := UUID{} 236 | for i := 0; i < c.N; i++ { 237 | u.UnmarshalText(bytes) 238 | } 239 | } 240 | 241 | var sink string 242 | 243 | func (s *codecTestSuite) BenchmarkMarshalToString(c *C) { 244 | u := NewV4() 245 | for i := 0; i < c.N; i++ { 246 | sink = u.String() 247 | } 248 | } 249 | -------------------------------------------------------------------------------- /vendor/github.com/satori/go.uuid/generator.go: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013-2018 by Maxim Bublis 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining 4 | // a copy of this software and associated documentation files (the 5 | // "Software"), to deal in the Software without restriction, including 6 | // without limitation the rights to use, copy, modify, merge, publish, 7 | // distribute, sublicense, and/or sell copies of the Software, and to 8 | // permit persons to whom the Software is furnished to do so, subject to 9 | // the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be 12 | // included in all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | package uuid 23 | 24 | import ( 25 | "crypto/md5" 26 | "crypto/rand" 27 | "crypto/sha1" 28 | "encoding/binary" 29 | "hash" 30 | "net" 31 | "os" 32 | "sync" 33 | "time" 34 | ) 35 | 36 | // Difference in 100-nanosecond intervals between 37 | // UUID epoch (October 15, 1582) and Unix epoch (January 1, 1970). 38 | const epochStart = 122192928000000000 39 | 40 | var ( 41 | global = newDefaultGenerator() 42 | 43 | epochFunc = unixTimeFunc 44 | posixUID = uint32(os.Getuid()) 45 | posixGID = uint32(os.Getgid()) 46 | ) 47 | 48 | // NewV1 returns UUID based on current timestamp and MAC address. 49 | func NewV1() UUID { 50 | return global.NewV1() 51 | } 52 | 53 | // NewV2 returns DCE Security UUID based on POSIX UID/GID. 54 | func NewV2(domain byte) UUID { 55 | return global.NewV2(domain) 56 | } 57 | 58 | // NewV3 returns UUID based on MD5 hash of namespace UUID and name. 59 | func NewV3(ns UUID, name string) UUID { 60 | return global.NewV3(ns, name) 61 | } 62 | 63 | // NewV4 returns random generated UUID. 64 | func NewV4() UUID { 65 | return global.NewV4() 66 | } 67 | 68 | // NewV5 returns UUID based on SHA-1 hash of namespace UUID and name. 69 | func NewV5(ns UUID, name string) UUID { 70 | return global.NewV5(ns, name) 71 | } 72 | 73 | // Generator provides interface for generating UUIDs. 74 | type Generator interface { 75 | NewV1() UUID 76 | NewV2(domain byte) UUID 77 | NewV3(ns UUID, name string) UUID 78 | NewV4() UUID 79 | NewV5(ns UUID, name string) UUID 80 | } 81 | 82 | // Default generator implementation. 83 | type generator struct { 84 | storageOnce sync.Once 85 | storageMutex sync.Mutex 86 | 87 | lastTime uint64 88 | clockSequence uint16 89 | hardwareAddr [6]byte 90 | } 91 | 92 | func newDefaultGenerator() Generator { 93 | return &generator{} 94 | } 95 | 96 | // NewV1 returns UUID based on current timestamp and MAC address. 97 | func (g *generator) NewV1() UUID { 98 | u := UUID{} 99 | 100 | timeNow, clockSeq, hardwareAddr := g.getStorage() 101 | 102 | binary.BigEndian.PutUint32(u[0:], uint32(timeNow)) 103 | binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32)) 104 | binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48)) 105 | binary.BigEndian.PutUint16(u[8:], clockSeq) 106 | 107 | copy(u[10:], hardwareAddr) 108 | 109 | u.SetVersion(V1) 110 | u.SetVariant(VariantRFC4122) 111 | 112 | return u 113 | } 114 | 115 | // NewV2 returns DCE Security UUID based on POSIX UID/GID. 116 | func (g *generator) NewV2(domain byte) UUID { 117 | u := UUID{} 118 | 119 | timeNow, clockSeq, hardwareAddr := g.getStorage() 120 | 121 | switch domain { 122 | case DomainPerson: 123 | binary.BigEndian.PutUint32(u[0:], posixUID) 124 | case DomainGroup: 125 | binary.BigEndian.PutUint32(u[0:], posixGID) 126 | } 127 | 128 | binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32)) 129 | binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48)) 130 | binary.BigEndian.PutUint16(u[8:], clockSeq) 131 | u[9] = domain 132 | 133 | copy(u[10:], hardwareAddr) 134 | 135 | u.SetVersion(V2) 136 | u.SetVariant(VariantRFC4122) 137 | 138 | return u 139 | } 140 | 141 | // NewV3 returns UUID based on MD5 hash of namespace UUID and name. 142 | func (g *generator) NewV3(ns UUID, name string) UUID { 143 | u := newFromHash(md5.New(), ns, name) 144 | u.SetVersion(V3) 145 | u.SetVariant(VariantRFC4122) 146 | 147 | return u 148 | } 149 | 150 | // NewV4 returns random generated UUID. 151 | func (g *generator) NewV4() UUID { 152 | u := UUID{} 153 | g.safeRandom(u[:]) 154 | u.SetVersion(V4) 155 | u.SetVariant(VariantRFC4122) 156 | 157 | return u 158 | } 159 | 160 | // NewV5 returns UUID based on SHA-1 hash of namespace UUID and name. 161 | func (g *generator) NewV5(ns UUID, name string) UUID { 162 | u := newFromHash(sha1.New(), ns, name) 163 | u.SetVersion(V5) 164 | u.SetVariant(VariantRFC4122) 165 | 166 | return u 167 | } 168 | 169 | func (g *generator) initStorage() { 170 | g.initClockSequence() 171 | g.initHardwareAddr() 172 | } 173 | 174 | func (g *generator) initClockSequence() { 175 | buf := make([]byte, 2) 176 | g.safeRandom(buf) 177 | g.clockSequence = binary.BigEndian.Uint16(buf) 178 | } 179 | 180 | func (g *generator) initHardwareAddr() { 181 | interfaces, err := net.Interfaces() 182 | if err == nil { 183 | for _, iface := range interfaces { 184 | if len(iface.HardwareAddr) >= 6 { 185 | copy(g.hardwareAddr[:], iface.HardwareAddr) 186 | return 187 | } 188 | } 189 | } 190 | 191 | // Initialize hardwareAddr randomly in case 192 | // of real network interfaces absence 193 | g.safeRandom(g.hardwareAddr[:]) 194 | 195 | // Set multicast bit as recommended in RFC 4122 196 | g.hardwareAddr[0] |= 0x01 197 | } 198 | 199 | func (g *generator) safeRandom(dest []byte) { 200 | if _, err := rand.Read(dest); err != nil { 201 | panic(err) 202 | } 203 | } 204 | 205 | // Returns UUID v1/v2 storage state. 206 | // Returns epoch timestamp, clock sequence, and hardware address. 207 | func (g *generator) getStorage() (uint64, uint16, []byte) { 208 | g.storageOnce.Do(g.initStorage) 209 | 210 | g.storageMutex.Lock() 211 | defer g.storageMutex.Unlock() 212 | 213 | timeNow := epochFunc() 214 | // Clock changed backwards since last UUID generation. 215 | // Should increase clock sequence. 216 | if timeNow <= g.lastTime { 217 | g.clockSequence++ 218 | } 219 | g.lastTime = timeNow 220 | 221 | return timeNow, g.clockSequence, g.hardwareAddr[:] 222 | } 223 | 224 | // Returns difference in 100-nanosecond intervals between 225 | // UUID epoch (October 15, 1582) and current time. 226 | // This is default epoch calculation function. 227 | func unixTimeFunc() uint64 { 228 | return epochStart + uint64(time.Now().UnixNano()/100) 229 | } 230 | 231 | // Returns UUID based on hashing of namespace UUID and name. 232 | func newFromHash(h hash.Hash, ns UUID, name string) UUID { 233 | u := UUID{} 234 | h.Write(ns[:]) 235 | h.Write([]byte(name)) 236 | copy(u[:], h.Sum(nil)) 237 | 238 | return u 239 | } 240 | -------------------------------------------------------------------------------- /vendor/github.com/satori/go.uuid/generator_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013-2018 by Maxim Bublis 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining 4 | // a copy of this software and associated documentation files (the 5 | // "Software"), to deal in the Software without restriction, including 6 | // without limitation the rights to use, copy, modify, merge, publish, 7 | // distribute, sublicense, and/or sell copies of the Software, and to 8 | // permit persons to whom the Software is furnished to do so, subject to 9 | // the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be 12 | // included in all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | package uuid 23 | 24 | import ( 25 | . "gopkg.in/check.v1" 26 | ) 27 | 28 | type genTestSuite struct{} 29 | 30 | var _ = Suite(&genTestSuite{}) 31 | 32 | func (s *genTestSuite) TestNewV1(c *C) { 33 | u := NewV1() 34 | c.Assert(u.Version(), Equals, V1) 35 | c.Assert(u.Variant(), Equals, VariantRFC4122) 36 | 37 | u1 := NewV1() 38 | u2 := NewV1() 39 | c.Assert(u1, Not(Equals), u2) 40 | 41 | oldFunc := epochFunc 42 | epochFunc = func() uint64 { return 0 } 43 | 44 | u3 := NewV1() 45 | u4 := NewV1() 46 | c.Assert(u3, Not(Equals), u4) 47 | 48 | epochFunc = oldFunc 49 | } 50 | 51 | func (s *genTestSuite) BenchmarkNewV1(c *C) { 52 | for i := 0; i < c.N; i++ { 53 | NewV1() 54 | } 55 | } 56 | 57 | func (s *genTestSuite) TestNewV2(c *C) { 58 | u1 := NewV2(DomainPerson) 59 | c.Assert(u1.Version(), Equals, V2) 60 | c.Assert(u1.Variant(), Equals, VariantRFC4122) 61 | 62 | u2 := NewV2(DomainGroup) 63 | c.Assert(u2.Version(), Equals, V2) 64 | c.Assert(u2.Variant(), Equals, VariantRFC4122) 65 | } 66 | 67 | func (s *genTestSuite) BenchmarkNewV2(c *C) { 68 | for i := 0; i < c.N; i++ { 69 | NewV2(DomainPerson) 70 | } 71 | } 72 | 73 | func (s *genTestSuite) TestNewV3(c *C) { 74 | u := NewV3(NamespaceDNS, "www.example.com") 75 | c.Assert(u.Version(), Equals, V3) 76 | c.Assert(u.Variant(), Equals, VariantRFC4122) 77 | c.Assert(u.String(), Equals, "5df41881-3aed-3515-88a7-2f4a814cf09e") 78 | 79 | u = NewV3(NamespaceDNS, "python.org") 80 | c.Assert(u.String(), Equals, "6fa459ea-ee8a-3ca4-894e-db77e160355e") 81 | 82 | u1 := NewV3(NamespaceDNS, "golang.org") 83 | u2 := NewV3(NamespaceDNS, "golang.org") 84 | c.Assert(u1, Equals, u2) 85 | 86 | u3 := NewV3(NamespaceDNS, "example.com") 87 | c.Assert(u1, Not(Equals), u3) 88 | 89 | u4 := NewV3(NamespaceURL, "golang.org") 90 | c.Assert(u1, Not(Equals), u4) 91 | } 92 | 93 | func (s *genTestSuite) BenchmarkNewV3(c *C) { 94 | for i := 0; i < c.N; i++ { 95 | NewV3(NamespaceDNS, "www.example.com") 96 | } 97 | } 98 | 99 | func (s *genTestSuite) TestNewV4(c *C) { 100 | u := NewV4() 101 | c.Assert(u.Version(), Equals, V4) 102 | c.Assert(u.Variant(), Equals, VariantRFC4122) 103 | } 104 | 105 | func (s *genTestSuite) BenchmarkNewV4(c *C) { 106 | for i := 0; i < c.N; i++ { 107 | NewV4() 108 | } 109 | } 110 | 111 | func (s *genTestSuite) TestNewV5(c *C) { 112 | u := NewV5(NamespaceDNS, "www.example.com") 113 | c.Assert(u.Version(), Equals, V5) 114 | c.Assert(u.Variant(), Equals, VariantRFC4122) 115 | 116 | u = NewV5(NamespaceDNS, "python.org") 117 | c.Assert(u.String(), Equals, "886313e1-3b8a-5372-9b90-0c9aee199e5d") 118 | 119 | u1 := NewV5(NamespaceDNS, "golang.org") 120 | u2 := NewV5(NamespaceDNS, "golang.org") 121 | c.Assert(u1, Equals, u2) 122 | 123 | u3 := NewV5(NamespaceDNS, "example.com") 124 | c.Assert(u1, Not(Equals), u3) 125 | 126 | u4 := NewV5(NamespaceURL, "golang.org") 127 | c.Assert(u1, Not(Equals), u4) 128 | } 129 | 130 | func (s *genTestSuite) BenchmarkNewV5(c *C) { 131 | for i := 0; i < c.N; i++ { 132 | NewV5(NamespaceDNS, "www.example.com") 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /vendor/github.com/satori/go.uuid/sql.go: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013-2018 by Maxim Bublis 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining 4 | // a copy of this software and associated documentation files (the 5 | // "Software"), to deal in the Software without restriction, including 6 | // without limitation the rights to use, copy, modify, merge, publish, 7 | // distribute, sublicense, and/or sell copies of the Software, and to 8 | // permit persons to whom the Software is furnished to do so, subject to 9 | // the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be 12 | // included in all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | package uuid 23 | 24 | import ( 25 | "database/sql/driver" 26 | "fmt" 27 | ) 28 | 29 | // Value implements the driver.Valuer interface. 30 | func (u UUID) Value() (driver.Value, error) { 31 | return u.String(), nil 32 | } 33 | 34 | // Scan implements the sql.Scanner interface. 35 | // A 16-byte slice is handled by UnmarshalBinary, while 36 | // a longer byte slice or a string is handled by UnmarshalText. 37 | func (u *UUID) Scan(src interface{}) error { 38 | switch src := src.(type) { 39 | case []byte: 40 | if len(src) == Size { 41 | return u.UnmarshalBinary(src) 42 | } 43 | return u.UnmarshalText(src) 44 | 45 | case string: 46 | return u.UnmarshalText([]byte(src)) 47 | } 48 | 49 | return fmt.Errorf("uuid: cannot convert %T to UUID", src) 50 | } 51 | 52 | // NullUUID can be used with the standard sql package to represent a 53 | // UUID value that can be NULL in the database 54 | type NullUUID struct { 55 | UUID UUID 56 | Valid bool 57 | } 58 | 59 | // Value implements the driver.Valuer interface. 60 | func (u NullUUID) Value() (driver.Value, error) { 61 | if !u.Valid { 62 | return nil, nil 63 | } 64 | // Delegate to UUID Value function 65 | return u.UUID.Value() 66 | } 67 | 68 | // Scan implements the sql.Scanner interface. 69 | func (u *NullUUID) Scan(src interface{}) error { 70 | if src == nil { 71 | u.UUID, u.Valid = Nil, false 72 | return nil 73 | } 74 | 75 | // Delegate to UUID Scan function 76 | u.Valid = true 77 | return u.UUID.Scan(src) 78 | } 79 | -------------------------------------------------------------------------------- /vendor/github.com/satori/go.uuid/sql_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013-2018 by Maxim Bublis 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining 4 | // a copy of this software and associated documentation files (the 5 | // "Software"), to deal in the Software without restriction, including 6 | // without limitation the rights to use, copy, modify, merge, publish, 7 | // distribute, sublicense, and/or sell copies of the Software, and to 8 | // permit persons to whom the Software is furnished to do so, subject to 9 | // the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be 12 | // included in all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | package uuid 23 | 24 | import ( 25 | . "gopkg.in/check.v1" 26 | ) 27 | 28 | type sqlTestSuite struct{} 29 | 30 | var _ = Suite(&sqlTestSuite{}) 31 | 32 | func (s *sqlTestSuite) TestValue(c *C) { 33 | u, err := FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8") 34 | c.Assert(err, IsNil) 35 | 36 | val, err := u.Value() 37 | c.Assert(err, IsNil) 38 | c.Assert(val, Equals, u.String()) 39 | } 40 | 41 | func (s *sqlTestSuite) TestValueNil(c *C) { 42 | u := UUID{} 43 | 44 | val, err := u.Value() 45 | c.Assert(err, IsNil) 46 | c.Assert(val, Equals, Nil.String()) 47 | } 48 | 49 | func (s *sqlTestSuite) TestNullUUIDValueNil(c *C) { 50 | u := NullUUID{} 51 | 52 | val, err := u.Value() 53 | c.Assert(err, IsNil) 54 | c.Assert(val, IsNil) 55 | } 56 | 57 | func (s *sqlTestSuite) TestScanBinary(c *C) { 58 | u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 59 | b1 := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 60 | 61 | u1 := UUID{} 62 | err := u1.Scan(b1) 63 | c.Assert(err, IsNil) 64 | c.Assert(u, Equals, u1) 65 | 66 | b2 := []byte{} 67 | u2 := UUID{} 68 | 69 | err = u2.Scan(b2) 70 | c.Assert(err, NotNil) 71 | } 72 | 73 | func (s *sqlTestSuite) TestScanString(c *C) { 74 | u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 75 | s1 := "6ba7b810-9dad-11d1-80b4-00c04fd430c8" 76 | 77 | u1 := UUID{} 78 | err := u1.Scan(s1) 79 | c.Assert(err, IsNil) 80 | c.Assert(u, Equals, u1) 81 | 82 | s2 := "" 83 | u2 := UUID{} 84 | 85 | err = u2.Scan(s2) 86 | c.Assert(err, NotNil) 87 | } 88 | 89 | func (s *sqlTestSuite) TestScanText(c *C) { 90 | u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 91 | b1 := []byte("6ba7b810-9dad-11d1-80b4-00c04fd430c8") 92 | 93 | u1 := UUID{} 94 | err := u1.Scan(b1) 95 | c.Assert(err, IsNil) 96 | c.Assert(u, Equals, u1) 97 | 98 | b2 := []byte("") 99 | u2 := UUID{} 100 | err = u2.Scan(b2) 101 | c.Assert(err, NotNil) 102 | } 103 | 104 | func (s *sqlTestSuite) TestScanUnsupported(c *C) { 105 | u := UUID{} 106 | 107 | err := u.Scan(true) 108 | c.Assert(err, NotNil) 109 | } 110 | 111 | func (s *sqlTestSuite) TestScanNil(c *C) { 112 | u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 113 | 114 | err := u.Scan(nil) 115 | c.Assert(err, NotNil) 116 | } 117 | 118 | func (s *sqlTestSuite) TestNullUUIDScanValid(c *C) { 119 | u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 120 | s1 := "6ba7b810-9dad-11d1-80b4-00c04fd430c8" 121 | 122 | u1 := NullUUID{} 123 | err := u1.Scan(s1) 124 | c.Assert(err, IsNil) 125 | c.Assert(u1.Valid, Equals, true) 126 | c.Assert(u1.UUID, Equals, u) 127 | } 128 | 129 | func (s *sqlTestSuite) TestNullUUIDScanNil(c *C) { 130 | u := NullUUID{UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}, true} 131 | 132 | err := u.Scan(nil) 133 | c.Assert(err, IsNil) 134 | c.Assert(u.Valid, Equals, false) 135 | c.Assert(u.UUID, Equals, Nil) 136 | } 137 | -------------------------------------------------------------------------------- /vendor/github.com/satori/go.uuid/uuid.go: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013-2018 by Maxim Bublis 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining 4 | // a copy of this software and associated documentation files (the 5 | // "Software"), to deal in the Software without restriction, including 6 | // without limitation the rights to use, copy, modify, merge, publish, 7 | // distribute, sublicense, and/or sell copies of the Software, and to 8 | // permit persons to whom the Software is furnished to do so, subject to 9 | // the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be 12 | // included in all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | // Package uuid provides implementation of Universally Unique Identifier (UUID). 23 | // Supported versions are 1, 3, 4 and 5 (as specified in RFC 4122) and 24 | // version 2 (as specified in DCE 1.1). 25 | package uuid 26 | 27 | import ( 28 | "bytes" 29 | "encoding/hex" 30 | ) 31 | 32 | // Size of a UUID in bytes. 33 | const Size = 16 34 | 35 | // UUID representation compliant with specification 36 | // described in RFC 4122. 37 | type UUID [Size]byte 38 | 39 | // UUID versions 40 | const ( 41 | _ byte = iota 42 | V1 43 | V2 44 | V3 45 | V4 46 | V5 47 | ) 48 | 49 | // UUID layout variants. 50 | const ( 51 | VariantNCS byte = iota 52 | VariantRFC4122 53 | VariantMicrosoft 54 | VariantFuture 55 | ) 56 | 57 | // UUID DCE domains. 58 | const ( 59 | DomainPerson = iota 60 | DomainGroup 61 | DomainOrg 62 | ) 63 | 64 | // String parse helpers. 65 | var ( 66 | urnPrefix = []byte("urn:uuid:") 67 | byteGroups = []int{8, 4, 4, 4, 12} 68 | ) 69 | 70 | // Nil is special form of UUID that is specified to have all 71 | // 128 bits set to zero. 72 | var Nil = UUID{} 73 | 74 | // Predefined namespace UUIDs. 75 | var ( 76 | NamespaceDNS = Must(FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8")) 77 | NamespaceURL = Must(FromString("6ba7b811-9dad-11d1-80b4-00c04fd430c8")) 78 | NamespaceOID = Must(FromString("6ba7b812-9dad-11d1-80b4-00c04fd430c8")) 79 | NamespaceX500 = Must(FromString("6ba7b814-9dad-11d1-80b4-00c04fd430c8")) 80 | ) 81 | 82 | // Equal returns true if u1 and u2 equals, otherwise returns false. 83 | func Equal(u1 UUID, u2 UUID) bool { 84 | return bytes.Equal(u1[:], u2[:]) 85 | } 86 | 87 | // Version returns algorithm version used to generate UUID. 88 | func (u UUID) Version() byte { 89 | return u[6] >> 4 90 | } 91 | 92 | // Variant returns UUID layout variant. 93 | func (u UUID) Variant() byte { 94 | switch { 95 | case (u[8] >> 7) == 0x00: 96 | return VariantNCS 97 | case (u[8] >> 6) == 0x02: 98 | return VariantRFC4122 99 | case (u[8] >> 5) == 0x06: 100 | return VariantMicrosoft 101 | case (u[8] >> 5) == 0x07: 102 | fallthrough 103 | default: 104 | return VariantFuture 105 | } 106 | } 107 | 108 | // Bytes returns bytes slice representation of UUID. 109 | func (u UUID) Bytes() []byte { 110 | return u[:] 111 | } 112 | 113 | // Returns canonical string representation of UUID: 114 | // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx. 115 | func (u UUID) String() string { 116 | buf := make([]byte, 36) 117 | 118 | hex.Encode(buf[0:8], u[0:4]) 119 | buf[8] = '-' 120 | hex.Encode(buf[9:13], u[4:6]) 121 | buf[13] = '-' 122 | hex.Encode(buf[14:18], u[6:8]) 123 | buf[18] = '-' 124 | hex.Encode(buf[19:23], u[8:10]) 125 | buf[23] = '-' 126 | hex.Encode(buf[24:], u[10:]) 127 | 128 | return string(buf) 129 | } 130 | 131 | // SetVersion sets version bits. 132 | func (u *UUID) SetVersion(v byte) { 133 | u[6] = (u[6] & 0x0f) | (v << 4) 134 | } 135 | 136 | // SetVariant sets variant bits. 137 | func (u *UUID) SetVariant(v byte) { 138 | switch v { 139 | case VariantNCS: 140 | u[8] = (u[8]&(0xff>>1) | (0x00 << 7)) 141 | case VariantRFC4122: 142 | u[8] = (u[8]&(0xff>>2) | (0x02 << 6)) 143 | case VariantMicrosoft: 144 | u[8] = (u[8]&(0xff>>3) | (0x06 << 5)) 145 | case VariantFuture: 146 | fallthrough 147 | default: 148 | u[8] = (u[8]&(0xff>>3) | (0x07 << 5)) 149 | } 150 | } 151 | 152 | // Must is a helper that wraps a call to a function returning (UUID, error) 153 | // and panics if the error is non-nil. It is intended for use in variable 154 | // initializations such as 155 | // var packageUUID = uuid.Must(uuid.FromString("123e4567-e89b-12d3-a456-426655440000")); 156 | func Must(u UUID, err error) UUID { 157 | if err != nil { 158 | panic(err) 159 | } 160 | return u 161 | } 162 | -------------------------------------------------------------------------------- /vendor/github.com/satori/go.uuid/uuid_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013-2018 by Maxim Bublis 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining 4 | // a copy of this software and associated documentation files (the 5 | // "Software"), to deal in the Software without restriction, including 6 | // without limitation the rights to use, copy, modify, merge, publish, 7 | // distribute, sublicense, and/or sell copies of the Software, and to 8 | // permit persons to whom the Software is furnished to do so, subject to 9 | // the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be 12 | // included in all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | package uuid 23 | 24 | import ( 25 | "bytes" 26 | "testing" 27 | 28 | . "gopkg.in/check.v1" 29 | ) 30 | 31 | // Hook up gocheck into the "go test" runner. 32 | func TestUUID(t *testing.T) { TestingT(t) } 33 | 34 | type testSuite struct{} 35 | 36 | var _ = Suite(&testSuite{}) 37 | 38 | func (s *testSuite) TestBytes(c *C) { 39 | u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 40 | 41 | bytes1 := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 42 | 43 | c.Assert(bytes.Equal(u.Bytes(), bytes1), Equals, true) 44 | } 45 | 46 | func (s *testSuite) TestString(c *C) { 47 | c.Assert(NamespaceDNS.String(), Equals, "6ba7b810-9dad-11d1-80b4-00c04fd430c8") 48 | } 49 | 50 | func (s *testSuite) TestEqual(c *C) { 51 | c.Assert(Equal(NamespaceDNS, NamespaceDNS), Equals, true) 52 | c.Assert(Equal(NamespaceDNS, NamespaceURL), Equals, false) 53 | } 54 | 55 | func (s *testSuite) TestVersion(c *C) { 56 | u := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} 57 | c.Assert(u.Version(), Equals, V1) 58 | } 59 | 60 | func (s *testSuite) TestSetVersion(c *C) { 61 | u := UUID{} 62 | u.SetVersion(4) 63 | c.Assert(u.Version(), Equals, V4) 64 | } 65 | 66 | func (s *testSuite) TestVariant(c *C) { 67 | u1 := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} 68 | c.Assert(u1.Variant(), Equals, VariantNCS) 69 | 70 | u2 := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} 71 | c.Assert(u2.Variant(), Equals, VariantRFC4122) 72 | 73 | u3 := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} 74 | c.Assert(u3.Variant(), Equals, VariantMicrosoft) 75 | 76 | u4 := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} 77 | c.Assert(u4.Variant(), Equals, VariantFuture) 78 | } 79 | 80 | func (s *testSuite) TestSetVariant(c *C) { 81 | u := UUID{} 82 | u.SetVariant(VariantNCS) 83 | c.Assert(u.Variant(), Equals, VariantNCS) 84 | u.SetVariant(VariantRFC4122) 85 | c.Assert(u.Variant(), Equals, VariantRFC4122) 86 | u.SetVariant(VariantMicrosoft) 87 | c.Assert(u.Variant(), Equals, VariantMicrosoft) 88 | u.SetVariant(VariantFuture) 89 | c.Assert(u.Variant(), Equals, VariantFuture) 90 | } 91 | --------------------------------------------------------------------------------