Skip to content

Instantly share code, notes, and snippets.

@ryankurte
Created April 27, 2017 04:04
Show Gist options
  • Save ryankurte/b611afc9ab4037c3a8791a14621ddbab to your computer and use it in GitHub Desktop.
Save ryankurte/b611afc9ab4037c3a8791a14621ddbab to your computer and use it in GitHub Desktop.
Golang structure field parsing helper
/**
* Recursive struct parser for parsing string fields in go structure
* Copyright 2017 Ryan Kurte
* Released under the MIT License (https://choosealicense.com/licenses/mit/)
*/
package parser
import (
"log"
"os"
"reflect"
)
// Parse is a string parsing function to be called when strings are found
type Parse func(in string) string
// ParseStructStrings reflects over a structure and calls Parse when strings are located
func ParseStructStrings(parse Parse, obj interface{}) {
parseStringsRecursive(parse, reflect.ValueOf(obj))
}
func parseStringsRecursive(parse Parse, val reflect.Value) {
switch val.Kind() {
case reflect.Ptr:
o := val.Elem()
if !o.IsValid() {
log.Panicf("Reflecting parser error: invalid pointer %+v", val)
}
parseStringsRecursive(parse, o)
case reflect.Struct:
for i := 0; i < val.NumField(); i++ {
parseStringsRecursive(parse, val.Field(i))
}
case reflect.Slice:
for i := 0; i < val.Len(); i++ {
parseStringsRecursive(parse, val.Index(i))
}
case reflect.Map:
for _, k := range val.MapKeys() {
mapVal := val.MapIndex(k)
if mapVal.Kind() == reflect.String {
val.SetMapIndex(k, reflect.ValueOf(parse(mapVal.String())))
} else {
// TODO: this is going to fail so hard with objects in maps
log.Panicf("Reflecting parser error: structs-in-maps not supported")
}
}
case reflect.String:
value := parse(val.String())
val.SetString(value)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment