interpolation.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. package interpolation
  2. import (
  3. "fmt"
  4. "github.com/aanand/compose-file/template"
  5. "github.com/aanand/compose-file/types"
  6. )
  7. func Interpolate(config types.Dict, section string, mapping template.Mapping) (types.Dict, error) {
  8. out := types.Dict{}
  9. for name, item := range config {
  10. if item == nil {
  11. out[name] = nil
  12. continue
  13. }
  14. interpolatedItem, err := interpolateSectionItem(name, item.(types.Dict), section, mapping)
  15. if err != nil {
  16. return nil, err
  17. }
  18. out[name] = interpolatedItem
  19. }
  20. return out, nil
  21. }
  22. func interpolateSectionItem(
  23. name string,
  24. item types.Dict,
  25. section string,
  26. mapping template.Mapping,
  27. ) (types.Dict, error) {
  28. out := types.Dict{}
  29. for key, value := range item {
  30. interpolatedValue, err := recursiveInterpolate(value, mapping)
  31. if err != nil {
  32. return nil, fmt.Errorf(
  33. "Invalid interpolation format for %#v option in %s %#v: %#v",
  34. key, section, name, err.Template,
  35. )
  36. }
  37. out[key] = interpolatedValue
  38. }
  39. return out, nil
  40. }
  41. func recursiveInterpolate(
  42. value interface{},
  43. mapping template.Mapping,
  44. ) (interface{}, *template.InvalidTemplateError) {
  45. switch value := value.(type) {
  46. case string:
  47. return template.Substitute(value, mapping)
  48. case types.Dict:
  49. out := types.Dict{}
  50. for key, elem := range value {
  51. interpolatedElem, err := recursiveInterpolate(elem, mapping)
  52. if err != nil {
  53. return nil, err
  54. }
  55. out[key] = interpolatedElem
  56. }
  57. return out, nil
  58. case []interface{}:
  59. out := make([]interface{}, len(value))
  60. for i, elem := range value {
  61. interpolatedElem, err := recursiveInterpolate(elem, mapping)
  62. if err != nil {
  63. return nil, err
  64. }
  65. out[i] = interpolatedElem
  66. }
  67. return out, nil
  68. default:
  69. return value, nil
  70. }
  71. }