Skip to content

Commit

Permalink
Merge pull request #5 from muir/expose
Browse files Browse the repository at this point in the history
Expose TagSet.Tags
  • Loading branch information
muir committed Nov 11, 2021
2 parents defa64b + bf7b427 commit 576e86b
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 7 deletions.
13 changes: 8 additions & 5 deletions parsetag.go
Expand Up @@ -29,7 +29,8 @@ type Tags []Tag
// TagSet is a simple transformation of an array of Tag into an
// indexted structure so that lookup is efficient.
type TagSet struct {
tags []Tag
// Tags is a read-only value
Tags Tags
index map[string]int
}

Expand Down Expand Up @@ -70,7 +71,7 @@ func (s TagSet) Get(tag string) Tag {

func (s TagSet) Lookup(tag string) (Tag, bool) {
if i, ok := s.index[tag]; ok {
return s.tags[i], true
return s.Tags[i], true
}
return mkTag("", ""), false
}
Expand All @@ -81,7 +82,7 @@ func (t Tags) Set() TagSet {
index[tag.Tag] = i
}
return TagSet{
tags: t,
Tags: t,
index: index,
}
}
Expand All @@ -99,6 +100,10 @@ func (t Tags) Set() TagSet {
// comma-separated list of tag elements: "flag", "!flag" (sets to false), "flag=true",
// "flag=false", "flag=0", "flag=1", "flag=t", "flag=f", "flag=T", "flag=F".
// It will set Int by looking for "intValue=280" (set to 280).
//
// When filling an array value, the default character to split upon is
// comma, but other values can be set with "split=X" to split on X.
// Special values of X are "quote", "space", and "none"
func (tag Tag) Fill(model interface{}, opts ...FillOptArg) error {
opt := fillOpt{
tag: "pt",
Expand Down Expand Up @@ -156,8 +161,6 @@ func (tag Tag) Fill(model interface{}, opts ...FillOptArg) error {
if strings.HasPrefix(part, "split=") {
splitOn := part[len("split="):]
switch splitOn {
case "comma":
splitOn = ","
case "quote":
splitOn = `"`
case "space":
Expand Down
17 changes: 16 additions & 1 deletion unpack.go
Expand Up @@ -17,6 +17,11 @@ type stringSetterOpts struct {

type StringSetterArg func(*stringSetterOpts)

// WithSplitOn specifies how to split strings into slices
// or arrays. An empty string indicates that input strings
// should not be split. That's different than the behavior
// of strings.Split(). If unspecified, strings will be split
// on comma (,).
func WithSplitOn(s string) StringSetterArg {
return func(o *stringSetterOpts) {
o.split = s
Expand Down Expand Up @@ -128,6 +133,11 @@ func MakeStringSetter(t reflect.Type, optArgs ...StringSetterArg) (func(target r
if err != nil {
return nil, err
}
if opts.split == "" {
return func(target reflect.Value, value string) error {
return setElem(target.Index(0), value)
}, nil
}
return func(target reflect.Value, value string) error {
for i, v := range strings.SplitN(value, opts.split, target.Cap()) {
err := setElem(target.Index(i), v)
Expand All @@ -143,7 +153,12 @@ func MakeStringSetter(t reflect.Type, optArgs ...StringSetterArg) (func(target r
return nil, err
}
return func(target reflect.Value, value string) error {
values := strings.Split(value, opts.split)
var values []string
if opts.split != "" {
values = strings.Split(value, opts.split)
} else {
values = []string{value}
}
a := reflect.MakeSlice(target.Type(), len(values), len(values))
for i, v := range values {
err := setElem(a.Index(i), v)
Expand Down
13 changes: 12 additions & 1 deletion unpack_test.go
Expand Up @@ -54,6 +54,12 @@ func TestStringSetter(t *testing.T) {
Foo Foo `value:"foo" want:"~foo~"`
FooArray [2]Foo `value:"a,b,c" want:"[~a~ ~b,c~]"`
FooP *Foo `value:"foo" want:"~foo~"`
SS1 []string `value:"foo/bar" want:"[foo/bar]"`
SS2 []string `value:"foo/bar" want:"[foo bar]" split:"/"`
SS3 []string `value:"foo,bar" want:"[foo,bar]" split:""`
SA1 [2]string `value:"foo/bar" want:"[foo/bar ]"`
SA2 [2]string `value:"foo/bar" want:"[foo bar]" split:"/"`
SA3 [2]string `value:"foo,bar" want:"[foo,bar ]" split:""`
}
var ts tsType
vp := reflect.ValueOf(&ts)
Expand All @@ -69,7 +75,12 @@ func TestStringSetter(t *testing.T) {
if !ok {
want = value
}
fn, err := reflectutils.MakeStringSetter(f.Type)
var opts []reflectutils.StringSetterArg
if split, ok := f.Tag.Lookup("split"); ok {
t.Log(" splitting on", split)
opts = append(opts, reflectutils.WithSplitOn(split))
}
fn, err := reflectutils.MakeStringSetter(f.Type, opts...)
if !assert.NoErrorf(t, err, "make string setter for %s", f.Name) {
return true
}
Expand Down

0 comments on commit 576e86b

Please sign in to comment.