Skip to content
This repository has been archived by the owner on Oct 11, 2018. It is now read-only.

Add ability to retrieve tag names from struct #81

Closed
dominicbarnes opened this issue Jan 9, 2017 · 5 comments
Closed

Add ability to retrieve tag names from struct #81

dominicbarnes opened this issue Jan 9, 2017 · 5 comments

Comments

@dominicbarnes
Copy link

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)

@fatih
Copy link
Owner

fatih commented Jan 11, 2017

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.

@fatih fatih closed this as completed Jan 11, 2017
@dominicbarnes
Copy link
Author

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?)

@fatih
Copy link
Owner

fatih commented Jan 11, 2017

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

@dominicbarnes
Copy link
Author

dominicbarnes commented Jan 11, 2017

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"}

@fatih
Copy link
Owner

fatih commented Jan 13, 2017

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)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants