Files
gojsonmapper/mapper.go
Björn Benouarets 9072d798c8 init: Initial commit
2026-01-22 12:14:49 +01:00

101 lines
2.1 KiB
Go

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
}