@@ -25,6 +25,7 @@ func Redact(iface interface{}) error {
2525 if ifv .Kind () != reflect .Ptr {
2626 return errors .New ("Not a pointer" )
2727 }
28+
2829 ift := reflect .Indirect (ifv ).Type ()
2930 if ift .Kind () != reflect .Struct {
3031 return nil
@@ -33,42 +34,6 @@ func Redact(iface interface{}) error {
3334 v := ift .Field (i )
3435 el := reflect .Indirect (ifv .Elem ().FieldByName (v .Name ))
3536 switch el .Kind () {
36- case reflect .Slice :
37- if el .CanInterface () {
38- elType := getSliceElemType (v .Type )
39-
40- // allow strings and string pointers
41- str := ""
42- if (elType .ConvertibleTo (reflect .TypeOf (str )) && reflect .TypeOf (str ).ConvertibleTo (elType )) ||
43- (elType .ConvertibleTo (reflect .TypeOf (& str )) && reflect .TypeOf (& str ).ConvertibleTo (elType )) {
44- tagVal := v .Tag .Get (tagName )
45- for i := 0 ; i < el .Len (); i ++ {
46- el .Index (i ).Set (transformValue (tagVal , el .Index (i )))
47- }
48- } else {
49- val := reflect .ValueOf (el .Interface ())
50- for i := 0 ; i < val .Len (); i ++ {
51- elVal := val .Index (i )
52- if elVal .Kind () != reflect .Ptr {
53- elVal = elVal .Addr ()
54- }
55- Redact (elVal .Interface ())
56- }
57- }
58- }
59- case reflect .Map :
60- if el .CanInterface () {
61- val := reflect .ValueOf (el .Interface ())
62- for _ , key := range val .MapKeys () {
63- mapValue := val .MapIndex (key )
64- mapValuePtr := reflect .New (mapValue .Type ())
65- mapValuePtr .Elem ().Set (mapValue )
66- if mapValuePtr .Elem ().CanAddr () {
67- Redact (mapValuePtr .Elem ().Addr ().Interface ())
68- }
69- val .SetMapIndex (key , reflect .Indirect (mapValuePtr ))
70- }
71- }
7237 case reflect .Struct :
7338 if el .CanAddr () && el .Addr ().CanInterface () {
7439 Redact (el .Addr ().Interface ())
@@ -79,6 +44,72 @@ func Redact(iface interface{}) error {
7944 input := el .String ()
8045 el .SetString (transformString (input , tagVal ))
8146 }
47+ default :
48+ tagVal := v .Tag .Get (tagName )
49+ if el .CanAddr () && el .Addr ().CanInterface () {
50+ redactHelper (el .Addr ().Interface (), tagVal )
51+ }
52+
53+ }
54+ }
55+ return nil
56+ }
57+
58+ func redactHelper (iface interface {}, tagVal string ) error {
59+ ifv := reflect .ValueOf (iface )
60+ if ifv .Kind () != reflect .Ptr {
61+ return errors .New ("Not a pointer" )
62+ }
63+
64+ ifIndirectValue := reflect .Indirect (ifv )
65+ switch ifIndirectValue .Kind () {
66+ case reflect .Slice :
67+ if ifIndirectValue .CanInterface () {
68+ elType := getSliceElemType (ifIndirectValue .Type ())
69+
70+ // allow strings and string pointers
71+ str := ""
72+ if (elType .ConvertibleTo (reflect .TypeOf (str )) && reflect .TypeOf (str ).ConvertibleTo (elType )) ||
73+ (elType .ConvertibleTo (reflect .TypeOf (& str )) && reflect .TypeOf (& str ).ConvertibleTo (elType )) {
74+ for i := 0 ; i < ifIndirectValue .Len (); i ++ {
75+ ifIndirectValue .Index (i ).Set (transformValue (tagVal , ifIndirectValue .Index (i )))
76+ }
77+ } else {
78+ val := reflect .ValueOf (ifIndirectValue .Interface ())
79+ for i := 0 ; i < val .Len (); i ++ {
80+ elVal := val .Index (i )
81+ if elVal .Kind () != reflect .Ptr {
82+ elVal = elVal .Addr ()
83+ }
84+ redactHelper (elVal .Interface (), tagVal )
85+ }
86+ }
87+ }
88+ case reflect .Map :
89+ if ifIndirectValue .CanInterface () {
90+ val := reflect .ValueOf (ifIndirectValue .Interface ())
91+ for _ , key := range val .MapKeys () {
92+ mapValue := val .MapIndex (key )
93+ mapValuePtr := reflect .New (mapValue .Type ())
94+ mapValuePtr .Elem ().Set (mapValue )
95+ if mapValuePtr .Elem ().CanAddr () {
96+ redactHelper (mapValuePtr .Elem ().Addr ().Interface (), tagVal )
97+ }
98+ val .SetMapIndex (key , reflect .Indirect (mapValuePtr ))
99+ }
100+ }
101+ case reflect .Struct :
102+ if ifIndirectValue .CanAddr () && ifIndirectValue .Addr ().CanInterface () {
103+ Redact (ifIndirectValue .Addr ().Interface ())
104+ }
105+ case reflect .String :
106+ if ifIndirectValue .CanSet () {
107+ input := ifIndirectValue .String ()
108+ ifIndirectValue .SetString (transformString (input , tagVal ))
109+ }
110+ case reflect .Ptr :
111+ if ifIndirectValue .CanInterface () {
112+ redactHelper (ifIndirectValue .Interface (), tagVal )
82113 }
83114 }
84115 return nil
0 commit comments