fatih / structs

Utilities for Go structs

Home Page:http://godoc.org/github.com/fatih/structs

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Add ability to retrieve tag names from struct

dominicbarnes opened this issue · comments

I would like to build a SQL statement without using * using an empty struct. It would be nice if I could retrieve all the "tag names", similar to how Names() works. For example:

type Person struct {
  FirstName string `structs:"first_name"`
  LastName string `structs:"last_name"`
}

p := new(Person)

names := structs.Names(p)
// names = []string{"FirstName", "LastName"}

// not currently possible
tagNames := structs.TagNames(p)
// tagNames = []string{"first_name", "last_name"}

I would argue that this is acceptable in this library since it deals with a tag that this package manages. A temporary workaround is to export the struct to a map and extract the keys from that. (but it would be great if this library could remove that boilerplate)

Hi @dominicbarnes

To get the tags you also need to define the tag key name. Such as structs, json, etc.. You can do it already with the following (for your example):

package main

import (
	"fmt"

	"github.com/fatih/structs"
)

type Person struct {
	FirstName string `structs:"first_name"`
	LastName  string `structs:"last_name"`
}

func main() {
	var tagNames []string
	for _, f := range structs.New(Person{}).Fields() {
		tagNames = append(tagNames, f.Tag("structs"))
	}

	fmt.Println(tagNames)
}

As you see it's just three lines to collect all tag names. I don't want to further expand this library as I believe it already provides the necessary API. Thanks for you feedback.

The example you have misses quite a few details, such as additional parts in the tag like omitempty or omitnested and using - or empty string to ignore a field. Plus, it's inconvenient to establish my own for loop to accomplish this.

Would you at least be open to a PR that adds this feature? (rather than needing to write it yourself?)

I'm not sure those are important. The struct pkg will take care of it already. Can you share an example what you mean?

To elaborate on my first example:

type Person struct {
  FirstName string    `structs:"first_name"`
  LastName  string    `structs:"last_name"`
  Birthdate time.Time `structs:"birthdate,omitnested"`
  CacheKey  string    `structs:"-"`
}

Using the code you have above, I'd end up with:

[]string{"first_name", "last_name", "birthdate,omitnested", "-"}

But what I really want is:

[]string{"first_name", "last_name", "birthdate"}

Hi @dominicbarnes

I see what you mean. I worked on a separate, improved and powerful tags package that deals with this any many other things. Let keep this open, I'll add the necessary feature once I have time (just need to replace the internal tags.go file with the package I wrote and expose it with some well defined API's)