github.com/livekit/protocol@v1.39.3/utils/deepcopy.go (about) 1 // Copyright 2024 LiveKit, Inc. 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 utils 16 17 import ( 18 "reflect" 19 ) 20 21 func DeepCopy[T any](v T) T { 22 return deepCopy(reflect.ValueOf(v)).Interface().(T) 23 } 24 25 func deepCopy(v reflect.Value) reflect.Value { 26 switch v.Type().Kind() { 27 case reflect.Array: 28 c := reflect.New(v.Type()).Elem() 29 for i := range v.Len() { 30 c.Index(i).Set(deepCopy(v.Index(i))) 31 } 32 return c 33 34 case reflect.Map: 35 if v.IsNil() { 36 return v 37 } 38 c := reflect.MakeMap(v.Type()) 39 for mr := v.MapRange(); mr.Next(); { 40 c.SetMapIndex(deepCopy(mr.Key()), deepCopy(mr.Value())) 41 } 42 return c 43 44 case reflect.Pointer: 45 if v.IsNil() { 46 return v 47 } 48 c := reflect.New(v.Type().Elem()) 49 c.Elem().Set(deepCopy(v.Elem())) 50 return c 51 52 case reflect.Slice: 53 if v.IsNil() { 54 return v 55 } 56 c := reflect.MakeSlice(v.Type(), v.Len(), v.Cap()) 57 for i := range v.Len() { 58 c.Index(i).Set(deepCopy(v.Index(i))) 59 } 60 return c 61 62 case reflect.Struct: 63 c := reflect.New(v.Type()).Elem() 64 for i := range v.NumField() { 65 if c.Field(i).CanSet() { 66 c.Field(i).Set(deepCopy(v.Field(i))) 67 } 68 } 69 return c 70 71 default: // Bool, Chan, Complex128, Complex64, Float32, Float64, Func, Int, Int16, Int32, Int64, Int8, Interface, String, Uint, Uint16, Uint32, Uint64, Uint8, Uintptr, UnsafePointer 72 return v 73 } 74 }