summaryrefslogtreecommitdiff
path: root/vendor/github.com/mitchellh/copystructure/copystructure.go
diff options
context:
space:
mode:
authorLibravatar Terin Stock <terinjokes@gmail.com>2025-03-09 17:47:56 +0100
committerLibravatar Terin Stock <terinjokes@gmail.com>2025-03-10 01:59:49 +0100
commit3ac1ee16f377d31a0fb80c8dae28b6239ac4229e (patch)
treef61faa581feaaeaba2542b9f2b8234a590684413 /vendor/github.com/mitchellh/copystructure/copystructure.go
parent[chore] update URLs to forked source (diff)
downloadgotosocial-3ac1ee16f377d31a0fb80c8dae28b6239ac4229e.tar.xz
[chore] remove vendor
Diffstat (limited to 'vendor/github.com/mitchellh/copystructure/copystructure.go')
-rw-r--r--vendor/github.com/mitchellh/copystructure/copystructure.go631
1 files changed, 0 insertions, 631 deletions
diff --git a/vendor/github.com/mitchellh/copystructure/copystructure.go b/vendor/github.com/mitchellh/copystructure/copystructure.go
deleted file mode 100644
index 8089e6670..000000000
--- a/vendor/github.com/mitchellh/copystructure/copystructure.go
+++ /dev/null
@@ -1,631 +0,0 @@
-package copystructure
-
-import (
- "errors"
- "reflect"
- "sync"
-
- "github.com/mitchellh/reflectwalk"
-)
-
-const tagKey = "copy"
-
-// Copy returns a deep copy of v.
-//
-// Copy is unable to copy unexported fields in a struct (lowercase field names).
-// Unexported fields can't be reflected by the Go runtime and therefore
-// copystructure can't perform any data copies.
-//
-// For structs, copy behavior can be controlled with struct tags. For example:
-//
-// struct {
-// Name string
-// Data *bytes.Buffer `copy:"shallow"`
-// }
-//
-// The available tag values are:
-//
-// * "ignore" - The field will be ignored, effectively resulting in it being
-// assigned the zero value in the copy.
-//
-// * "shallow" - The field will be be shallow copied. This means that references
-// values such as pointers, maps, slices, etc. will be directly assigned
-// versus deep copied.
-//
-func Copy(v interface{}) (interface{}, error) {
- return Config{}.Copy(v)
-}
-
-// CopierFunc is a function that knows how to deep copy a specific type.
-// Register these globally with the Copiers variable.
-type CopierFunc func(interface{}) (interface{}, error)
-
-// Copiers is a map of types that behave specially when they are copied.
-// If a type is found in this map while deep copying, this function
-// will be called to copy it instead of attempting to copy all fields.
-//
-// The key should be the type, obtained using: reflect.TypeOf(value with type).
-//
-// It is unsafe to write to this map after Copies have started. If you
-// are writing to this map while also copying, wrap all modifications to
-// this map as well as to Copy in a mutex.
-var Copiers map[reflect.Type]CopierFunc = make(map[reflect.Type]CopierFunc)
-
-// ShallowCopiers is a map of pointer types that behave specially
-// when they are copied. If a type is found in this map while deep
-// copying, the pointer value will be shallow copied and not walked
-// into.
-//
-// The key should be the type, obtained using: reflect.TypeOf(value
-// with type).
-//
-// It is unsafe to write to this map after Copies have started. If you
-// are writing to this map while also copying, wrap all modifications to
-// this map as well as to Copy in a mutex.
-var ShallowCopiers map[reflect.Type]struct{} = make(map[reflect.Type]struct{})
-
-// Must is a helper that wraps a call to a function returning
-// (interface{}, error) and panics if the error is non-nil. It is intended
-// for use in variable initializations and should only be used when a copy
-// error should be a crashing case.
-func Must(v interface{}, err error) interface{} {
- if err != nil {
- panic("copy error: " + err.Error())
- }
-
- return v
-}
-
-var errPointerRequired = errors.New("Copy argument must be a pointer when Lock is true")
-
-type Config struct {
- // Lock any types that are a sync.Locker and are not a mutex while copying.
- // If there is an RLocker method, use that to get the sync.Locker.
- Lock bool
-
- // Copiers is a map of types associated with a CopierFunc. Use the global
- // Copiers map if this is nil.
- Copiers map[reflect.Type]CopierFunc
-
- // ShallowCopiers is a map of pointer types that when they are
- // shallow copied no matter where they are encountered. Use the
- // global ShallowCopiers if this is nil.
- ShallowCopiers map[reflect.Type]struct{}
-}
-
-func (c Config) Copy(v interface{}) (interface{}, error) {
- if c.Lock && reflect.ValueOf(v).Kind() != reflect.Ptr {
- return nil, errPointerRequired
- }
-
- w := new(walker)
- if c.Lock {
- w.useLocks = true
- }
-
- if c.Copiers == nil {
- c.Copiers = Copiers
- }
- w.copiers = c.Copiers
-
- if c.ShallowCopiers == nil {
- c.ShallowCopiers = ShallowCopiers
- }
- w.shallowCopiers = c.ShallowCopiers
-
- err := reflectwalk.Walk(v, w)
- if err != nil {
- return nil, err
- }
-
- // Get the result. If the result is nil, then we want to turn it
- // into a typed nil if we can.
- result := w.Result
- if result == nil {
- val := reflect.ValueOf(v)
- result = reflect.Indirect(reflect.New(val.Type())).Interface()
- }
-
- return result, nil
-}
-
-// Return the key used to index interfaces types we've seen. Store the number
-// of pointers in the upper 32bits, and the depth in the lower 32bits. This is
-// easy to calculate, easy to match a key with our current depth, and we don't
-// need to deal with initializing and cleaning up nested maps or slices.
-func ifaceKey(pointers, depth int) uint64 {
- return uint64(pointers)<<32 | uint64(depth)
-}
-
-type walker struct {
- Result interface{}
-
- copiers map[reflect.Type]CopierFunc
- shallowCopiers map[reflect.Type]struct{}
- depth int
- ignoreDepth int
- vals []reflect.Value
- cs []reflect.Value
-
- // This stores the number of pointers we've walked over, indexed by depth.
- ps []int
-
- // If an interface is indirected by a pointer, we need to know the type of
- // interface to create when creating the new value. Store the interface
- // types here, indexed by both the walk depth and the number of pointers
- // already seen at that depth. Use ifaceKey to calculate the proper uint64
- // value.
- ifaceTypes map[uint64]reflect.Type
-
- // any locks we've taken, indexed by depth
- locks []sync.Locker
- // take locks while walking the structure
- useLocks bool
-}
-
-func (w *walker) Enter(l reflectwalk.Location) error {
- w.depth++
-
- // ensure we have enough elements to index via w.depth
- for w.depth >= len(w.locks) {
- w.locks = append(w.locks, nil)
- }
-
- for len(w.ps) < w.depth+1 {
- w.ps = append(w.ps, 0)
- }
-
- return nil
-}
-
-func (w *walker) Exit(l reflectwalk.Location) error {
- locker := w.locks[w.depth]
- w.locks[w.depth] = nil
- if locker != nil {
- defer locker.Unlock()
- }
-
- // clear out pointers and interfaces as we exit the stack
- w.ps[w.depth] = 0
-
- for k := range w.ifaceTypes {
- mask := uint64(^uint32(0))
- if k&mask == uint64(w.depth) {
- delete(w.ifaceTypes, k)
- }
- }
-
- w.depth--
- if w.ignoreDepth > w.depth {
- w.ignoreDepth = 0
- }
-
- if w.ignoring() {
- return nil
- }
-
- switch l {
- case reflectwalk.Array:
- fallthrough
- case reflectwalk.Map:
- fallthrough
- case reflectwalk.Slice:
- w.replacePointerMaybe()
-
- // Pop map off our container
- w.cs = w.cs[:len(w.cs)-1]
- case reflectwalk.MapValue:
- // Pop off the key and value
- mv := w.valPop()
- mk := w.valPop()
- m := w.cs[len(w.cs)-1]
-
- // If mv is the zero value, SetMapIndex deletes the key form the map,
- // or in this case never adds it. We need to create a properly typed
- // zero value so that this key can be set.
- if !mv.IsValid() {
- mv = reflect.Zero(m.Elem().Type().Elem())
- }
- m.Elem().SetMapIndex(mk, mv)
- case reflectwalk.ArrayElem:
- // Pop off the value and the index and set it on the array
- v := w.valPop()
- i := w.valPop().Interface().(int)
- if v.IsValid() {
- a := w.cs[len(w.cs)-1]
- ae := a.Elem().Index(i) // storing array as pointer on stack - so need Elem() call
- if ae.CanSet() {
- ae.Set(v)
- }
- }
- case reflectwalk.SliceElem:
- // Pop off the value and the index and set it on the slice
- v := w.valPop()
- i := w.valPop().Interface().(int)
- if v.IsValid() {
- s := w.cs[len(w.cs)-1]
- se := s.Elem().Index(i)
- if se.CanSet() {
- se.Set(v)
- }
- }
- case reflectwalk.Struct:
- w.replacePointerMaybe()
-
- // Remove the struct from the container stack
- w.cs = w.cs[:len(w.cs)-1]
- case reflectwalk.StructField:
- // Pop off the value and the field
- v := w.valPop()
- f := w.valPop().Interface().(reflect.StructField)
- if v.IsValid() {
- s := w.cs[len(w.cs)-1]
- sf := reflect.Indirect(s).FieldByName(f.Name)
-
- if sf.CanSet() {
- sf.Set(v)
- }
- }
- case reflectwalk.WalkLoc:
- // Clear out the slices for GC
- w.cs = nil
- w.vals = nil
- }
-
- return nil
-}
-
-func (w *walker) Map(m reflect.Value) error {
- if w.ignoring() {
- return nil
- }
- w.lock(m)
-
- // Create the map. If the map itself is nil, then just make a nil map
- var newMap reflect.Value
- if m.IsNil() {
- newMap = reflect.New(m.Type())
- } else {
- newMap = wrapPtr(reflect.MakeMap(m.Type()))
- }
-
- w.cs = append(w.cs, newMap)
- w.valPush(newMap)
- return nil
-}
-
-func (w *walker) MapElem(m, k, v reflect.Value) error {
- return nil
-}
-
-func (w *walker) PointerEnter(v bool) error {
- if v {
- w.ps[w.depth]++
- }
- return nil
-}
-
-func (w *walker) PointerExit(v bool) error {
- if v {
- w.ps[w.depth]--
- }
- return nil
-}
-
-func (w *walker) Pointer(v reflect.Value) error {
- if _, ok := w.shallowCopiers[v.Type()]; ok {
- // Shallow copy this value. Use the same logic as primitive, then
- // return skip.
- if err := w.Primitive(v); err != nil {
- return err
- }
-
- return reflectwalk.SkipEntry
- }
-
- return nil
-}
-
-func (w *walker) Interface(v reflect.Value) error {
- if !v.IsValid() {
- return nil
- }
- if w.ifaceTypes == nil {
- w.ifaceTypes = make(map[uint64]reflect.Type)
- }
-
- w.ifaceTypes[ifaceKey(w.ps[w.depth], w.depth)] = v.Type()
- return nil
-}
-
-func (w *walker) Primitive(v reflect.Value) error {
- if w.ignoring() {
- return nil
- }
- w.lock(v)
-
- // IsValid verifies the v is non-zero and CanInterface verifies
- // that we're allowed to read this value (unexported fields).
- var newV reflect.Value
- if v.IsValid() && v.CanInterface() {
- newV = reflect.New(v.Type())
- newV.Elem().Set(v)
- }
-
- w.valPush(newV)
- w.replacePointerMaybe()
- return nil
-}
-
-func (w *walker) Slice(s reflect.Value) error {
- if w.ignoring() {
- return nil
- }
- w.lock(s)
-
- var newS reflect.Value
- if s.IsNil() {
- newS = reflect.New(s.Type())
- } else {
- newS = wrapPtr(reflect.MakeSlice(s.Type(), s.Len(), s.Cap()))
- }
-
- w.cs = append(w.cs, newS)
- w.valPush(newS)
- return nil
-}
-
-func (w *walker) SliceElem(i int, elem reflect.Value) error {
- if w.ignoring() {
- return nil
- }
-
- // We don't write the slice here because elem might still be
- // arbitrarily complex. Just record the index and continue on.
- w.valPush(reflect.ValueOf(i))
-
- return nil
-}
-
-func (w *walker) Array(a reflect.Value) error {
- if w.ignoring() {
- return nil
- }
- w.lock(a)
-
- newA := reflect.New(a.Type())
-
- w.cs = append(w.cs, newA)
- w.valPush(newA)
- return nil
-}
-
-func (w *walker) ArrayElem(i int, elem reflect.Value) error {
- if w.ignoring() {
- return nil
- }
-
- // We don't write the array here because elem might still be
- // arbitrarily complex. Just record the index and continue on.
- w.valPush(reflect.ValueOf(i))
-
- return nil
-}
-
-func (w *walker) Struct(s reflect.Value) error {
- if w.ignoring() {
- return nil
- }
- w.lock(s)
-
- var v reflect.Value
- if c, ok := w.copiers[s.Type()]; ok {
- // We have a Copier for this struct, so we use that copier to
- // get the copy, and we ignore anything deeper than this.
- w.ignoreDepth = w.depth
-
- dup, err := c(s.Interface())
- if err != nil {
- return err
- }
-
- // We need to put a pointer to the value on the value stack,
- // so allocate a new pointer and set it.
- v = reflect.New(s.Type())
- reflect.Indirect(v).Set(reflect.ValueOf(dup))
- } else {
- // No copier, we copy ourselves and allow reflectwalk to guide
- // us deeper into the structure for copying.
- v = reflect.New(s.Type())
- }
-
- // Push the value onto the value stack for setting the struct field,
- // and add the struct itself to the containers stack in case we walk
- // deeper so that its own fields can be modified.
- w.valPush(v)
- w.cs = append(w.cs, v)
-
- return nil
-}
-
-func (w *walker) StructField(f reflect.StructField, v reflect.Value) error {
- if w.ignoring() {
- return nil
- }
-
- // If PkgPath is non-empty, this is a private (unexported) field.
- // We do not set this unexported since the Go runtime doesn't allow us.
- if f.PkgPath != "" {
- return reflectwalk.SkipEntry
- }
-
- switch f.Tag.Get(tagKey) {
- case "shallow":
- // If we're shallow copying then assign the value directly to the
- // struct and skip the entry.
- if v.IsValid() {
- s := w.cs[len(w.cs)-1]
- sf := reflect.Indirect(s).FieldByName(f.Name)
- if sf.CanSet() {
- sf.Set(v)
- }
- }
-
- return reflectwalk.SkipEntry
-
- case "ignore":
- // Do nothing
- return reflectwalk.SkipEntry
- }
-
- // Push the field onto the stack, we'll handle it when we exit
- // the struct field in Exit...
- w.valPush(reflect.ValueOf(f))
-
- return nil
-}
-
-// ignore causes the walker to ignore any more values until we exit this on
-func (w *walker) ignore() {
- w.ignoreDepth = w.depth
-}
-
-func (w *walker) ignoring() bool {
- return w.ignoreDepth > 0 && w.depth >= w.ignoreDepth
-}
-
-func (w *walker) pointerPeek() bool {
- return w.ps[w.depth] > 0
-}
-
-func (w *walker) valPop() reflect.Value {
- result := w.vals[len(w.vals)-1]
- w.vals = w.vals[:len(w.vals)-1]
-
- // If we're out of values, that means we popped everything off. In
- // this case, we reset the result so the next pushed value becomes
- // the result.
- if len(w.vals) == 0 {
- w.Result = nil
- }
-
- return result
-}
-
-func (w *walker) valPush(v reflect.Value) {
- w.vals = append(w.vals, v)
-
- // If we haven't set the result yet, then this is the result since
- // it is the first (outermost) value we're seeing.
- if w.Result == nil && v.IsValid() {
- w.Result = v.Interface()
- }
-}
-
-func (w *walker) replacePointerMaybe() {
- // Determine the last pointer value. If it is NOT a pointer, then
- // we need to push that onto the stack.
- if !w.pointerPeek() {
- w.valPush(reflect.Indirect(w.valPop()))
- return
- }
-
- v := w.valPop()
-
- // If the expected type is a pointer to an interface of any depth,
- // such as *interface{}, **interface{}, etc., then we need to convert
- // the value "v" from *CONCRETE to *interface{} so types match for
- // Set.
- //
- // Example if v is type *Foo where Foo is a struct, v would become
- // *interface{} instead. This only happens if we have an interface expectation
- // at this depth.
- //
- // For more info, see GH-16
- if iType, ok := w.ifaceTypes[ifaceKey(w.ps[w.depth], w.depth)]; ok && iType.Kind() == reflect.Interface {
- y := reflect.New(iType) // Create *interface{}
- y.Elem().Set(reflect.Indirect(v)) // Assign "Foo" to interface{} (dereferenced)
- v = y // v is now typed *interface{} (where *v = Foo)
- }
-
- for i := 1; i < w.ps[w.depth]; i++ {
- if iType, ok := w.ifaceTypes[ifaceKey(w.ps[w.depth]-i, w.depth)]; ok {
- iface := reflect.New(iType).Elem()
- iface.Set(v)
- v = iface
- }
-
- p := reflect.New(v.Type())
- p.Elem().Set(v)
- v = p
- }
-
- w.valPush(v)
-}
-
-// if this value is a Locker, lock it and add it to the locks slice
-func (w *walker) lock(v reflect.Value) {
- if !w.useLocks {
- return
- }
-
- if !v.IsValid() || !v.CanInterface() {
- return
- }
-
- type rlocker interface {
- RLocker() sync.Locker
- }
-
- var locker sync.Locker
-
- // We can't call Interface() on a value directly, since that requires
- // a copy. This is OK, since the pointer to a value which is a sync.Locker
- // is also a sync.Locker.
- if v.Kind() == reflect.Ptr {
- switch l := v.Interface().(type) {
- case rlocker:
- // don't lock a mutex directly
- if _, ok := l.(*sync.RWMutex); !ok {
- locker = l.RLocker()
- }
- case sync.Locker:
- locker = l
- }
- } else if v.CanAddr() {
- switch l := v.Addr().Interface().(type) {
- case rlocker:
- // don't lock a mutex directly
- if _, ok := l.(*sync.RWMutex); !ok {
- locker = l.RLocker()
- }
- case sync.Locker:
- locker = l
- }
- }
-
- // still no callable locker
- if locker == nil {
- return
- }
-
- // don't lock a mutex directly
- switch locker.(type) {
- case *sync.Mutex, *sync.RWMutex:
- return
- }
-
- locker.Lock()
- w.locks[w.depth] = locker
-}
-
-// wrapPtr is a helper that takes v and always make it *v. copystructure
-// stores things internally as pointers until the last moment before unwrapping
-func wrapPtr(v reflect.Value) reflect.Value {
- if !v.IsValid() {
- return v
- }
- vPtr := reflect.New(v.Type())
- vPtr.Elem().Set(v)
- return vPtr
-}