/goreset

Generates automatically a Reset() method

Primary LanguageGoBSD 3-Clause "New" or "Revised" LicenseBSD-3-Clause

Build Status

Goreset

goreset generates reset method for any structure, allowing to reuse it easily. It has been written to use sync.pool without fear of tricky bugs as one field not properly reset before reuse.

Just run goreset and be sure that the reset method will wipe clean your instanciated structure.

Installation

go get github.com/mrsinham/goreset

Usage

With the following structure in the mystructure.go file :

package mypackage

type simple struct {
	field1  int
	field2  string
	field3  []string
	field4  [3]int
	field5  *http.Client
	field6  float32
	field7  float64
	field8  complex64
	field9  complex128
	field10 bool
	field11 byte
	field12 rune
	field13 uintptr
	field14 func()
}

if you run :

$ goreset github.com/me/mypackage mystructure

you will have this output :

package mypackage

func (s *simple) Reset() {
	s.field1 = 0
	s.field2 = ""
	s.field3 = nil
	s.field4 = [3]int{}
	s.field5 = nil
	s.field6 = 0.0
	s.field7 = 0.0
	s.field8 = 0
	s.field9 = 0
	s.field10 = false
	s.field11 = 0
	s.field12 = 0
	s.field13 = 0
	s.field14 = nil
}

just add the -w flag to write it to mystructure_reset.go.

goreset handles many types as you can see :

package mypackage

import "net/http"

type mystructure struct {
	field1 int
	field2 string
	field3 [5]int
	field4 []string
	field5 chan int
	field6 chan chan string
	field7 *http.Client
}

gives you :

package mypackage

func (m *mystructure) Reset() {
	m.field1 = 0
	m.field2 = ""
	m.field3 = [5]int{}
	m.field4 = nil
	m.field5 = nil
	m.field6 = nil
	m.field7 = nil
}

Reinstanciate fields

Sometimes you don't want to have the zero value, you want to have those already instanciated. For this you cant use the reset:"nonil" tag.

package mypackage

import "net/http"

type mystructure struct {
	field1 *http.Client `reset:"nonil"`
	field2 []chan *http.Client `reset:"nonil"`
}

gives you :

$ go build && ./goreset github.com/mrsinham/mypackage mystructure   
goreset
package mypackage

import http "net/http"

func (m *mystructure) Reset() {
        m.field = &http.Client{}
        m.field = make([]chan *http.Client, 0)
}

Composition

Given those two structures :

type composition struct {
	subfield1 int
	subfield2 string
}

type composited struct {
	composition
	fieldsimple string
}

goreset will generate :

// Code generated by github.com/mrsinham/goreset. DO NOT EDIT.
package composition

func (c *composited) Reset() {
	c.subfield1 = 0
	c.subfield2 = ""
	c.fieldsimple = ""
}

And if your composited field is external :

package compositionexternal

import "github.com/mrsinham/goreset/test/compositionexternal/sub"

type base struct {
	field1 string
	sub.Sub
}
package sub

type Sub struct {
	Field1 string
}

you will have

// Code generated by github.com/mrsinham/goreset. DO NOT EDIT.
package compositionexternal

func (b *base) Reset() {
	b.field1 = ""
	b.Field1 = ""
}
If one field of the sub structure is not exported :
package compositionexternal

import "github.com/mrsinham/goreset/test/compositionexternal/sub"

type compositionNotExported struct {
	field1 string
	sub.Sub2
}
type Sub2 struct {
	field3 string
}

You will have :

// Code generated by github.com/mrsinham/goreset. DO NOT EDIT.
package compositionexternal

import sub "github.com/mrsinham/goreset/test/compositionexternal/sub"

func (c *compositionNotExported) Reset() {
	c.field1 = ""
	c.Sub2 = sub.Sub2{}
}

Reset method detection

If your composited structure or interfaces have already a Reset method (with empty param), the code generated will try to call it.

package nonilexternalreset

import "github.com/mrsinham/goreset/test/nonil/external"

type nonilExternalWithReset struct {
	Field1 int
	external.ExternalReset
	interfaceReset
}

type interfaceReset interface {
	Reset()
}
package external

type ExternalReset struct {
	field1 int
}

func (e *ExternalReset) Reset() {
	e.field1 = 0
}

You will have :

// Code generated by github.com/mrsinham/goreset. DO NOT EDIT.
package nonilexternalreset

func (n *nonilExternalWithReset) Reset() {
	n.Field1 = 0
	n.ExternalReset.Reset()
	if n.interfaceReset != nil {
		n.interfaceReset.Reset()
	} else {
		n.interfaceReset = nil
	}
}

Anonymous structures

Given these :

package structnoname

import "net/http"

type structnoname struct {
	field1 int
	field2 struct {
		tutu1, tutu2 *http.Request
		tutu3        struct {
			file string
		}
	}
}

You will have :

// Code generated by github.com/mrsinham/goreset. DO NOT EDIT.
package structnoname

import http "net/http"

func (s *structnoname) Reset() {
	s.field1 = 0
	s.field2 = struct {
		tutu1 *http.Request
		tutu2 *http.Request
		tutu3 struct {
			file string
		}
	}{}
}

Status

Goreset is young and still under development but you can already use it the most of the cases. A bunch of tests are already implemented but it is sure that all cases are not covered as the utility is still young.

Bug, feature ?

Please submit an issue or a pull request, let's fix this together ;)

Dependencies

The two main dependencies are :

TODO

  • autobuild of dependencies (to be up to date with code)
  • interface by composition
  • nonil on inherited fields
  • inherited of inherited fields of inherited...
  • detection of Reset() method on composition
  • detection of reset method of fields