From fc5199c8cc0393a6c88c020e475381b7bfb67220 Mon Sep 17 00:00:00 2001 From: Fatih Arslan Date: Thu, 7 Aug 2014 18:17:41 +0300 Subject: [PATCH] tags: parse tag names and options --- tags.go | 39 +++++++++++++++++++++++++++++++++++++++ tags_test.go | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 tags.go create mode 100644 tags_test.go diff --git a/tags.go b/tags.go new file mode 100644 index 0000000..c096728 --- /dev/null +++ b/tags.go @@ -0,0 +1,39 @@ +package structure + +import "strings" + +// tagOptions contains a slice of tag options +type tagOptions []string + +// Has returns true if the given opt is available inside the slice. +func (t tagOptions) Has(opt string) bool { + for _, tagOpt := range t { + if tagOpt == opt { + return true + } + } + + return false +} + +// parseTag splits a struct field's tag into its name and a list of options +// which comes after a name +func parseTag(tag string) (string, tagOptions) { + res := strings.Split(tag, ",") + + // tag = "" + if len(res) == 0 { + return tag, res + } + + // tag = "name" + if len(res) == 1 { + return tag, res[1:] + } + + // tag is one of followings: + // "name,opt" + // "name,opt,opt2" + // ",opt" + return res[0], res[1:] +} diff --git a/tags_test.go b/tags_test.go new file mode 100644 index 0000000..d914241 --- /dev/null +++ b/tags_test.go @@ -0,0 +1,45 @@ +package structure + +import "testing" + +func TestParseTag_Name(t *testing.T) { + tags := []struct { + tag string + has bool + }{ + {"name", true}, + {"name,opt", true}, + {"name , opt, opt2", false}, // has a single whitespace + {", opt, opt2", false}, + } + + for _, tag := range tags { + name, _ := parseTag(tag.tag) + + if (name != "name") && tag.has { + t.Errorf("Parse tag should return name: %#v", tag) + } + } +} + +func TestParseTag_Opts(t *testing.T) { + tags := []struct { + opts string + has bool + }{ + {"name", false}, + {"name,opt", true}, + {"name , opt, opt2", false}, // has a single whitespace + {",opt, opt2", true}, + {", opt3, opt4", false}, + } + + // search for "opt" + for _, tag := range tags { + _, opts := parseTag(tag.opts) + + if opts.Has("opt") != tag.has { + t.Errorf("Tag opts should have opt: %#v", tag) + } + } +}