package gojsonmapper import ( "encoding/json" "fmt" "os" "strings" ) type Mapper struct { mapping map[string]string } func ReadMapping(path string) (map[string]string, error) { jsonData, err := os.ReadFile(path) if err != nil { return nil, err } var mapping map[string]string err = json.Unmarshal(jsonData, &mapping) return mapping, nil } func NewMapper(mapping map[string]string) *Mapper { return &Mapper{mapping: mapping} } func (m *Mapper) Map(input map[string]interface{}) (map[string]interface{}, error) { output := make(map[string]interface{}) for key, path := range m.mapping { output[key] = navigatePath(input, path) } return output, nil } func navigatePath(current map[string]interface{}, path string) interface{} { parts := strings.Split(path, ".") for i, part := range parts { isLast := i == len(parts)-1 if strings.Contains(part, "[") && strings.HasSuffix(part, "]") { key := part[:strings.Index(part, "[")] indexStr := part[strings.Index(part, "[")+1 : len(part)-1] if current[key] == nil { return nil } arr, ok := current[key].([]interface{}) if !ok { return nil } // Handle mapping all elements: key[] if indexStr == "" { if isLast { return arr } remainingPath := strings.Join(parts[i+1:], ".") result := make([]interface{}, len(arr)) for j, item := range arr { if nestedMap, ok := item.(map[string]interface{}); ok { result[j] = navigatePath(nestedMap, remainingPath) } } return result } // Handle specific index: key[0] var index int fmt.Sscanf(indexStr, "%d", &index) if index < 0 || index >= len(arr) { return nil } if isLast { return arr[index] } if nestedMap, ok := arr[index].(map[string]interface{}); ok { remainingPath := strings.Join(parts[i+1:], ".") return navigatePath(nestedMap, remainingPath) } return nil } // Regular key access if isLast { return current[part] } if current[part] == nil { return nil } var ok bool current, ok = current[part].(map[string]interface{}) if !ok { return nil } } return current }