Skip to content

Instantly share code, notes, and snippets.

@kaynetik
Created January 29, 2021 19:37
Show Gist options
  • Save kaynetik/547d1d5748f22881d38577312e384335 to your computer and use it in GitHub Desktop.
Save kaynetik/547d1d5748f22881d38577312e384335 to your computer and use it in GitHub Desktop.
Dynamic tags alteration
// Route marshaler
// Implements the Marhaler interface of the yaml pkg.
func (p Path) MarshalYAML() (interface{}, error) {
res, err := marshalYAML("SetTagYAML", p)
if err != nil {
return res, fmt.Errorf("failed to marshal yaml: %w", err)
}
return string(res), nil
}
func (p Path) SetTagYAML(tag string) string {
if tag == "route" {
return p.Route
}
return tag
}
func marshalYAML(tagSetter string, marshalObject interface{}) ([]byte, error) {
out := map[string]interface{}{}
t := reflect.TypeOf(marshalObject)
v := reflect.ValueOf(marshalObject)
funcCtx := v.MethodByName(tagSetter)
outTag := ""
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
switch n := f.Tag.Get("yaml"); n {
case "":
outTag = f.Name
case "-":
outTag = ""
default:
outTag = alterTagName(funcCtx, n)
}
if outTag != "" {
out[outTag] = v.Field(i).Interface()
}
}
res, err := yaml.Marshal(out)
return res, err
}
func alterTagName(funcCtx reflect.Value, params ...interface{}) string {
in := make([]reflect.Value, len(params))
for k, param := range params {
in[k] = reflect.ValueOf(param)
}
res := funcCtx.Call(in)[0].String()
return res
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment