vendor: github.com/mitchellh/hashstructure v1.0.0

This commit is contained in:
Radek Simko 2019-02-12 11:44:28 +00:00
parent e0841f73b3
commit 12ac212611
No known key found for this signature in database
GPG Key ID: 1F1C84FE689A88D7
6 changed files with 81 additions and 41 deletions

2
go.mod
View File

@ -100,7 +100,7 @@ require (
github.com/mitchellh/go-homedir v1.0.0
github.com/mitchellh/go-linereader v0.0.0-20141013185533-07bab5fdd958
github.com/mitchellh/go-wordwrap v1.0.0
github.com/mitchellh/hashstructure v0.0.0-20160209213820-6b17d669fac5
github.com/mitchellh/hashstructure v1.0.0
github.com/mitchellh/mapstructure v0.0.0-20170307201123-53818660ed49
github.com/mitchellh/panicwrap v0.0.0-20161208170302-ba9e1a65e0f7
github.com/mitchellh/prefixedio v0.0.0-20151214002211-6e6954073784

4
go.sum
View File

@ -239,8 +239,8 @@ github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4=
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/hashstructure v0.0.0-20160209213820-6b17d669fac5 h1:h+4fp6yIoLPf/K2egDK3kvYM2zqb28gJIWWMiDzBdKM=
github.com/mitchellh/hashstructure v0.0.0-20160209213820-6b17d669fac5/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ=
github.com/mitchellh/hashstructure v1.0.0 h1:ZkRJX1CyOoTkar7p/mLS5TZU4nJ1Rn/F8u9dGS02Q3Y=
github.com/mitchellh/hashstructure v1.0.0/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ=
github.com/mitchellh/mapstructure v0.0.0-20170307201123-53818660ed49 h1:kaWdlw4YogwkDl8CG+/VxhXkrL9uz3n1D9QBC2pEGLE=
github.com/mitchellh/mapstructure v0.0.0-20170307201123-53818660ed49/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/panicwrap v0.0.0-20161208170302-ba9e1a65e0f7 h1:+PBI9A4rLQJlch3eQI/RkTY2HzX+bl2lPUf3goenBxs=

View File

@ -1,4 +1,4 @@
# hashstructure
# hashstructure [![GoDoc](https://godoc.org/github.com/mitchellh/hashstructure?status.svg)](https://godoc.org/github.com/mitchellh/hashstructure)
hashstructure is a Go library for creating a unique hash value
for arbitrary values in Go.
@ -20,6 +20,9 @@ sending data across the network, caching values locally (de-dup), and so on.
* Optionally specify a custom hash function to optimize for speed, collision
avoidance for your data set, etc.
* Optionally hash the output of `.String()` on structs that implement fmt.Stringer,
allowing effective hashing of time.Time
## Installation
Standard `go get`:
@ -34,28 +37,29 @@ For usage and examples see the [Godoc](http://godoc.org/github.com/mitchellh/has
A quick code example is shown below:
```go
type ComplexStruct struct {
Name string
Age uint
Metadata map[string]interface{}
}
type ComplexStruct struct {
Name string
Age uint
Metadata map[string]interface{}
}
v := ComplexStruct{
Name: "mitchellh",
Age: 64,
Metadata: map[string]interface{}{
"car": true,
"location": "California",
"siblings": []string{"Bob", "John"},
},
}
v := ComplexStruct{
Name: "mitchellh",
Age: 64,
Metadata: map[string]interface{}{
"car": true,
"location": "California",
"siblings": []string{"Bob", "John"},
},
}
hash, err := hashstructure.Hash(v, nil)
if err != nil {
panic(err)
}
hash, err := hashstructure.Hash(v, nil)
if err != nil {
panic(err)
}
fmt.Printf("%d", hash)
// Output:
// 2307517237273902113
fmt.Printf("%d", hash)
// Output:
// 2307517237273902113
```

1
vendor/github.com/mitchellh/hashstructure/go.mod generated vendored Normal file
View File

@ -0,0 +1 @@
module github.com/mitchellh/hashstructure

View File

@ -8,6 +8,16 @@ import (
"reflect"
)
// ErrNotStringer is returned when there's an error with hash:"string"
type ErrNotStringer struct {
Field string
}
// Error implements error for ErrNotStringer
func (ens *ErrNotStringer) Error() string {
return fmt.Sprintf("hashstructure: %s has hash:\"string\" set, but does not implement fmt.Stringer", ens.Field)
}
// HashOptions are options that are available for hashing.
type HashOptions struct {
// Hasher is the hash function to use. If this isn't set, it will
@ -17,12 +27,18 @@ type HashOptions struct {
// TagName is the struct tag to look at when hashing the structure.
// By default this is "hash".
TagName string
// ZeroNil is flag determining if nil pointer should be treated equal
// to a zero value of pointed type. By default this is false.
ZeroNil bool
}
// Hash returns the hash value of an arbitrary value.
//
// If opts is nil, then default options will be used. See HashOptions
// for the default values.
// for the default values. The same *HashOptions value cannot be used
// concurrently. None of the values within a *HashOptions struct are
// safe to read/write while hashing is being done.
//
// Notes on the value:
//
@ -41,11 +57,14 @@ type HashOptions struct {
//
// The available tag values are:
//
// * "ignore" - The field will be ignored and not affect the hash code.
// * "ignore" or "-" - The field will be ignored and not affect the hash code.
//
// * "set" - The field will be treated as a set, where ordering doesn't
// affect the hash code. This only works for slices.
//
// * "string" - The field will be hashed as a string, only works when the
// field implements fmt.Stringer
//
func Hash(v interface{}, opts *HashOptions) (uint64, error) {
// Create default options
if opts == nil {
@ -63,15 +82,17 @@ func Hash(v interface{}, opts *HashOptions) (uint64, error) {
// Create our walker and walk the structure
w := &walker{
h: opts.Hasher,
tag: opts.TagName,
h: opts.Hasher,
tag: opts.TagName,
zeronil: opts.ZeroNil,
}
return w.visit(reflect.ValueOf(v), nil)
}
type walker struct {
h hash.Hash64
tag string
h hash.Hash64
tag string
zeronil bool
}
type visitOpts struct {
@ -84,6 +105,8 @@ type visitOpts struct {
}
func (w *walker) visit(v reflect.Value, opts *visitOpts) (uint64, error) {
t := reflect.TypeOf(0)
// Loop since these can be wrapped in multiple layers of pointers
// and interfaces.
for {
@ -96,6 +119,9 @@ func (w *walker) visit(v reflect.Value, opts *visitOpts) (uint64, error) {
}
if v.Kind() == reflect.Ptr {
if w.zeronil {
t = v.Type().Elem()
}
v = reflect.Indirect(v)
continue
}
@ -105,8 +131,7 @@ func (w *walker) visit(v reflect.Value, opts *visitOpts) (uint64, error) {
// If it is nil, treat it like a zero.
if !v.IsValid() {
var tmp int8
v = reflect.ValueOf(tmp)
v = reflect.Zero(t)
}
// Binary writing can use raw ints, we have to convert to
@ -189,8 +214,8 @@ func (w *walker) visit(v reflect.Value, opts *visitOpts) (uint64, error) {
return h, nil
case reflect.Struct:
var include Includable
parent := v.Interface()
var include Includable
if impl, ok := parent.(Includable); ok {
include = impl
}
@ -203,7 +228,7 @@ func (w *walker) visit(v reflect.Value, opts *visitOpts) (uint64, error) {
l := v.NumField()
for i := 0; i < l; i++ {
if v := v.Field(i); v.CanSet() || t.Field(i).Name != "_" {
if innerV := v.Field(i); v.CanSet() || t.Field(i).Name != "_" {
var f visitFlag
fieldType := t.Field(i)
if fieldType.PkgPath != "" {
@ -212,14 +237,25 @@ func (w *walker) visit(v reflect.Value, opts *visitOpts) (uint64, error) {
}
tag := fieldType.Tag.Get(w.tag)
if tag == "ignore" {
if tag == "ignore" || tag == "-" {
// Ignore this field
continue
}
// if string is set, use the string value
if tag == "string" {
if impl, ok := innerV.Interface().(fmt.Stringer); ok {
innerV = reflect.ValueOf(impl.String())
} else {
return 0, &ErrNotStringer{
Field: v.Type().Field(i).Name,
}
}
}
// Check if we implement includable and check it
if include != nil {
incl, err := include.HashInclude(fieldType.Name, v)
incl, err := include.HashInclude(fieldType.Name, innerV)
if err != nil {
return 0, err
}
@ -238,7 +274,7 @@ func (w *walker) visit(v reflect.Value, opts *visitOpts) (uint64, error) {
return 0, err
}
vh, err := w.visit(v, &visitOpts{
vh, err := w.visit(innerV, &visitOpts{
Flags: f,
Struct: parent,
StructField: fieldType.Name,
@ -289,7 +325,6 @@ func (w *walker) visit(v reflect.Value, opts *visitOpts) (uint64, error) {
return 0, fmt.Errorf("unknown kind to hash: %s", k)
}
return 0, nil
}
func hashUpdateOrdered(h hash.Hash64, a, b uint64) uint64 {

2
vendor/modules.txt vendored
View File

@ -473,7 +473,7 @@ github.com/mitchellh/go-linereader
github.com/mitchellh/go-testing-interface
# github.com/mitchellh/go-wordwrap v1.0.0
github.com/mitchellh/go-wordwrap
# github.com/mitchellh/hashstructure v0.0.0-20160209213820-6b17d669fac5
# github.com/mitchellh/hashstructure v1.0.0
github.com/mitchellh/hashstructure
# github.com/mitchellh/mapstructure v0.0.0-20170307201123-53818660ed49
github.com/mitchellh/mapstructure