MCPcopy Index your code
hub / github.com/go-task/task / TraverseStringsFunc

Function TraverseStringsFunc

internal/deepcopy/deepcopy.go:73–167  ·  view source on GitHub ↗

TraverseStringsFunc runs the given function on every string in the given value by traversing it recursively. If the given value is a string, the function will run on a copy of the string and return it. If the value is a struct, map or a slice, the function will recursively call itself for each field

(v T, fn func(v string) (string, error))

Source from the content-addressed store, hash-verified

71// field or element of the struct, map or slice until all strings inside the
72// struct or slice are replaced.
73func TraverseStringsFunc[T any](v T, fn func(v string) (string, error)) (T, error) {
74 original := reflect.ValueOf(v)
75 if original.Kind() == reflect.Invalid || !original.IsValid() {
76 return v, nil
77 }
78 copy := reflect.New(original.Type()).Elem()
79
80 var traverseFunc func(copy, v reflect.Value) error
81 traverseFunc = func(copy, v reflect.Value) error {
82 switch v.Kind() {
83
84 case reflect.Pointer:
85 // Unwrap the pointer
86 originalValue := v.Elem()
87 // If the pointer is nil, do nothing
88 if !originalValue.IsValid() {
89 return nil
90 }
91 // Create an empty copy from the original value's type
92 copy.Set(reflect.New(originalValue.Type()))
93 // Unwrap the newly created pointer and call traverseFunc recursively
94 if err := traverseFunc(copy.Elem(), originalValue); err != nil {
95 return err
96 }
97
98 case reflect.Interface:
99 // Unwrap the interface
100 originalValue := v.Elem()
101 if !originalValue.IsValid() {
102 return nil
103 }
104 // Create an empty copy from the original value's type
105 copyValue := reflect.New(originalValue.Type()).Elem()
106 // Unwrap the newly created pointer and call traverseFunc recursively
107 if err := traverseFunc(copyValue, originalValue); err != nil {
108 return err
109 }
110 copy.Set(copyValue)
111
112 case reflect.Struct:
113 // Loop over each field and call traverseFunc recursively
114 for i := range v.NumField() {
115 if err := traverseFunc(copy.Field(i), v.Field(i)); err != nil {
116 return err
117 }
118 }
119
120 case reflect.Slice:
121 // Create an empty copy from the original value's type
122 copy.Set(reflect.MakeSlice(v.Type(), v.Len(), v.Cap()))
123 // Loop over each element and call traverseFunc recursively
124 for i := range v.Len() {
125 if err := traverseFunc(copy.Index(i), v.Index(i)); err != nil {
126 return err
127 }
128 }
129
130 case reflect.Map:

Callers 1

ReplaceWithExtraFunction · 0.92

Calls 5

traverseFuncFuncType · 0.85
KindMethod · 0.65
SetMethod · 0.45
LenMethod · 0.45
StringMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…