https://github.com/globusdigital/deep-copy
Deep copy generator
https://github.com/globusdigital/deep-copy
code-generator generator go golang
Last synced: 5 months ago
JSON representation
Deep copy generator
- Host: GitHub
- URL: https://github.com/globusdigital/deep-copy
- Owner: globusdigital
- License: bsd-3-clause
- Created: 2020-01-07T13:16:10.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2024-05-10T19:09:25.000Z (about 2 years ago)
- Last Synced: 2024-06-18T20:16:59.469Z (almost 2 years ago)
- Topics: code-generator, generator, go, golang
- Language: Go
- Size: 56.6 KB
- Stars: 147
- Watchers: 5
- Forks: 33
- Open Issues: 9
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# deep-copy
deep-copy is a tool for generating DeepCopy() functions for a given type.
Given a package directory, and a type name that appears in that package, a
`DeepCopy` method will be generated, to create a deep copy of the type value.
Members of the type will also be copied deeply, recursively. If a member `T` of
the type has a method `DeepCopy() [*]T`, that method will be reused. Multiple
types can be specified for the given package, by adding more `--type`
parameters.
To specify a pointer receiver for the method, an optional `--pointer-receiver`
boolean flag can be specified. The flag will also govern whether the return
type is a pointer as well.
To specify build tags in the generated code, an optional `--tags` comma separated
list flag can be specified. The flag will add all items as build tags to the
generated code.
It might also be desirable to skip deeply copying certain fields, slice
members, or map members. To achieve that, selectors can be specified in the
optional comma-separated `--skip` flag. Multiple `--skip` flags can be
specified, to match the number of `--type` flags. For example, given the
following type:
```go
type Foo struct {
J *int
B Bar
}
type Bar struct {
I *int
}
```
Leaving the 'B' field as a shallow copy can be achieved by specifying `--skip
B`. To skip deeply copying the inner 'I' field, one can specify `--skip B.I`.
Slice and Map members can also be skipped, by adding `[i]` and `[k]`
respectively.
To specify a max depth of deep copying, use `--maxdepth` option. It stops
deep copying at a given depth, with a warning message spotting a place
the deep copying has been stopped. It might especially be useful when
one or more structs have circular references.
To change a method name of deep copying, use `--method` option.
## Usage
Pass either path to the folder containing the types or the module name:
```bash
deep-copy /path/to/package/containing/type
deep-copy github.com/globusdigital/deep-copy
deep-copy github.com/globusdigital/deep-copy/some/sub/packages
```
Here is the full set of supported flags:
```bash
deep-copy \
[-o /output/path.go] \
[--method DeepCopy] \
[--pointer-receiver] \
[--skip Selector1,Selector.Two --skip Selector2[i], Selector.Three[k]]
[--type Type1 --type Type2\ \
[--tags mytag,anotherTag ] \ \
/path/to/package/containing/type
```
## Example
Given the following types:
```go
package pkg
type Foo struct {
Map map[string]*Bar
ch chan float32
baz Baz
}
type Bar struct {
IntV int
Slice []string
}
type Baz struct {
String string
StringPointer *string
}
```
Running `deep-copy --type Foo ./path/to/pkg` will generate:
```go
// Code generated by deep-copy --type Foo ./path/to/pkg; DO NOT EDIT.
package pkg
// DeepCopy generates a deep copy of Foo
func (o Foo) DeepCopy() Foo {
var cp Foo
cp = o
if o.Map != nil {
cp.Map = make(map[string]*Bar, len(o.Map))
for k, v := range o.Map {
var cpv *Bar
if v != nil {
cpv = new(Bar)
*cpv = *v
if v.Slice != nil {
cpv.Slice = make([]string, len(v.Slice))
copy(cpv.Slice, v.Slice)
}
}
cp.Map[k] = cpv
}
}
if o.ch != nil {
cp.ch = make(chan float32, cap(o.ch))
}
if o.baz.StringPointer != nil {
cp.baz.StringPointer = new(string)
*cp.baz.StringPointer = *o.baz.StringPointer
}
return cp
}
```