@@ -19,10 +19,11 @@ type fieldMap map[string][]int
1919// behaves like most marshallers, optionally obeying a field tag for name
2020// mapping and a function to provide a basic mapping of fields to names.
2121type Mapper struct {
22- cache map [reflect.Type ]fieldMap
23- tagName string
24- mapFunc func (string ) string
25- mutex sync.Mutex
22+ cache map [reflect.Type ]fieldMap
23+ tagName string
24+ tagMapFunc func (string ) string
25+ mapFunc func (string ) string
26+ mutex sync.Mutex
2627}
2728
2829// NewMapper returns a new mapper which optionally obeys the field tag given
@@ -34,6 +35,18 @@ func NewMapper(tagName string) *Mapper {
3435 }
3536}
3637
38+ // NewMapperTagFunc returns a new mapper which contains a mapper for field names
39+ // AND a mapper for tag values. This is useful for tags like json which can
40+ // have values like "name,omitempty".
41+ func NewMapperTagFunc (tagName string , mapFunc , tagMapFunc func (string ) string ) * Mapper {
42+ return & Mapper {
43+ cache : make (map [reflect.Type ]fieldMap ),
44+ tagName : tagName ,
45+ mapFunc : mapFunc ,
46+ tagMapFunc : tagMapFunc ,
47+ }
48+ }
49+
3750// NewMapperFunc returns a new mapper which optionally obeys a field tag and
3851// a struct field name mapper func given by f. Tags will take precedence, but
3952// for any other field, the mapped name will be f(field.Name)
@@ -51,7 +64,7 @@ func (m *Mapper) TypeMap(t reflect.Type) fieldMap {
5164 m .mutex .Lock ()
5265 mapping , ok := m .cache [t ]
5366 if ! ok {
54- mapping = getMapping (t , m .tagName , m .mapFunc )
67+ mapping = getMapping (t , m .tagName , m .mapFunc , m . tagMapFunc )
5568 m .cache [t ] = mapping
5669 }
5770 m .mutex .Unlock ()
@@ -202,9 +215,9 @@ func apnd(is []int, i int) []int {
202215 return x
203216}
204217
205- // getMapping returns a mapping for the t type, using the tagName and the mapFunc
206- // to determine the canonical names of fields.
207- func getMapping (t reflect.Type , tagName string , mapFunc func (string ) string ) fieldMap {
218+ // getMapping returns a mapping for the t type, using the tagName, mapFunc and
219+ // tagMapFunc to determine the canonical names of fields.
220+ func getMapping (t reflect.Type , tagName string , mapFunc , tagMapFunc func (string ) string ) fieldMap {
208221 queue := []typeQueue {}
209222 queue = append (queue , typeQueue {Deref (t ), []int {}})
210223 m := fieldMap {}
@@ -223,6 +236,8 @@ func getMapping(t reflect.Type, tagName string, mapFunc func(string) string) fie
223236 } else {
224237 name = f .Name
225238 }
239+ } else if tagMapFunc != nil {
240+ name = tagMapFunc (name )
226241 }
227242
228243 // if the name is "-", disabled via a tag, skip it
0 commit comments