parser.go 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. package grapher
  2. import (
  3. "bytes"
  4. "fmt"
  5. "gopkg.in/yaml.v2"
  6. )
  7. // ImportMultiDocYAML is a helper function that goes through a yaml file with multiple documents (or objects)
  8. // separated by '---' or '...' and returns an array of yamls.
  9. func ImportMultiDocYAML(source []byte) (arr []map[string]interface{}) {
  10. dec := yaml.NewDecoder(bytes.NewReader(source))
  11. for {
  12. doc := make(map[interface{}]interface{})
  13. if dec.Decode(&doc) != nil {
  14. return arr
  15. }
  16. strmap := recursiveConv(doc).(map[string]interface{})
  17. arr = append(arr, strmap)
  18. }
  19. }
  20. // recursive helper function that type asserts each layer of nested interfaces to
  21. // retrieve child value. Every call of GetField must be accompanied with a type assertion.
  22. func getField(yaml map[string]interface{}, keys ...string) interface{} {
  23. if yaml[keys[0]] == nil {
  24. return nil
  25. }
  26. if len(keys) == 1 {
  27. return yaml[keys[0]]
  28. }
  29. return getField(yaml[keys[0]].(map[string]interface{}), keys[1:]...)
  30. }
  31. // recursively convert all key values in generic interface{} format into strings.
  32. // i.e. map[interface{}]interface{} --> map[string]interface{}
  33. func recursiveConv(m interface{}) interface{} {
  34. switch o := m.(type) {
  35. // quickly skip if object already has strings as keys
  36. case map[string]interface{}:
  37. for k, v := range o {
  38. o[k] = recursiveConv(v)
  39. }
  40. case map[interface{}]interface{}:
  41. res := make(map[string]interface{})
  42. for k, v := range o {
  43. // ✨ sprinkle of efficiency by skipping string keys
  44. switch kt := k.(type) {
  45. case string:
  46. res[kt] = recursiveConv(v)
  47. default:
  48. res[fmt.Sprint(kt)] = recursiveConv(v)
  49. }
  50. }
  51. m = res
  52. case []interface{}:
  53. for i, v := range o {
  54. o[i] = recursiveConv(v)
  55. }
  56. }
  57. return m
  58. }